Chapter 3: Markov Dynamics#
inventory_sim.py#
import numpy as np
from scipy.stats import geom
from itertools import product
from quantecon import MarkovChain
from collections import namedtuple
# NamedTuple Model
Model = namedtuple("Model", ("S", "s", "p", "φ", "h"))
def create_inventory_model(S=100, # Order size
s=10, # Order threshold
p=0.4): # Demand parameter
φ = geom(p, loc=-1) # loc sets support to {0,1,...}
h = lambda x, d: max(x - d, 0) + S*(x <= s)
return Model(S=S, s=s, p=p, φ=φ, h=h)
def sim_inventories(model, ts_length=200):
"""Simulate the inventory process."""
S, s, p, φ, h = model
X = np.empty(ts_length)
X[0] = S # Initial condition
for t in range(0, ts_length - 1):
X[t+1] = h(X[t], φ.rvs())
return X
def compute_mc(model, d_max=100):
"""Compute the transition probabilities and state."""
S, s, p, φ, h = model
n = S + s + 1 # Size of state space
state_vals = np.arange(n)
P = np.empty((n, n))
for (i, j) in product(range(0, n), range(0, n)):
P[i, j] = sum((h(i, d) == j)*φ.pmf(d) for d in range(d_max+1))
return MarkovChain(P, state_vals)
def compute_stationary_dist(model):
"""Compute the stationary distribution of the model."""
mc = compute_mc(model)
return mc.state_values, mc.stationary_distributions[0]
# Plots
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
plt.rcParams.update({"text.usetex": True, "font.size": 14})
default_model = create_inventory_model()
def plot_ts(model, fontsize=16,
figname="./figures/inventory_sim_1.pdf",
savefig=False):
S, s, p, φ, h = model
X = sim_inventories(model)
fig, ax = plt.subplots(figsize=(9, 5.2))
ax.plot(X, label=r"$X_t$", linewidth=3, alpha=0.6)
fontdict = {'fontsize': fontsize}
ax.set_xlabel(r"$t$", fontdict=fontdict)
ax.set_ylabel("inventory", fontdict=fontdict)
ax.legend(fontsize=fontsize, frameon=False)
ax.set_ylim(0, S + s + 20)
if savefig:
fig.savefig(figname)
def plot_hist(model, fontsize=16,
figname="./figures/inventory_sim_2.pdf",
savefig=False):
S, s, p, φ, h = model
state_values, ψ_star = compute_stationary_dist(model)
X = sim_inventories(model, 1_000_000)
histogram = [np.mean(X == i) for i in state_values]
fig, ax = plt.subplots(figsize=(9, 5.2))
ax.plot(state_values, ψ_star, "k-", linewidth=3, alpha=0.7,
label=r"$\psi^*$")
ax.bar(state_values, histogram, alpha=0.7, label="frequency")
fontdict = {'fontsize': fontsize}
ax.set_xlabel("state", fontdict=fontdict)
ax.legend(fontsize=fontsize, frameon=False)
ax.set_ylim(0, 0.015)
if savefig:
fig.savefig(figname)
model = create_inventory_model()
plot_ts(model)

plot_hist(model)

is_irreducible.py#
from quantecon import MarkovChain
import numpy as np
P = np.array([
[0.1, 0.9],
[0.0, 1.0]
])
mc = MarkovChain(P)
print(mc.is_irreducible)
False
laborer_sim.py#
import numpy as np
from collections import namedtuple
# NamedTuple Model
Model = namedtuple("Model", ("α", "β"))
def create_laborer_model(α=0.3, β=0.2):
return Model(α=α, β=β)
def laborer_update(x, model): # update X from t to t+1
if x == 1:
x_ = 2 if np.random.rand() < model.α else 1
else:
x_ = 1 if np.random.rand() < model.β else 2
return x_
def sim_chain(k, p, model):
X = np.empty(k)
X[0] = 1 if np.random.rand() < p else 2
for t in range(0, k-1):
X[t+1] = laborer_update(X[t], model)
return X
def test_convergence(k=10_000_000, p=0.5):
model = create_laborer_model()
α, β = model
ψ_star = (1/(α + β)) * np.array([β, α])
X = sim_chain(k, p, model)
ψ_e = (1/k) * np.array([sum(X == 1), sum(X == 2)])
error = np.max(np.abs(ψ_star - ψ_e))
approx_equal = np.allclose(ψ_star, ψ_e, rtol=0.01)
print(f"Sup norm deviation is {error}")
print(f"Approximate equality is {approx_equal}")
markov_js.py#
"""
Infinite-horizon job search with Markov wage draws.
"""
from quantecon.markov import tauchen
import numpy as np
from collections import namedtuple
from s_approx import successive_approx
# NamedTuple Model
Model = namedtuple("Model", ("n", "w_vals", "P", "β", "c"))
def create_markov_js_model(
n=200, # wage grid size
ρ=0.9, # wage persistence
ν=0.2, # wage volatility
β=0.98, # discount factor
c=1.0 # unemployment compensation
):
"""
Creates an instance of the job search model with Markov wages.
"""
mc = tauchen(n, ρ, ν)
w_vals, P = np.exp(mc.state_values), mc.P
return Model(n=n, w_vals=w_vals, P=P, β=β, c=c)
def T(v, model):
"""
The Bellman operator Tv = max{e, c + β P v} with e(w) = w / (1-β).
"""
n, w_vals, P, β, c = model
h = c + β * np.dot(P, v)
e = w_vals / (1 - β)
return np.maximum(e, h)
def get_greedy(v, model):
"""Get a v-greedy policy."""
n, w_vals, P, β, c = model
σ = w_vals / (1 - β) >= c + β * np.dot(P, v)
return σ
def vfi(model):
"""Solve the infinite-horizon Markov job search model by VFI."""
v_init = np.zeros(model.w_vals.shape)
v_star = successive_approx(lambda v: T(v, model), v_init)
σ_star = get_greedy(v_star, model)
return v_star, σ_star
# == Policy iteration == #
def get_value(σ, model):
"""Get the value of policy σ."""
n, w_vals, P, β, c = model
e = w_vals / (1 - β)
K_σ = β * ((1 - σ) * P.T).T
r_σ = σ * e + (1 - σ) * c
I = np.identity(K_σ.shape[0])
return np.linalg.solve((I - K_σ), r_σ)
def policy_iteration(model):
"""
Howard policy iteration routine.
"""
σ = np.zeros(model.n, dtype=bool)
i, error = 0, True
while error:
v_σ = get_value(σ, model)
σ_new = get_greedy(v_σ, model)
error = np.any(σ_new ^ σ)
σ = σ_new
i = i + 1
print(f"Concluded loop {i} with error: {error}.")
return σ
# == Plots == #
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
plt.rcParams.update({"text.usetex": True, "font.size": 14})
default_model = create_markov_js_model()
def plot_main(model=default_model,
method="vfi",
savefig=False,
figname="./figures/markov_js_vfix.png"):
n, w_vals, P, β, c = model
if method == "vfi":
v_star, σ_star = vfi(model)
else:
σ_star = policy_iteration(model)
v_star = get_value(σ_star, model)
h_star = c + β * np.dot(P, v_star)
e = w_vals / (1 - β)
fig, ax = plt.subplots(figsize=(9, 5.2))
ax.plot(w_vals, h_star, linewidth=4, ls="--", alpha=0.4, label=r"$h^*(w)$")
ax.plot(w_vals, e, linewidth=4, ls="--", alpha=0.4, label=r"$w/(1-\beta)$")
ax.plot(w_vals, np.maximum(e, h_star), "k-", alpha=0.7, label=r"$v^*(w)$")
ax.legend(frameon=False)
ax.set_xlabel(r"$w$")
if savefig:
fig.savefig(figname)
plot_main()
Completed iteration 25 with error 0.7358325123867075.
Completed iteration 50 with error 0.21393801675841218.
Completed iteration 75 with error 0.07487776205154262.
Completed iteration 100 with error 0.027611709626711445.
Completed iteration 125 with error 0.010342258331789367.
Completed iteration 150 with error 0.00392782716204465.
Completed iteration 175 with error 0.0014931447809232168.
Completed iteration 200 with error 0.0005676247519517119.
Completed iteration 225 with error 0.00021578485559814453.
Completed iteration 250 with error 8.203149057806058e-05.
Completed iteration 275 with error 3.1184604821987705e-05.
Completed iteration 300 with error 1.1854954394152628e-05.
Completed iteration 325 with error 4.506709132101605e-06.
Completed iteration 350 with error 1.713243804601916e-06.
Terminated successfully in 365 iterations.

markov_js_with_sep.py#
"""
Infinite-horizon job search with Markov wage draws and separation.
"""
from quantecon.markov import tauchen
import numpy as np
from collections import namedtuple
from s_approx import successive_approx
# NamedTuple Model
Model = namedtuple("Model", ("n", "w_vals", "P", "β", "c", "α"))
def create_js_with_sep_model(
n=200, # wage grid size
ρ=0.9, ν=0.2, # wage persistence and volatility
β=0.98, α=0.1, # discount factor and separation rate
c=1.0): # unemployment compensation
"""Creates an instance of the job search model with separation."""
mc = tauchen(n, ρ, ν)
w_vals, P = np.exp(mc.state_values), mc.P
return Model(n=n, w_vals=w_vals, P=P, β=β, c=c, α=α)
def T(v, model):
"""The Bellman operator for the value of being unemployed."""
n, w_vals, P, β, c, α = model
d = 1 / (1 - β * (1 - α))
accept = d * (w_vals + α * β * np.dot(P, v))
reject = c + β * np.dot(P, v)
return np.maximum(accept, reject)
def get_greedy(v, model):
""" Get a v-greedy policy."""
n, w_vals, P, β, c, α = model
d = 1 / (1 - β * (1 - α))
accept = d * (w_vals + α * β * np.dot(P, v))
reject = c + β * np.dot(P, v)
σ = accept >= reject
return σ
def vfi(model):
"""Solve by VFI."""
v_init = np.zeros(model.w_vals.shape)
v_star = successive_approx(lambda v: T(v, model), v_init)
σ_star = get_greedy(v_star, model)
return v_star, σ_star
# == Plots == #
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
plt.rcParams.update({"text.usetex": True, "font.size": 14})
default_model = create_js_with_sep_model()
def plot_main(model=default_model,
savefig=False,
figname="./figures/markov_js_with_sep_1.pdf"):
n, w_vals, P, β, c, α = model
v_star, σ_star = vfi(model)
d = 1 / (1 - β * (1 - α))
accept = d * (w_vals + α * β * np.dot(P, v_star))
h_star = c + β * np.dot(P, v_star)
w_star = np.inf
for (i, w) in enumerate(w_vals):
if accept[i] >= h_star[i]:
w_star = w
break
assert w_star != np.inf, "Agent never accepts"
fig, ax = plt.subplots(figsize=(9, 5.2))
ax.plot(w_vals, h_star, linewidth=4, ls="--", alpha=0.4,
label="continuation value")
ax.plot(w_vals, accept, linewidth=4, ls="--", alpha=0.4,
label="stopping value")
ax.plot(w_vals, v_star, "k-", alpha=0.7, label=r"$v_u^*(w)$")
ax.legend(frameon=False)
ax.set_xlabel(r"$w$")
if savefig:
fig.savefig(figname)
def plot_w_stars(α_vals=np.linspace(0.0, 1.0, 10),
savefig=False,
figname="./figures/markov_js_with_sep_2.pdf"):
w_star_vec = np.empty_like(α_vals)
for (i_α, α) in enumerate(α_vals):
print(i_α, α)
model = create_js_with_sep_model(α=α)
n, w_vals, P, β, c, α = model
v_star, σ_star = vfi(model)
d = 1 / (1 - β * (1 - α))
accept = d * (w_vals + α * β * np.dot(P, v_star))
h_star = c + β * np.dot(P, v_star)
w_star = np.inf
for (i_w, w) in enumerate(w_vals):
if accept[i_w] >= h_star[i_w]:
w_star = w
break
assert w_star != np.inf, "Agent never accepts"
w_star_vec[i_α] = w_star
fig, ax = plt.subplots(figsize=(9, 5.2))
ax.plot(α_vals, w_star_vec, linewidth=2, alpha=0.6,
label="reservation wage")
ax.legend(frameon=False)
ax.set_xlabel(r"$\alpha$")
ax.set_xlabel(r"$w$")
if savefig:
fig.savefig(figname)
plot_main()
Completed iteration 25 with error 1.0768067726007757.
Completed iteration 50 with error 0.3114311653737616.
Completed iteration 75 with error 0.10927534292912355.
Completed iteration 100 with error 0.04148769976492872.
Completed iteration 125 with error 0.016208489343711108.
Completed iteration 150 with error 0.00636718413682047.
Completed iteration 175 with error 0.002501707451486368.
Completed iteration 200 with error 0.000989361244521092.
Completed iteration 225 with error 0.0003952811634491127.
Completed iteration 250 with error 0.0001580316448865915.
Completed iteration 275 with error 6.318165887364557e-05.
Completed iteration 300 with error 2.526028629290522e-05.
Completed iteration 325 with error 1.0099166189547759e-05.
Completed iteration 350 with error 4.037688142943807e-06.
Completed iteration 375 with error 1.6142843008992713e-06.
Terminated successfully in 390 iterations.

plot_w_stars()
0 0.0
Completed iteration 25 with error 0.7358325123867075.
Completed iteration 50 with error 0.21393801675841218.
Completed iteration 75 with error 0.07487776205154262.
Completed iteration 100 with error 0.027611709626711445.
Completed iteration 125 with error 0.010342258331789367.
Completed iteration 150 with error 0.00392782716204465.
Completed iteration 175 with error 0.0014931447809232168.
Completed iteration 200 with error 0.0005676247519517119.
Completed iteration 225 with error 0.00021578485559814453.
Completed iteration 250 with error 8.203149057806058e-05.
Completed iteration 275 with error 3.1184604821987705e-05.
Completed iteration 300 with error 1.1854954394152628e-05.
Completed iteration 325 with error 4.506709132101605e-06.
Completed iteration 350 with error 1.713243804601916e-06.
Terminated successfully in 365 iterations.
1 0.1111111111111111
Completed iteration 25 with error 1.0908342197011365.
Completed iteration 50 with error 0.3207246338823424.
Completed iteration 75 with error 0.11318340744479372.
Completed iteration 100 with error 0.04326081621015021.
Completed iteration 125 with error 0.01702270454350696.
Completed iteration 150 with error 0.006738975380415013.
Completed iteration 175 with error 0.0026685293016583955.
Completed iteration 200 with error 0.0010679313731145612.
Completed iteration 225 with error 0.0004299980392232783.
Completed iteration 250 with error 0.00017318107607877664.
Completed iteration 275 with error 6.974899999079298e-05.
Completed iteration 300 with error 2.8091546738551187e-05.
Completed iteration 325 with error 1.1313925725175977e-05.
Completed iteration 350 with error 4.556705860636612e-06.
Completed iteration 375 with error 1.8352222355133563e-06.
Terminated successfully in 393 iterations.
2 0.2222222222222222
Completed iteration 25 with error 1.1302039661879064.
Completed iteration 50 with error 0.40190677446813794.
Completed iteration 75 with error 0.15417026004176648.
Completed iteration 100 with error 0.06350128466102234.
Completed iteration 125 with error 0.026934357233869832.
Completed iteration 150 with error 0.011580448768086171.
Completed iteration 175 with error 0.0050026366601017.
Completed iteration 200 with error 0.0021615971167534553.
Completed iteration 225 with error 0.0009340178864860604.
Completed iteration 250 with error 0.0004035857706625734.
Completed iteration 275 with error 0.00017438796437119208.
Completed iteration 300 with error 7.535241419276417e-05.
Completed iteration 325 with error 3.255950799996299e-05.
Completed iteration 350 with error 1.4068846688530812e-05.
Completed iteration 375 with error 6.079098213263023e-06.
Completed iteration 400 with error 2.6267565402804394e-06.
Completed iteration 425 with error 1.135012084318987e-06.
Terminated successfully in 430 iterations.
3 0.3333333333333333
Completed iteration 25 with error 1.082781806027267.
Completed iteration 50 with error 0.45519415974240474.
Completed iteration 75 with error 0.19282144291682357.
Completed iteration 100 with error 0.08581200863319793.
Completed iteration 125 with error 0.039157737964949035.
Completed iteration 150 with error 0.01805454739234591.
Completed iteration 175 with error 0.00838563508999357.
Completed iteration 200 with error 0.003898038044262364.
Completed iteration 225 with error 0.0018120704587545333.
Completed iteration 250 with error 0.0008423743598768851.
Completed iteration 275 with error 0.00039159330419380467.
Completed iteration 300 with error 0.00018203939284688886.
Completed iteration 325 with error 8.462437999412487e-05.
Completed iteration 350 with error 3.9339208811384196e-05.
Completed iteration 375 with error 1.8287559086616056e-05.
Completed iteration 400 with error 8.501310219344305e-06.
Completed iteration 425 with error 3.951991345729766e-06.
Completed iteration 450 with error 1.8371563044183858e-06.
Terminated successfully in 471 iterations.
4 0.4444444444444444
Completed iteration 25 with error 1.0101061095615904.
Completed iteration 50 with error 0.48366451069681204.
Completed iteration 75 with error 0.2245641250651147.
Completed iteration 100 with error 0.10739554585371991.
Completed iteration 125 with error 0.052283813599210305.
Completed iteration 150 with error 0.025665632138029082.
Completed iteration 175 with error 0.012671593196692754.
Completed iteration 200 with error 0.00626138069863913.
Completed iteration 225 with error 0.0030940523821314514.
Completed iteration 250 with error 0.0015289256308008703.
Completed iteration 275 with error 0.0007555185499654726.
Completed iteration 300 with error 0.00037333947034312587.
Completed iteration 325 with error 0.00018448568895479411.
Completed iteration 350 with error 9.116359809979713e-05.
Completed iteration 375 with error 4.5048489489829535e-05.
Completed iteration 400 with error 2.226070982658257e-05.
Completed iteration 425 with error 1.1000129170213313e-05.
Completed iteration 450 with error 5.435713518409102e-06.
Completed iteration 475 with error 2.68605767672625e-06.
Completed iteration 500 with error 1.3273153314230512e-06.
Terminated successfully in 512 iterations.
5 0.5555555555555556
Completed iteration 25 with error 0.9354993514006864.
Completed iteration 50 with error 0.49436451425174255.
Completed iteration 75 with error 0.24818960566408776.
Completed iteration 100 with error 0.12648987573435022.
Completed iteration 125 with error 0.06517289125884673.
Completed iteration 150 with error 0.03378604797021012.
Completed iteration 175 with error 0.017566215840986388.
Completed iteration 200 with error 0.00915584797562019.
Completed iteration 225 with error 0.004772835312394363.
Completed iteration 250 with error 0.002488041947152908.
Completed iteration 275 with error 0.001296997585946258.
Completed iteration 300 with error 0.0006761151259055964.
Completed iteration 325 with error 0.00035245375121206735.
Completed iteration 350 with error 0.0001837315007549023.
Completed iteration 375 with error 9.577785525749505e-05.
Completed iteration 400 with error 4.992827860661464e-05.
Completed iteration 425 with error 2.60272376877424e-05.
Completed iteration 450 with error 1.3567804067804445e-05.
Completed iteration 475 with error 7.072794652174252e-06.
Completed iteration 500 with error 3.686994872964533e-06.
Completed iteration 525 with error 1.9220028093513974e-06.
Completed iteration 550 with error 1.0019256606597082e-06.
Terminated successfully in 552 iterations.
6 0.6666666666666666
Completed iteration 25 with error 0.904928287097114.
Completed iteration 50 with error 0.4935393062159932.
Completed iteration 75 with error 0.2642254156191157.
Completed iteration 100 with error 0.1422057238442065.
Completed iteration 125 with error 0.07698303775877946.
Completed iteration 150 with error 0.04180499616060729.
Completed iteration 175 with error 0.022759933588368142.
Completed iteration 200 with error 0.012395733168744982.
Completed iteration 225 with error 0.006751179539278951.
Completed iteration 250 with error 0.003676948092248722.
Completed iteration 275 with error 0.0020026053292028223.
Completed iteration 300 with error 0.001090694788466351.
Completed iteration 325 with error 0.0005940337342735802.
Completed iteration 350 with error 0.00032353329382317497.
Completed iteration 375 with error 0.0001762084982104284.
Completed iteration 400 with error 9.596982887671857e-05.
Completed iteration 425 with error 5.226880737296824e-05.
Completed iteration 450 with error 2.8467574225032877e-05.
Completed iteration 475 with error 1.5504520249010056e-05.
Completed iteration 500 with error 8.444349539615814e-06.
Completed iteration 525 with error 4.59911291983417e-06.
Completed iteration 550 with error 2.5048512597436456e-06.
Completed iteration 575 with error 1.3642369722788317e-06.
Terminated successfully in 589 iterations.
7 0.7777777777777777
Completed iteration 25 with error 0.8754680641411525.
Completed iteration 50 with error 0.48591938913980925.
Completed iteration 75 with error 0.2739472364400086.
Completed iteration 100 with error 0.15435613754701194.
Completed iteration 125 with error 0.08716896006367847.
Completed iteration 150 with error 0.04929986845724699.
Completed iteration 175 with error 0.027901732615987385.
Completed iteration 200 with error 0.01580799147810552.
Completed iteration 225 with error 0.008956542454093608.
Completed iteration 250 with error 0.00507463627297966.
Completed iteration 275 with error 0.002875209574966675.
Completed iteration 300 with error 0.001629048808375444.
Completed iteration 325 with error 0.0009229935949193191.
Completed iteration 350 with error 0.0005229537457083211.
Completed iteration 375 with error 0.00029629741923287156.
Completed iteration 400 with error 0.00016787748700153315.
Completed iteration 425 with error 9.511676042706085e-05.
Completed iteration 450 with error 5.389166990710237e-05.
Completed iteration 475 with error 3.053417790255253e-05.
Completed iteration 500 with error 1.7300188005719974e-05.
Completed iteration 525 with error 9.802016151638782e-06.
Completed iteration 550 with error 5.55366914767319e-06.
Completed iteration 575 with error 3.1466221486198265e-06.
Completed iteration 600 with error 1.7828269136543895e-06.
Completed iteration 625 with error 1.0101218776981113e-06.
Terminated successfully in 627 iterations.
8 0.8888888888888888
Completed iteration 25 with error 0.8460605070496783.
Completed iteration 50 with error 0.4748541534684918.
Completed iteration 75 with error 0.2788181611011922.
Completed iteration 100 with error 0.16317372471699798.
Completed iteration 125 with error 0.09553448380320617.
Completed iteration 150 with error 0.05593656450190565.
Completed iteration 175 with error 0.03276931670900751.
Completed iteration 200 with error 0.01920113908680321.
Completed iteration 225 with error 0.01125091517433674.
Completed iteration 250 with error 0.006592479196839918.
Completed iteration 275 with error 0.00386286641577982.
Completed iteration 300 with error 0.0022634484706642866.
Completed iteration 325 with error 0.0013262687414226093.
Completed iteration 350 with error 0.0007771278194965703.
Completed iteration 375 with error 0.00045535842692601136.
Completed iteration 400 with error 0.0002668174935891443.
Completed iteration 425 with error 0.00015634184123314299.
Completed iteration 450 with error 9.16085785291898e-05.
Completed iteration 475 with error 5.367809152545533e-05.
Completed iteration 500 with error 3.1452704064349746e-05.
Completed iteration 525 with error 1.8429727369095872e-05.
Completed iteration 550 with error 1.0798907794651313e-05.
Completed iteration 575 with error 6.3276253214894496e-06.
Completed iteration 600 with error 3.707675148234557e-06.
Completed iteration 625 with error 2.1725140655348696e-06.
Completed iteration 650 with error 1.2729856990745247e-06.
Terminated successfully in 663 iterations.
9 1.0
Completed iteration 25 with error 0.8195566251536164.
Completed iteration 50 with error 0.46642498056927195.
Completed iteration 75 with error 0.28037678187634185.
Completed iteration 100 with error 0.16915170563319748.
Completed iteration 125 with error 0.10207516364071978.
Completed iteration 150 with error 0.061598680129037575.
Completed iteration 175 with error 0.03717262745708183.
Completed iteration 200 with error 0.02243236944053706.
Completed iteration 225 with error 0.01353714375674997.
Completed iteration 250 with error 0.008169188798902383.
Completed iteration 275 with error 0.004929817311051465.
Completed iteration 300 with error 0.0029749708714845724.
Completed iteration 325 with error 0.0017952899930691046.
Completed iteration 350 with error 0.0010833941905588063.
Completed iteration 375 with error 0.0006537901824543724.
Completed iteration 400 with error 0.0003945393158062416.
Completed iteration 425 with error 0.0002380905616092832.
Completed iteration 450 with error 0.00014367925643909985.
Completed iteration 475 with error 8.670536367105797e-05.
Completed iteration 500 with error 5.232362886431474e-05.
Completed iteration 525 with error 3.157546457543958e-05.
Completed iteration 550 with error 1.905467919982584e-05.
Completed iteration 575 with error 1.1498826843592269e-05.
Completed iteration 600 with error 6.9391364547755074e-06.
Completed iteration 625 with error 4.1875241052480305e-06.
Completed iteration 650 with error 2.5270231276408595e-06.
Completed iteration 675 with error 1.5249693490204663e-06.
Terminated successfully in 697 iterations.
