From c301f0332ddc94ec66ea58b8267285df005fefff Mon Sep 17 00:00:00 2001 From: Spencer Lyon Date: Mon, 4 Aug 2014 14:28:02 -0700 Subject: [PATCH 1/2] ENH: moved the lucas_tree tuple to a new LucasTree class Updated examples and solutions to match change --- examples/lucas_tree_price1.py | 15 +- quantecon/compute_fp.py | 12 +- quantecon/models/__init__.py | 5 +- quantecon/models/lucastree.py | 254 +++++++++++++++++++++++--------- solutions/asset_solutions.ipynb | 250 +++++++++++++++++++++++-------- 5 files changed, 386 insertions(+), 150 deletions(-) diff --git a/examples/lucas_tree_price1.py b/examples/lucas_tree_price1.py index bc2660df2..89f5ea89d 100644 --- a/examples/lucas_tree_price1.py +++ b/examples/lucas_tree_price1.py @@ -2,20 +2,19 @@ from __future__ import division # Omit for Python 3.x import numpy as np import matplotlib.pyplot as plt -from quantecon.models import lucas_tree, compute_lt_price +from quantecon.models import LucasTree fig, ax = plt.subplots() -#grid = np.linspace(1e-10, 4, 100) -tree = lucas_tree(gamma=2, beta=0.95, alpha=0.90, sigma=0.1) -grid, price_vals = compute_lt_price(tree) +tree = LucasTree(gamma=2, beta=0.95, alpha=0.90, sigma=0.1) +grid, price_vals = tree.grid, tree.compute_lt_price() ax.plot(grid, price_vals, lw=2, alpha=0.7, label=r'$p^*(y)$') ax.set_xlim(min(grid), max(grid)) -#tree = lucas_tree(gamma=3, beta=0.95, alpha=0.90, sigma=0.1) -#grid, price_vals = compute_price(tree) -#ax.plot(grid, price_vals, lw=2, alpha=0.7, label='more patient') -#ax.set_xlim(min(grid), max(grid)) +# tree = LucasTree(gamma=3, beta=0.95, alpha=0.90, sigma=0.1) +# grid, price_vals = tree.grid, tree.compute_lt_price() +# ax.plot(grid, price_vals, lw=2, alpha=0.7, label='more patient') +# ax.set_xlim(min(grid), max(grid)) ax.set_xlabel(r'$y$', fontsize=16) ax.set_ylabel(r'price', fontsize=16) diff --git a/quantecon/compute_fp.py b/quantecon/compute_fp.py index f4d63955c..4febad17f 100644 --- a/quantecon/compute_fp.py +++ b/quantecon/compute_fp.py @@ -9,7 +9,9 @@ import numpy as np -def compute_fixed_point(T, v, error_tol=1e-3, max_iter=50, verbose=1): + +def compute_fixed_point(T, v, error_tol=1e-3, max_iter=50, verbose=1, *args, + **kwargs): """ Computes and returns :math:`T^k v`, an approximate fixed point. @@ -29,6 +31,9 @@ def compute_fixed_point(T, v, error_tol=1e-3, max_iter=50, verbose=1): Maximum number of iterations verbose : bool, optional(default=True) If True then print current error at each iterate. + args, kwargs : + Other arguments and keyword arguments that are passed directly + to the function T each time it is called Returns ------- @@ -39,12 +44,11 @@ def compute_fixed_point(T, v, error_tol=1e-3, max_iter=50, verbose=1): iterate = 0 error = error_tol + 1 while iterate < max_iter and error > error_tol: - new_v = T(v) + new_v = T(v, *args, **kwargs) iterate += 1 error = np.max(np.abs(new_v - v)) if verbose: print("Computed iterate %d with error %f" % (iterate, error)) - v = new_v + v[:] = new_v return v - diff --git a/quantecon/models/__init__.py b/quantecon/models/__init__.py index a1eb7acd3..f26cede3c 100644 --- a/quantecon/models/__init__.py +++ b/quantecon/models/__init__.py @@ -6,13 +6,12 @@ """ __all__ = ["AssetPrices", "CareerWorkerProblem", "ConsumerProblem", - "JvWorker", "lucas_tree", "compute_lt_price", "SearchProblem", - "GrowthModel"] + "JvWorker", "LucasTree", "SearchProblem", "GrowthModel"] from .asset_pricing import AssetPrices from .career import CareerWorkerProblem from .ifp import ConsumerProblem from .jv import JvWorker -from .lucastree import lucas_tree, compute_lt_price +from .lucastree import LucasTree from .odu import SearchProblem from .optgrowth import GrowthModel diff --git a/quantecon/models/lucastree.py b/quantecon/models/lucastree.py index 9e393607a..d3e8618fb 100644 --- a/quantecon/models/lucastree.py +++ b/quantecon/models/lucastree.py @@ -1,7 +1,7 @@ r""" Filename: lucastree.py -Authors: Thomas Sargent, John Stachurski +Authors: Thomas Sargent, John Stachurski, Spencer Lyon Solves the price function for the Lucas tree in a continuous state setting, using piecewise linear approximation for the sequence of @@ -33,91 +33,164 @@ where LN means lognormal. -Example usage: - - tree = lucas_tree(gamma=2, beta=0.95, alpha=0.90, sigma=0.1) - grid, price_vals = compute_price(tree) - """ -from __future__ import division # Omit for Python 3.x +from __future__ import division # == Omit for Python 3.x == # import numpy as np -from collections import namedtuple from scipy import interp from scipy.stats import lognorm from scipy.integrate import fixed_quad +from ..compute_fp import compute_fixed_point -# == Use a namedtuple to store the parameters of the Lucas tree == # -lucas_tree = namedtuple('lucas_tree', - ['gamma', # Risk aversion - 'beta', # Discount factor - 'alpha', # Correlation coefficient - 'sigma']) # Shock volatility - -# == A function to compute the price == # - -def compute_lt_price(lt, grid=None): +class LucasTree(object): """ - Compute the equilibrium price function associated with Lucas tree lt + Class to solve for the price of a the Lucas tree in the Lucas + asset pricing model Parameters ---------- - lt : namedtuple(lucas_tree) - A namedtuple containing the parameters of the Lucas tree - + gamma : scalar(float) + The coefficient of risk aversion in the household's CRRA utility + function + beta : scalar(float) + The household's discount factor + alpha : scalar(float) + The correlation coefficient in the shock process + sigma : scalar(float) + The volatility of the shock process grid : array_like(float), optional(default=None) - The grid points on which to return the function values. Grid - points should be nonnegative. + The grid points on which to evaluate the asset prices. Grid + points should be nonnegative. If None is passed, we will create + a reasonable one for you - Returns - ------- + Attributes + ---------- + gamma : scalar(float) + The coefficient of risk aversion in the household's CRRA utility + function + beta : scalar(float) + The household's discount factor + alpha : scalar(float) + The correlation coefficient in the shock process + sigma : scalar(float) + The volatility of the shock process grid : array_like(float) - The grid that was used to calculate the prices - price : array_like(float) - The prices at the grid points + The grid points on which to evaluate the asset prices. Grid + points should be nonnegative. + grid_min, grid_max, grid_size : scalar(int) + Properties for grid upon which prices are evaluated + phi : scipy.stats.lognorm + The distribution for the shock process + + Examples + -------- + >>> tree = LucasTree(gamma=2, beta=0.95, alpha=0.90, sigma=0.1) + >>> grid, price_vals = tree.grid, tree.compute_lt_price() """ - # == Simplify names, set up distribution phi == # - gamma, beta, alpha, sigma = lt.gamma, lt.beta, lt.alpha, lt.sigma - phi = lognorm(sigma) - # == Set up a function for integrating w.r.t. phi == # + def __init__(self, gamma, beta, alpha, sigma, grid=None): + self.gamma = gamma + self.beta = beta + self.alpha = alpha + self.sigma = sigma - int_min, int_max = np.exp(-4 * sigma), np.exp(4 * sigma) - def integrate(g): - "Integrate over three standard deviations" - integrand = lambda z: g(z) * phi.pdf(z) - result, error = fixed_quad(integrand, int_min, int_max) - return result + # == set up grid == # + if grid is None: + (self.grid, self.grid_min, + self.grid_max, self.grid_size) = self._new_grid() + else: + self.grid = np.asarray(grid) + self.grid_min = min(grid) + self.grid_max = max(grid) + self.grid_size = len(grid) - # == If there's no grid, form an appropriate one == # + # == set up distribution for shocks == # + self.phi = lognorm(sigma) - if grid == None: + # == set up integration bounds. 3 Standard deviations. Make them + # private attributes b/c users don't need to see them, but we + # only want to compute them once. == # + self._int_min = np.exp(-4.0 * sigma) + self._int_max = np.exp(4.0 * sigma) + + # == Set up h from the Lucas Operator == # + self.h = self._init_h() + + def _init_h(self): + """ + Compute the function h in the Lucas operator as a vector of + values on the grid + + Recall that h(y) = beta * int u'(G(y,z)) G(y,z) phi(dz) + """ + alpha, gamma, beta = self.alpha, self.gamma, self.beta + grid, grid_size = self.grid, self.grid_size + + h = np.empty(grid_size) + + for i, y in enumerate(grid): + # == u'(G(y,z)) G(y,z) == # + integrand = lambda z: (y**alpha * z)**(1 - gamma) + h[i] = beta * self.integrate(integrand) + + return h + + def _new_grid(self): + """ + Construct the default grid for the problem + + This is defined to be np.linspace(0, 10, 100) when alpha > 1 + and 100 evenly spaced points covering 3 standard deviations + when alpha < 1 + """ grid_size = 100 - if abs(alpha) >= 1: - # If nonstationary, put the grid on [0,10] - grid_min, grid_max = 0, 10 + if abs(self.alpha) >= 1.0: + grid_min, grid_max = 0.0, 10.0 else: - # Set the grid interval to contain most of the mass of the - # stationary distribution of the consumption endowment - ssd = sigma / np.sqrt(1 - alpha**2) + # == Set the grid interval to contain most of the mass of the + # stationary distribution of the consumption endowment == # + ssd = self.sigma / np.sqrt(1 - self.alpha**2) grid_min, grid_max = np.exp(-4 * ssd), np.exp(4 * ssd) + grid = np.linspace(grid_min, grid_max, grid_size) - else: - grid_min, grid_max, grid_size = min(grid), max(grid), len(grid) - # == Compute the function h in the Lucas operator as a vector of == # - # == values on the grid == # + return grid, grid_min, grid_max, grid_size - h = np.empty(grid_size) - # Recall that h(y) = beta * int u'(G(y,z)) G(y,z) phi(dz) - for i, y in enumerate(grid): - integrand = lambda z: (y**alpha * z)**(1 - gamma) # u'(G(y,z)) G(y,z) - h[i] = beta * integrate(integrand) + def integrate(self, g, int_min=None, int_max=None): + """ + Integrate the function g(z) * self.phi(z) from int_min to + int_max. - # == Set up the Lucas operator T == # + Parameters + ---------- + g : function + The function which to integrate + + int_min, int_max : scalar(float), optional + The bounds of integration. If either of these parameters are + `None` (the default), they will be set to 3 standard + deviations above and below the mean. + + Returns + ------- + result : scalar(float) + The result of the integration + + """ + # == Simplify notation == # + phi = self.phi + if int_min is None: + int_min = self._int_min + if int_max is None: + int_max = self._int_max + + # == set up integrand and integrate == # + integrand = lambda z: g(z) * phi.pdf(z) + result, error = fixed_quad(integrand, int_min, int_max) + return result - def lucas_operator(f): + def lucas_operator(self, f, Tf=None): """ The approximate Lucas operator, which computes and returns the updated function Tf on the grid points. @@ -128,35 +201,70 @@ def lucas_operator(f): A candidate function on R_+ represented as points on a grid and should be flat NumPy array with len(f) = len(grid) + Tf : array_like(float) + storage array for Tf + Returns ------- Tf : array_like(float) The updated function Tf + Notes + ----- + The argument `Tf` is optional, but recommended. If it is passed + into this function, then we do not have to allocate any memory + for the array here. As this function is often called many times + in an iterative algorithm, this can save significant computation + time. + """ - Tf = np.empty(len(f)) + grid, h = self.grid, self.h + alpha, beta = self.alpha, self.beta + + # == set up storage if needed == # + if Tf is None: + Tf = np.empty_like(f) + + # == Apply the T operator to f == # Af = lambda x: interp(x, grid, f) # Piecewise linear interpolation for i, y in enumerate(grid): - Tf[i] = h[i] + beta * integrate(lambda z: Af(y**alpha * z)) + Tf[i] = h[i] + beta * self.integrate(lambda z: Af(y**alpha * z)) return Tf - # == Now compute the price by iteration == # - error_tol, max_iter = 1e-3, 50 - error = error_tol + 1 - iterate = 0 - f = np.zeros(len(grid)) # Initial condition - while iterate < max_iter and error > error_tol: - new_f = lucas_operator(f) - iterate += 1 - error = np.max(np.abs(new_f - f)) - print(error) - f = new_f + def compute_lt_price(self, error_tol=1e-3, max_iter=50, verbose=1): + """ + Compute the equilibrium price function associated with Lucas + tree lt - price = f * grid**gamma + Parameters + ---------- + error_tol, max_iter, verbose + Arguments to be passed directly to + `quantecon.compute_fixed_point`. See that docstring for more + information + + Returns + ------- + price : array_like(float) + The prices at the grid points in the attribute `grid` of the + object + + """ + # == simplify notation == # + grid, grid_size = self.grid, self.grid_size + lucas_operator, gamma = self.lucas_operator, self.gamma - return grid, price # p(y) = f(y) / u'(y) = f(y) * y^gamma + # == Create storage array for compute_fixed_point. Reduces memory + # allocation and speeds code up == # + Tf = np.empty(grid_size) + # == Initial guess, just a vector of zeros == # + f_init = np.zeros(grid_size) + f = compute_fixed_point(lucas_operator, f_init, error_tol, + max_iter, verbose, Tf=Tf) + price = f * grid**gamma + return price diff --git a/solutions/asset_solutions.ipynb b/solutions/asset_solutions.ipynb index 36cc46b35..556436d63 100644 --- a/solutions/asset_solutions.ipynb +++ b/solutions/asset_solutions.ipynb @@ -1,7 +1,7 @@ { "metadata": { "name": "", - "signature": "sha256:c1025454f7f4927ab3781cb7c727633e1f5461aaf0ea3b2dd7548fa8603da321" + "signature": "sha256:0d27c64dfec03970dd7a7f5ad638c0a6297d7786b4e95caf74265abaf49291f9" }, "nbformat": 3, "nbformat_minor": 0, @@ -32,7 +32,7 @@ "language": "python", "metadata": {}, "outputs": [], - "prompt_number": 7 + "prompt_number": 1 }, { "cell_type": "code", @@ -46,7 +46,7 @@ "language": "python", "metadata": {}, "outputs": [], - "prompt_number": 8 + "prompt_number": 2 }, { "cell_type": "heading", @@ -95,13 +95,15 @@ "output_type": "stream", "stream": "stdout", "text": [ - "Lucas Tree Prices: [ 12.72221763 14.72515002 17.57142236 21.93570661 29.47401578]\n", - "Consol Bond Prices: [ 87.56860139 109.25108965 148.67554548 242.55144082 753.87100476]\n", - "Should be 0: [ 0.00000000e+00 -1.77635684e-15 0.00000000e+00 0.00000000e+00\n", - " 0.00000000e+00]\n" + "('Lucas Tree Prices: ', array([ 12.72221763, 14.72515002, 17.57142236, 21.93570661, 29.47401578]))\n", + "('Consol Bond Prices: ', array([ 87.56860139, 109.25108965, 148.67554548, 242.55144082,\n", + " 753.87100476]))\n", + "('Should be 0: ', array([ 0.00000000e+00, -1.77635684e-15, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00]))\n" ] } - ] + ], + "prompt_number": 3 }, { "cell_type": "heading", @@ -115,8 +117,7 @@ "cell_type": "code", "collapsed": false, "input": [ - "\n", - "from quantecon.models import lucas_tree, compute_lt_price\n", + "from quantecon.models import LucasTree\n", "\n", "fig, ax = plt.subplots(figsize=(10,7))\n", "\n", @@ -124,14 +125,13 @@ "ax.set_ylabel(r'price', fontsize=16)\n", "\n", "for beta in (.95, 0.98):\n", - " tree = lucas_tree(gamma=2, beta=beta, alpha=0.90, sigma=0.1)\n", - " grid, price_vals = compute_lt_price(tree)\n", + " tree = LucasTree(gamma=2, beta=beta, alpha=0.90, sigma=0.1)\n", + " grid, price_vals = tree.grid, tree.compute_lt_price()\n", " label = r'$\\beta = {}$'.format(beta)\n", " ax.plot(grid, price_vals, lw=2, alpha=0.7, label=label)\n", "\n", "ax.legend(loc='upper left')\n", - "ax.set_xlim(min(grid), max(grid))\n", - "\n" + "ax.set_xlim(min(grid), max(grid))" ], "language": "python", "metadata": {}, @@ -140,8 +140,72 @@ "output_type": "stream", "stream": "stdout", "text": [ - "2.04938432509\n", - "1.66149297725" + "Computed iterate 1 with error 2.049384\n", + "Computed iterate 2 with error 1.661493\n", + "Computed iterate 3 with error 1.378032" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "Computed iterate 4 with error 1.156638\n", + "Computed iterate 5 with error 0.978062" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "Computed iterate 6 with error 0.832668\n", + "Computed iterate 7 with error 0.713060" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "Computed iterate 8 with error 0.613716\n", + "Computed iterate 9 with error 0.530633" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "Computed iterate 10 with error 0.460669\n", + "Computed iterate 11 with error 0.401395" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "Computed iterate 12 with error 0.350903\n", + "Computed iterate 13 with error 0.307676" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "Computed iterate 14 with error 0.270498\n", + "Computed iterate 15 with error 0.238388" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "Computed iterate 16 with error 0.210549\n", + "Computed iterate 17 with error 0.186327" ] }, { @@ -149,7 +213,8 @@ "stream": "stdout", "text": [ "\n", - "1.37803173269" + "Computed iterate 18 with error 0.165185\n", + "Computed iterate 19 with error 0.146677" ] }, { @@ -157,7 +222,8 @@ "stream": "stdout", "text": [ "\n", - "1.15663751147" + "Computed iterate 20 with error 0.130430\n", + "Computed iterate 21 with error 0.116135" ] }, { @@ -165,7 +231,8 @@ "stream": "stdout", "text": [ "\n", - "0.978062304284" + "Computed iterate 22 with error 0.103528\n", + "Computed iterate 23 with error 0.092387" ] }, { @@ -173,7 +240,7 @@ "stream": "stdout", "text": [ "\n", - "0.832668325534" + "Computed iterate 24 with error 0.082524" ] }, { @@ -181,7 +248,8 @@ "stream": "stdout", "text": [ "\n", - "0.713060167719" + "Computed iterate 25 with error 0.073778\n", + "Computed iterate 26 with error 0.066009" ] }, { @@ -189,7 +257,7 @@ "stream": "stdout", "text": [ "\n", - "0.61371626793" + "Computed iterate 27 with error 0.059100" ] }, { @@ -197,7 +265,8 @@ "stream": "stdout", "text": [ "\n", - "0.53063330463" + "Computed iterate 28 with error 0.052948\n", + "Computed iterate 29 with error 0.047463" ] }, { @@ -205,7 +274,8 @@ "stream": "stdout", "text": [ "\n", - "0.460668631589" + "Computed iterate 30 with error 0.042567\n", + "Computed iterate 31 with error 0.038195" ] }, { @@ -213,7 +283,8 @@ "stream": "stdout", "text": [ "\n", - "0.401394661594" + "Computed iterate 32 with error 0.034285\n", + "Computed iterate 33 with error 0.030788" ] }, { @@ -221,7 +292,8 @@ "stream": "stdout", "text": [ "\n", - "0.350903428553" + "Computed iterate 34 with error 0.027656\n", + "Computed iterate 35 with error 0.024851" ] }, { @@ -229,7 +301,8 @@ "stream": "stdout", "text": [ "\n", - "0.307676036308" + "Computed iterate 36 with error 0.022336\n", + "Computed iterate 37 with error 0.020081" ] }, { @@ -237,7 +310,7 @@ "stream": "stdout", "text": [ "\n", - "0.27049798974" + "Computed iterate 38 with error 0.018057" ] }, { @@ -245,7 +318,8 @@ "stream": "stdout", "text": [ "\n", - "0.238388117941" + "Computed iterate 39 with error 0.016240\n", + "Computed iterate 40 with error 0.014609" ] }, { @@ -253,7 +327,8 @@ "stream": "stdout", "text": [ "\n", - "0.210548793647" + "Computed iterate 41 with error 0.013144\n", + "Computed iterate 42 with error 0.011828" ] }, { @@ -261,7 +336,8 @@ "stream": "stdout", "text": [ "\n", - "0.186327054293" + "Computed iterate 43 with error 0.010644\n", + "Computed iterate 44 with error 0.009581" ] }, { @@ -269,7 +345,8 @@ "stream": "stdout", "text": [ "\n", - "0.165184942744" + "Computed iterate 45 with error 0.008624\n", + "Computed iterate 46 with error 0.007764" ] }, { @@ -277,7 +354,8 @@ "stream": "stdout", "text": [ "\n", - "0.146676609164" + "Computed iterate 47 with error 0.006990\n", + "Computed iterate 48 with error 0.006294" ] }, { @@ -285,7 +363,8 @@ "stream": "stdout", "text": [ "\n", - "0.130430429253" + "Computed iterate 49 with error 0.005667\n", + "Computed iterate 50 with error 0.005103" ] }, { @@ -293,7 +372,7 @@ "stream": "stdout", "text": [ "\n", - "0.116134976434" + "Computed iterate 1 with error 2.114102" ] }, { @@ -301,7 +380,8 @@ "stream": "stdout", "text": [ "\n", - "0.103527938351" + "Computed iterate 2 with error 1.768086\n", + "Computed iterate 3 with error 1.512748" ] }, { @@ -309,7 +389,8 @@ "stream": "stdout", "text": [ "\n", - "0.0923873003367" + "Computed iterate 4 with error 1.309807\n", + "Computed iterate 5 with error 1.142560" ] }, { @@ -317,7 +398,8 @@ "stream": "stdout", "text": [ "\n", - "0.0825242944775" + "Computed iterate 6 with error 1.003430\n", + "Computed iterate 7 with error 0.886428" ] }, { @@ -325,7 +407,8 @@ "stream": "stdout", "text": [ "\n", - "0.0737777259241" + "Computed iterate 8 with error 0.787023\n", + "Computed iterate 9 with error 0.701967" ] }, { @@ -333,7 +416,8 @@ "stream": "stdout", "text": [ "\n", - "0.0660093832382" + "Computed iterate 10 with error 0.628656\n", + "Computed iterate 11 with error 0.565065" ] }, { @@ -341,7 +425,8 @@ "stream": "stdout", "text": [ "\n", - "0.0591003057495" + "Computed iterate 12 with error 0.509586\n", + "Computed iterate 13 with error 0.460920" ] }, { @@ -349,7 +434,8 @@ "stream": "stdout", "text": [ "\n", - "0.05294773235" + "Computed iterate 14 with error 0.418022\n", + "Computed iterate 15 with error 0.380033" ] }, { @@ -357,7 +443,7 @@ "stream": "stdout", "text": [ "\n", - "0.0474625949005" + "Computed iterate 16 with error 0.346252" ] }, { @@ -365,7 +451,8 @@ "stream": "stdout", "text": [ "\n", - "0.0425674491262" + "Computed iterate 17 with error 0.316095\n", + "Computed iterate 18 with error 0.289078" ] }, { @@ -373,7 +460,8 @@ "stream": "stdout", "text": [ "\n", - "0.0381947586263" + "Computed iterate 19 with error 0.264794\n", + "Computed iterate 20 with error 0.242900" ] }, { @@ -381,7 +469,8 @@ "stream": "stdout", "text": [ "\n", - "0.034285465252" + "Computed iterate 21 with error 0.223108\n", + "Computed iterate 22 with error 0.205169" ] }, { @@ -389,7 +478,8 @@ "stream": "stdout", "text": [ "\n", - "0.0307877927868" + "Computed iterate 23 with error 0.188873\n", + "Computed iterate 24 with error 0.174037" ] }, { @@ -397,7 +487,8 @@ "stream": "stdout", "text": [ "\n", - "0.0276562415505" + "Computed iterate 25 with error 0.160504\n", + "Computed iterate 26 with error 0.148139" ] }, { @@ -405,7 +496,8 @@ "stream": "stdout", "text": [ "\n", - "0.0248507399348" + "Computed iterate 27 with error 0.136822\n", + "Computed iterate 28 with error 0.126449" ] }, { @@ -413,7 +505,8 @@ "stream": "stdout", "text": [ "\n", - "0.0223359254809" + "Computed iterate 29 with error 0.116929\n", + "Computed iterate 30 with error 0.108181" ] }, { @@ -421,7 +514,7 @@ "stream": "stdout", "text": [ "\n", - "0.0200805333435" + "Computed iterate 31 with error 0.100134" ] }, { @@ -429,7 +522,8 @@ "stream": "stdout", "text": [ "\n", - "0.0180568741442" + "Computed iterate 32 with error 0.092723\n", + "Computed iterate 33 with error 0.085893" ] }, { @@ -437,7 +531,8 @@ "stream": "stdout", "text": [ "\n", - "0.0162403865331" + "Computed iterate 34 with error 0.079593\n", + "Computed iterate 35 with error 0.073778" ] }, { @@ -445,7 +540,8 @@ "stream": "stdout", "text": [ "\n", - "0.0146092524399" + "Computed iterate 36 with error 0.068406\n", + "Computed iterate 37 with error 0.063441" ] }, { @@ -453,7 +549,8 @@ "stream": "stdout", "text": [ "\n", - "0.0131440651338" + "Computed iterate 38 with error 0.058849\n", + "Computed iterate 39 with error 0.054600" ] }, { @@ -461,7 +558,8 @@ "stream": "stdout", "text": [ "\n", - "0.0118275419375" + "Computed iterate 40 with error 0.050667\n", + "Computed iterate 41 with error 0.047025" ] }, { @@ -469,7 +567,8 @@ "stream": "stdout", "text": [ "\n", - "0.0106442748427" + "Computed iterate 42 with error 0.043651\n", + "Computed iterate 43 with error 0.040525" ] }, { @@ -477,7 +576,7 @@ "stream": "stdout", "text": [ "\n", - "0.00958051340986" + "Computed iterate 44 with error 0.037627" ] }, { @@ -485,7 +584,8 @@ "stream": "stdout", "text": [ "\n", - "0.00862397526576" + "Computed iterate 45 with error 0.034940\n", + "Computed iterate 46 with error 0.032448" ] }, { @@ -493,7 +593,8 @@ "stream": "stdout", "text": [ "\n", - "0.00776368027316" + "Computed iterate 47 with error 0.030136\n", + "Computed iterate 48 with error 0.027991" ] }, { @@ -501,10 +602,35 @@ "stream": "stdout", "text": [ "\n", - "0.00698980507068" + "Computed iterate 49 with error 0.026000\n", + "Computed iterate 50 with error 0.024153" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n" + ] + }, + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 4, + "text": [ + "(0.39945149497311855, 2.5034328637756031)" + ] + }, + { + "metadata": {}, + "output_type": "display_data", + "png": "iVBORw0KGgoAAAANSUhEUgAAAmUAAAG7CAYAAACCU+LlAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3Xl8XHd97//XmZkzo9XyLmuzFsu7Qy4mlJK2JBA3JCQh\nCxwIO5SwtYVAafmFlsulv/uAB7/btBRSllC2pEkgHELYskBNWLIRuBiTxIusfbVsS5Zka5s5Z875\n/XFkS3ZiR7KlOTOj9/OvmaNZPpK1vH2+n/P5goiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI\niIiISFYxMvlmlmW9BLgaGAduA6qBmwAXuMO27eZM1iMiIiKy6FiWVW5Z1o2nHfv7GbdvyXxVIiIi\nItkhksH3uhIYsizrHy3LevnUsWMzPj6RwVpEREREskomQ1k9UGHb9meAl1mWFeXU5dPJDNYiIiIi\nklViGXwvH7hz6vY+oBIwT/v483ryySf9sbGxBSxNREREZN78aseOHZfO9UmZDGW/AS4CfksQyH4J\nlAJYlmWcuP18xsbG2L59ewZKFBERETk/u3btuuRcnpex5Uvbth8GrrAs6+NA0rbtJHCfZVmfBj4D\n3JepWkRERESyTUZHYpyrnTt3+jpTJiIiIrlg165d7NixY84ZK5ON/iIiIiJyBgplIiIiIlkgk43+\nCyKVSjEwMBB2GXlj5cqVxOPxsMsQERFZdHI6lKVSKQ4dOkRVVRWRiE76nS/P8+jt7aW8vFzBTERE\nJMNyOskMDAwokM2jSCRCVVWVzjyKiIiEIOfTjALZ/NLXU0REJBz6CywiIiKSBRTKRERERLKAQpmI\niIhIFsjpqy8XmwceeICmpiYikQgVFRW88Y1vfM5j7rrrLvr7+zFNk8bGRq666ioAtm/fTl9fH2Vl\nZfzzP/8zN954Y6bLFxERkbNQKMuQZ555ho6ODgDa2tq4+eab5/T8Y8eOceutt/KLX/wCgMsvv5wd\nO3awYsWKk4/Zu3cv99xzDw8++CAA119/PZdddhkFBQXcfPPNXHbZZaxZs4ZYTP/sIiIi2UbLlxmw\nd+9eRkZGuOaaa7jmmmt45JFH5vwaTzzxBBs3bjx5f9u2bTz66KOnPGbnzp3U1taevL9q1Sqeeuop\nAOLxONXV1QpkIiIiWUp/oTNg//793HDDDQDs3r2bzZs3A9DR0cGdd955xudddNFFvOY1rwE4ufR4\nQllZGW1tbac8vrS0FMdxTt6fnJykubmZSy65hD/84Q8kk0mOHz9OY2MjV1555bx9fiIiInL+8jqU\n/ehHxfPyOq997dg5P7e/v5/Kykr27t3LnXfeSVdXF//2b/8GQF1dHZ/85Cdn9TojIyMkEomT903T\nZGzs1Lquvvpq7r77bnzfZ3R0lJaWFrZv3w7AK17xCq6++uqTty+++OJTQp6IiIiES8uXC+z3v/89\nF110EVu2bOGzn/0sO3bs4O67757z65SUlOD7/sn7k5OTLF269JTHrFq1ittuu4077riDxx9/nC1b\ntrBy5UqAk2fcAJYuXcpjjz12jp+RiIiILIS8PlN2Pme45svk5OQpfVxNTU00NDQAc1u+rKurY/fu\n3Sc/Njg4yIUXXvic52zatOnk8ui//Mu/8I//+I9897vf5aGHHuKb3/wmAOPj4+otExERyTL6y7zA\nnnzySV73utcBQZD63e9+xyc+8QlgbsuXF198MZ/61KdO3n/66adP3m9vb6euro7u7m7e8pa38Oij\nj9LU1ER1dTUNDQ0cPnyYd73rXUAQyAYGBviLv/iL+fskRURE5LwZYRcwGzt37vRP9EbN1NfXR2Vl\nZQgVzc6+fftob29ndHSUwsJC9uzZw1vf+laqq6vP6fXuvfdeuru78TyP+vp6LMsC4NJLL+ULX/gC\nmzdv5tZbb2X16tW0trbysY997OQSp23bDAwM0N3dzQ033MBFF110xvfJ9q+riIhINtu1axc7duyY\nc8ZSKFtA999/P9dff33YZcxZtn9dRUREstm5hjI1+i+gSERfXhEREZkdpYYFdO2114ZdgoiIiOQI\nhTIRERGRLKBQJiIiIpIFFMpEREREsoBCmYiIiEgWUCgTERERmSfR/nPfxlChTERERGQexLofJLH/\nq+f+/HmsRURERGTx8T3Mtnsxux86r5dRKBMRERE5V55LvOnrxA49DpEoyY3vhd5zeyktX4qIiIic\ni/QkiWf/PQhk0QImt/0d6fKXn/PL6UxZDnnggQdoamoiEolQUVHBG9/4xuc85q677qK/vx/TNGls\nbOSqq64C4OGHH6avr4/JyUlqamq45pprMl2+iIhI/nBGKXjmX4kca8U3S0le8Hd4S9ad10sqlGXI\nM888Q0dHBwBtbW3cfPPNc3r+sWPHuPXWW/nFL34BwOWXX86OHTtYsWLFycfs3buXe+65hwcffBCA\n66+/nssuu4yBgQGam5v54Ac/CMCHPvQhXvnKV1JSUjIPn5mIiMjiYkwOkHj6ViLjffgFK5l80T/g\nF1Wc9+tq+TID9u7dy8jICNdccw3XXHMNjzzyyJxf44knnmDjxo0n72/bto1HH330lMfs3LmT2tra\nk/dXrVrFU089xdGjR/nVr35FKpUCoKioiHg8fo6fjYiIyOJljHZT8If/TWS8D6+khskX/895CWSg\nM2UZsX//fm644QYAdu/ezebNmwHo6OjgzjvvPOPzLrroIl7zmtcA0NfXR1lZ2cmPlZWV0dbWdsrj\nS0tLcRzn5P3JyUmam5u56aab8DyPyy67jHe84x286lWvUigTERGZo8jwfhLP/juGO0566SaS2z4M\nsaJ5e/28DmVFv3z7vLzO+KVnDk4vpL+/n8rKSvbu3cudd95JV1cX//Zv/wZAXV0dn/zkJ2f1OiMj\nIyQSiZP3TdNkbGzslMdcffXV3H333fi+z+joKC0tLWzfvh2AD3/4w3zuc5/jk5/8JJ/5zGfO+fMR\nERFZjKJHfkdi31fAc0iveinJTe+D6Pye4NDy5QL7/e9/z0UXXcSWLVv47Gc/y44dO7j77rvn/Dol\nJSX4vn/y/uTkJEuXLj3lMatWreK2227jjjvu4PHHH2fLli2sXLmSlpYWHnvsMe6//37uuecebr31\nVp566qnz/txEREQWg1jfIyT2/gd4Dm7VZSS3/M28BzLI8zNl53OGa75MTk4Si01/mZuammhoaADm\ntnxZV1fH7t27T35scHCQCy+88DnP2bRp08nl0X/5l3/h4x//OA899BDXXXcdAJdeeilf+tKXeOqp\np3jZy152/p+giIhIvvJ9zI77MTt/AIBTdwNO7bVgGAvydnkdyrLBk08+yete9zogCFK/+93v+MQn\nPgHMbfny4osv5lOf+tTJ+08//fTJ++3t7dTV1dHd3c1b3vIWHn30UZqamqiurmbdunXU1tayb98+\ntmzZAkAymeSiiy6av09SREQk33hp4s3fInbwV2BESK1/J27lpQv6lgsT9ebZzp07/RO9UTP19fVR\nWVkZQkWzs2/fPtrb2xkdHaWwsJA9e/bw1re+lerq6nN6vXvvvZfu7m48z6O+vh7LsoDg7NcXvvAF\nNm/ezK233srq1atpbW3lYx/72Mklzq985SuMj49TVFREWVkZb3rTm874Ptn+dRUREVlQ6SSJvV8i\n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\nAElFTkSuQmCC\n", + "text": [ + "" ] } - ] + ], + "prompt_number": 4 }, { "cell_type": "code", From 004860521bbdc622a6e28728af77c366d03d89cd Mon Sep 17 00:00:00 2001 From: Spencer Lyon Date: Tue, 5 Aug 2014 10:05:20 -0700 Subject: [PATCH 2/2] TESTS: added tests for LucasTree class --- quantecon/tests/__init__.py | 10 ++- quantecon/tests/data/testing_data.h5 | Bin 0 -> 346352 bytes quantecon/tests/test_lucastree.py | 108 ++++++++++++++++++++++ quantecon/tests/util.py | 130 +++++++++++++++++++++++++++ setup.py | 2 +- 5 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 quantecon/tests/data/testing_data.h5 create mode 100644 quantecon/tests/test_lucastree.py create mode 100644 quantecon/tests/util.py diff --git a/quantecon/tests/__init__.py b/quantecon/tests/__init__.py index de0d56246..d37314c89 100644 --- a/quantecon/tests/__init__.py +++ b/quantecon/tests/__init__.py @@ -1 +1,9 @@ -# blank +""" +namespace for quantecon.tests + +@author : Spencer Lyon +@date : 2014-08-01 13:13:59 + +""" +from . util import (capture, get_data_dir, get_h5_data_file, write_array, + max_abs_diff, get_h5_data_group) diff --git a/quantecon/tests/data/testing_data.h5 b/quantecon/tests/data/testing_data.h5 new file mode 100644 index 0000000000000000000000000000000000000000..fc297f1b81e237be9ba0ff60c3f52d5672ce3327 GIT binary patch literal 346352 zcmeI$33yG{zwq&WG7y9YL5LwFk(feA$w1dHi4YYDNern5DWO_J$Y7p}RB6pa6;;}* zc_?CxQd3PS)oNAMSZYqlEP2n#*{AyIy?^)K=Y8ILZ~NVzbJpH#{npxReb(A5`*=6B zZM*ViYn0VYhn<~fqdAnETE2?)<6)?6NtWf>Qr<^DG3aTkp02SnpBS`KnyJi5&v($< zcd<5SwydGd#r_C%CUXWJQ*X#4^+FtW5scBl@cE*3v9iqdG3s|dc z{Fv6L~rTNi!!6ZQSvqS3c^ zO8+zPv z*0{1vEm>KcZ)0cN^-b5-R@M{sDyF|2rshhPU?qJenqt=FUyS-!<1cNDG51o_f&(KX z17rT|_1FF1wBjuB-unKn-_}@SJ}l3JW&OI;wUqqZspYx3U^)4>!~S?%OfyaTKj5&| z=eeSb(q~jOpK_W{vHm{${Jj48y}&d_mU*&Jnf`tnjJcNgT}%4cNJ|ZKn%emPzP3z+ zW&OTj+McV-B?1T_fB*srAb`OCbOD3@`@=o<9l}JdU{v?8SmMa|G9oPXw#V`m-lSl zg#-Zv5I_I{1Q7UJ3H+)`NA_QnUHm}3+w+~%4IA86i*D`xY5&ZJs`}A_J44p|u4Z)g z-RrgVk#byIXov~ArzZP(%}X1bsn+iu5FFn6p_*&cujiG3EOn~sjfn?>AF1;0eS2o! z&Qh0r9oJuIo~b@Q(<)%(jK}KeqzXM}XJo3Bf+d%C)_tP7GVU>lvB<9X_GRtm0@eO zYLmWrqO4aub@J+#qxLND**hm7TRjc7jo*GgN7X+QQFY3ZY*qMRQsrKqbJd}M(#cah z=BVR-JFeIq%~h{Hy!B}Di5zwQuHWfE|2#GF>X24#+vloXvqna|yEaexx~)Csx-3^6 ztx$GNOQ(D#A2*p)H$7M7#%}XmG9_OfnLpslmKJ#`!?SeLmiO}2zQ*r_#MO><4KI&f{-g|7bondup0T`sII zQ=D#{Q{}g=9(U4hHxJPIEze803OHOa!ux9avY`>DkET9O|8Dd?$7AKrr6){W-M@0* z2kGA(8EIp^XJz_`@6L4S<8m{-ZP0gT+jKdp#wM@zic9_}{ml+Dqn+#gqFj5~-AsJ% zV0y3PV`3^@xT(g6M}I$k;XZX@e~Mjt!hJQd@$PvpAO4`)hxr}~dXTAJpFMTmnJw2; z{ST|{nlU$9-F&tCq{s1hRPwUbJGQyzt9R~?-EcVNk*d(3+w_7}PgO$SdacXVf1*Y@ z4=?36LzDTR?tA6cgSl#B@fS8$0ao(+;wueKh83y-n!)$0>(&z9DrUl`M~c;=mwwrC zZn~|^4_Y?Oez8HU=P#{3%dNDOxmjs&=MZbzw`pA;-#vEnQ6_ z>F0K?a*$Q6!q2^BUs+PUR-8H)TTw=~p0&Pke`Oh;_fhwCRVqmz zr)3#4hdRpnsh0|)PgIh=Ip>`l)vh9kni)o18DClY$4B=0?VBp%H?Z@}KFu5@DdSX7 zMsii@JJ$Jf#$`v@v_HIER_$tXa#?hP$XQin{r0eTVvkf4cdPfF(0NglRqAG8`B#$7)JIwby=V65}k#H=Ldl_(m-mKWok9fNWS~#rd`5tDK_?F3+hc z{mUeKTZhg3x98Nsd^vs?*@`A^QVgwLC009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**{)Pg-s=c-C z#x`7gUtQVR@zYhOZz|g+oemD1`A}W0{6XOKznZ!#OP#Q{`AX6rsY#w%K$?22 z8jbJinJ_j}4Luf|UiaK%wJg)8LQc~xHL38*%IMxt)Qu5Gx|}_qrS7#FpV0Qk6IJ>8 zPN&tw9;+KM$L?;9&sJ7jetYMv%@b9%PlKfQuVky4Sy53pWIVMMqOkVbO ze${MctUK(b(>ZFXTU60ci?UUB=iQ?}RJm%?YhB+8bj(q)C+!MSHs-3wJzw6iZ)T3F zdnD-0?HYNi*S&Xr(+#<5Xh5=Glc{;il1TTm!Vl-4!@VDo;Du7W%t!wHSU!E zt?NpVy@2s{=p0^VPe%@|4%clUBbt7pTjXn)n>5o3Gj>%w4^5 zT!Fe(zTRo4)O=OG{HzH@mkN}RA$aHRyZLI8cKZD)Z3@-L7304<7Ez#Lw`4EO`LIxp zwaU%txurmD9c4RVUrwR=(kUWrcEv)q>6a+`l&Gib;k&P%pO{dn7Djh!+G68V^<{MI z2{~P;?wm;9YGqfX;vUT3cD3PCReZNo@uNOP>Td5ni6f^yRd3E~6kUFov3%aAL6xsO zRodmSgx(ItD*WJ$UI+Y(RLvtfb29rEE3fdwAI+Rsr0QF3s+6(USl%$Uc+8z5Rru%| zKdp==p54waSP@jLehG8?F{FhioeoU)vt3fGPTyVhe(P9GT$>Ea+#3}f}=&fU)`+9=u&F3U6>|cd%yY9fFCvK@^Om#Em@PQiN}qTZIHem-QC8l z&}2~L;E6vpG{`mEyaPv$X>!Q_lPlg)23he&qq`>`Y0@-G3ym0KkVipd5@y#h$k7ka zxVBhjkfPWkJI7#y1%HrOH+6J+bzv08qkPtus0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009IL_;&>inyqFqmOAMX4w^&BS!h%1k~B@vkB$rp(TtJB z&mDTP=HP9Px3grB{-Xp!LjpUS2HZm*wRsh3+Cwk%y0Bn$(@#um&UA#DlmGH}MSZ<) zZfw3!hJHVL&9|gYgH}qjGyaS25FKV*z*=SF$Iyi5@VdXesEY|RFv`BRNuBF-}q%b+DAroH4Xe(yy9QCaKe;sdWV~i=zbOZ-RMh3?G>+#wc z<1F#sUfw13Ec;3iy)$NolA@BYsPKrk24k&1_K#+Ir=Nvz_8$;m0R#|00D-@az)PWJ#w_URD$l1=LPD(l z5?y6h>ubFtm%B=C!wS1%4!O#ew^!Uac->X}rk`qAXzeC9FONSrxvrZm+5b|f6>Z$) zOshT-lY6*H+p3|*dJK1y$^I|-w|&n|Lgv4w%~<6obIV?t`}H0-ajNIzUVP3?E*_n{ z)9rE%ca4{|HimrF}} zxVP}AFRH<)b%RxX8Dv$q{hIFeWy7cbKVKbMUp}!PH>6goG47LF$$U}x#UOJ@9MGxseYgN&E zSspUz>hTYbl=GCo&B9_J2q1s}0tg_000IagfB*srAbg)Aa zfAjj&^!wRsQqrP9E2Y^P|3!C*4l^!bt+MgsZ2Va6-!CpH&ZYm*;Vy%c`^F_E4Udoa zN*Lvm6rY%6?4%__xAEGsb|?=X6v0XE0h$Kd_{#vv^5xOS@sd%SM*Ll3*qcPAn^P={(1eI z=EO2DmZnVmyUG2z?Y;P~k>(l?L!X-$7jwR4-Yo5sB7gt_2q1vK-$x)O_-xX=eFoX@ z_(AfncGhxce9{*yj@!t>?5A@lhn14Io(7~$IA2;+)We43Hd9KP@XwA`kQ} zyWC!SEe`GTeY*;hdve!1_i|p6@?O^~ExzC&k-sc24BAyuYTw>*uJQ6p@_6fm-5%2` zOKO{?L+d0tN{Zv)eTDt1$b?O$5ABGlDwh}JuTP1rCf4p}vb`gmBs8aR@{Wk=($-D= zbSJ8YBsTcC{o$U@a^~^qyyXLG%8q5;{{ACs$%C)wypcGgwk*s@x$nEOj=Z&Lq|>Qb z7nyg_+xO~S7wI?DX2f2_vfu!T~Ff5EZK6&-&H!sH;Db_tgEc? z%kzJ8kehgB+058d+Fg7GBz8Q!+FhoOco4HFxW0IH%$(tPy}l$LpIz8|nuq+*bX>C5 z&{MkQHhAm(GoJEosMVgYQW}Wk;Rn^`)M+S1d%q61`KFq^;?Kb(zat+sV$`c+O3_(+-)J{+C7?hu(OYJaWx#hxZOv3#x$C^#rb7% zXt88|$mEyh+pz^+i*COxrH0MT*xaS1TndiNoVL5A1a!}Ry}DZ~iLIORc+mT;WRXXe z5fk!SNl2zDIyp4}^QOYSDz&Nt@2_C|b9zd&i@ek$B+WT4dUwm!bs&Oq5cVOzIb z*@5Eso!Wb