from compecon.tools import nodeunif from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm # Univariate Taylor approximation x = np.linspace(-1, 1, 100) y = (x + 1) * np.exp(2 * x) y1 = 1 + 3 * x y2 = 1 + 3 * x + 8 * x**2 plt.figure(figsize=[6, 6]) plt.plot(x, y, 'k', linewidth=3, label='Function') plt.plot(x, y1, 'b', linewidth=3, label='1st order approximation') plt.plot(x, y2, 'r', linewidth=3, label='2nd order approximation') plt.legend() plt.xticks([-1, 0, 1]) plt.show() ## Bivariate Taylor approximation nplot = [101, 101] a = [0, -1] b = [2, 1] x1, x2 = nodeunif(nplot, a, b) x1.shape = nplot x2.shape = nplot y = np.exp(x2) * x1**2 y1 = 2 * x1 - x2 - 1 y2 = x1**2 - 2 * x1 * x2 + 0.5 * x2**2 + x2
S = BasisSpline(n, a, b, f=ff) L = BasisSpline(n, a, b, k=1, f=ff) # Compute actual and fitted values on grid y = ff(x) # actual yc = C(x) # Chebychev approximant ys = S(x) # cubic spline approximant yl = L(x) # linear spline approximant # Plot function approximations plt.figure() ymin = np.floor(y.min()) ymax = np.ceil(y.max()) xlim = [a, b] ylim = [-0.2, 1.2] if ifunc == 2 else [ymin, ymax] subfig(1, x, y, xlim, ylim, 'Function') subfig(2, x, yc, xlim, ylim, 'Chebyshev') subfig(3, x, ys, xlim, ylim, 'Cubic Spline') subfig(4, x, yl, xlim, ylim, 'Linear Spline') # Plot function approximation error plt.figure() plt.plot(x, np.c_[yc - y, ys - y], linewidth=3) plt.xlabel('x') plt.ylabel('Approximation Error') plt.legend(['Chebychev Polynomial', 'Cubic Spline']) # pltlegend('boxoff') plt.show()
model = DPmodel(basis, reward, transition, discount=delta, j=['keep', 'clear cut']) model.solve() resid, sr, vr = model.residuals() # Plot Action-Contingent Value Functions demo.figure('Action-Contingent Value Functions', 'Biomass', 'Value of Stand') plt.plot(sr, vr.T) plt.legend(model.labels.j, loc='upper center') # Compute and Plot Optimal Harvesting Stock Level scrit = np.interp(0.0, vr[1] - vr[0], sr) vcrit = np.interp(scrit, sr, vr[0]) demo.annotate(scrit, vcrit, '$s^* = {:.2f}$'.format(scrit), 'wo', (-5, 5), fs=12) print('Optimal Biomass Harvesting Level = {:5.2f}'.format(scrit)) # Plot Residual demo.figure('Bellman Equation Residual', 'Biomass', 'Percent Residual') plt.plot(sr, 100 * resid.T / vr.max(0).T)
vlq, plq = growth_model.Value(S.Wealth, order) klq = growth_model.Policy(S.Wealth) # ============ Compute Analytic Solution vtrue = vstar + b * (np.log(S.Wealth) - np.log(sstar)) # ============== Make plots: Wealth = S.Wealth.T # Plot Optimal Policy demo.figure('Optimal Investment Policy', 'Wealth', 'Investment') plt.plot(Wealth, np.c_[k, klq]) demo.annotate(sstar, kstar,'$s^*$ = %.2f\n$k^*$ = %.2f' % (sstar, kstar), 'bo', (10, -7)) plt.legend(['Chebychev Collocation','L-Q Approximation'], loc = 'upper left') # Plot Value Function demo.figure('Value Function', 'Wealth', 'Value') plt.plot(Wealth, np.c_[v, vlq]) demo.annotate(sstar, vstar,'$s^*$ = %.2f\n$V^*$ = %.2f' % (sstar, vstar),'bo', (10, -7)) plt.legend(['Chebychev Collocation','L-Q Approximation'], loc= 'upper left') # Plot Shadow Price Function demo.figure('Shadow Price Function', 'Wealth', 'Shadow Price') plt.plot(Wealth, np.c_[pr, plq]) demo.annotate(sstar, pstar,'$s^*$ = %.2f\n$\lambda^*$ = %.2f' % (sstar, pstar), 'bo', (10, 7)) plt.legend(['Chebychev Collocation','L-Q Approximation'])
plt.plot(s, q.T) # Plot Value Function demo.figure('Value Function', 'Ore Stock', 'Value') plt.plot(s, v.T) # Plot Shadow Price Function demo.figure('Shadow Price Function', 'Ore Stock', 'Shadow Price') plt.plot(s, model.Value(s, 1)) # Plot Residual demo.figure('Bellman Equation Residual', 'Ore Stock', 'Residual') plt.plot(s, resid.T) plt.hlines(0, 0, smax, 'k', '--') ## SIMULATION # Simulate Model T = 20 data = model.simulate(T, smax) # Plot State and Policy Paths data[['stock', 'extracted']].plot() plt.title('State and Policy Paths') plt.legend(['Stock', 'Extraction']) plt.hlines(sstar, 0, T, 'k', '--') plt.xlabel('Period') plt.ylabel('Stock / Extraction') plt.show()
plt.plot(s, v.T) # Plot Shadow Price Function demo.figure('Shadow Price Function', 'Stock', 'Shadow Price') plt.plot(s, model.Value(s, 1).T) # Plot Residual demo.figure('Bellman Equation Residual', 'Stock', 'Residual') plt.plot(s, resid.T) plt.hlines(0, smin, smax, 'k', '--') ## SIMULATION # Simulate Model T = 15 data = model.simulate(T, smin) print(data) # Plot State and Policy Paths opts = dict(spec='r*', offset=(0, -5), fs=11, ha='right') data[['available', 'harvest']].plot() demo.annotate(T, sstar, 'steady-state stock = %.2f' % sstar, **opts) demo.annotate(T, qstar, 'steady-state harvest = %.2f' % qstar, **opts) plt.xlim([0, T + 0.25]) plt.title('State and Policy Paths') plt.xlabel('Period') plt.ylabel('Stock / Harvest') plt.legend(['Stock', 'Harvest'], loc='right') plt.show()
# Plot Shadow Price Function demo.figure('Shadow Price Function', 'Stock', 'Shadow Price') plt.plot(s, model.Value(s, 1).T) # Plot Residual demo.figure('Bellman Equation Residual','Stock', 'Residual') plt.plot(s, resid.T) plt.hlines(0, smin, smax, 'k', '--') ## SIMULATION # Simulate Model T = 15 data = model.simulate(T, smin) print(data) # Plot State and Policy Paths opts = dict(spec='r*', offset=(0,-5), fs=11, ha='right') data[['available', 'harvest']].plot() demo.annotate(T, sstar, 'steady-state stock = %.2f' % sstar, **opts) demo.annotate(T, qstar, 'steady-state harvest = %.2f' % qstar, **opts) plt.xlim([0, T + 0.25]) plt.title('State and Policy Paths') plt.xlabel('Period') plt.ylabel('Stock / Harvest') plt.legend(['Stock','Harvest'], loc='right') plt.show()
## Analysis # Display Optimal Policy xtemp = model.policy.reshape((n1, n2)) header = '{:^8s} {:^8s} {:^8s} {:^8s}'.format('Age', 'Lo', 'Med', 'Hi') print('Optimal Policy') print(header) print(*('{:^8d} {:^8s} {:^8s} {:^8s}\n'.format(s, *X[x]) for s, x in zip(s1, xtemp))) # Plot Value Function demo.figure('Optimal Replacement Value', 'Age', 'Optimal Value (thousands)') plt.plot(s1, model.value.reshape((n1, n2)) / 1000) plt.legend(['Low', 'Med', 'Hi']) # Compute Steady-State distribution pi = model.markov().reshape((n1, n2)) # Display Steady-State distribution print(' Invariant Distribution ') print(header) print(*('{:^8d} {:8.3f} {:8.3f} {:8.3f}\n'.format(s, *x) for s, x in zip(s1, pi))) # Compute Steady-State Mean Cow Age and Productivity pi = pi.flatten() avgage = np.dot(pi.T, S1) avgpri = np.dot(pi.T, S2) print('Steady-state Age = {:8.2f}'.format(avgage))
figs = [] figs.append(demo.figure("Runge's Function", '', 'y')) plt.plot(x, y) plt.text(-0.8, 0.8, r'$y = \frac{1}{1+25x^2}$', fontsize=18) plt.xticks=[] # In[9]: figs.append(demo.figure("Runge's Function $11^{th}$-Degree\nPolynomial Approximation Error.",'x', 'Error')) plt.hlines(0, a, b, 'gray', '--') plt.plot(x, errcheb[4], label='Chebychev Nodes') plt.plot(x, errunif[4], label='Uniform Nodes') plt.legend(loc='upper center') # Plot approximation error per degree of approximation # In[10]: figs.append(demo.figure("Log10 Polynomial Approximation Error for Runge's Function",'', 'Log10 Error')) plt.plot(n, nrmcheb, label='Chebychev Nodes') plt.plot(n, nrmunif, label='Uniform Nodes') plt.legend(loc='upper left') plt.xticks=[] # In[11]:
## Analysis # Display Optimal Policy xtemp = model.policy.reshape((n1, n2)) header = '{:^8s} {:^8s} {:^8s} {:^8s}'.format('Age','Lo', 'Med', 'Hi') print('Optimal Policy') print(header) print(*('{:^8d} {:^8s} {:^8s} {:^8s}\n'.format(s, *X[x]) for s, x in zip(s1, xtemp))) # Plot Value Function demo.figure('Optimal Replacement Value', 'Age', 'Optimal Value (thousands)') plt.plot(s1, model.value.reshape((n1,n2)) / 1000) plt.legend(['Low','Med','Hi']) # Compute Steady-State distribution pi = model.markov().reshape((n1, n2)) # Display Steady-State distribution print(' Invariant Distribution ') print(header) print(*('{:^8d} {:8.3f} {:8.3f} {:8.3f}\n'.format(s, *x) for s, x in zip(s1, pi))) # Compute Steady-State Mean Cow Age and Productivity pi = pi.flatten() avgage = np.dot(pi.T, S1)
# Plot Value Function demo.figure('Value Function', 'Ore Stock', 'Value') plt.plot(s, v.T) # Plot Shadow Price Function demo.figure('Shadow Price Function', 'Ore Stock', 'Shadow Price') plt.plot(s, model.Value(s, 1)) # Plot Residual demo.figure('Bellman Equation Residual', 'Ore Stock', 'Residual') plt.plot(s, resid.T) plt.hlines(0, 0, smax,'k', '--') ## SIMULATION # Simulate Model T = 20 data = model.simulate(T, smax) # Plot State and Policy Paths data[['stock', 'extracted']].plot() plt.title('State and Policy Paths') plt.legend(['Stock','Extraction']) plt.hlines(sstar, 0, T, 'k', '--') plt.xlabel('Period') plt.ylabel('Stock / Extraction') plt.show()
figs = [] figs.append(demo.figure("Runge's Function", '', 'y')) plt.plot(x, y) plt.text(-0.8, 0.8, r'$y = \frac{1}{1+25x^2}$', fontsize=18) plt.xticks = [] # In[9]: figs.append( demo.figure( "Runge's Function $11^{th}$-Degree\nPolynomial Approximation Error.", 'x', 'Error')) plt.hlines(0, a, b, 'gray', '--') plt.plot(x, errcheb[4], label='Chebychev Nodes') plt.plot(x, errunif[4], label='Uniform Nodes') plt.legend(loc='upper center') # Plot approximation error per degree of approximation # In[10]: figs.append( demo.figure("Log10 Polynomial Approximation Error for Runge's Function", '', 'Log10 Error')) plt.plot(n, nrmcheb, label='Chebychev Nodes') plt.plot(n, nrmunif, label='Uniform Nodes') plt.legend(loc='upper left') plt.xticks = [] # In[11]:
print('Critical Search Wage = {:5.1f}'.format(wcrit0)) wcrit1 = np.interp(0, vr[1, 1] - vr[1, 0], sr) vcrit1 = np.interp(wcrit1, sr, vr[1, 0]) print('Critical Quit Wage = {:5.1f}'.format(wcrit1)) # Plot Action-Contingent Value Function - Unemployed demo.figure('Action-Contingent Value, Unemployed', 'Wage', 'Value') plt.plot(sr, vr[0].T) demo.annotate(wcrit0, vcrit0, '$w^*_0 = {:.1f}$'.format(wcrit0), 'wo', (5, -5), fs=12) plt.legend(['Do Not Search', 'Search'], loc='upper left') # Plot Action-Contingent Value Function - Unemployed demo.figure('Action-Contingent Value, Employed', 'Wage', 'Value') plt.plot(sr, vr[1].T) demo.annotate(wcrit1, vcrit1, '$w^*_0 = {:.1f}$'.format(wcrit1), 'wo', (5, -5), fs=12) plt.legend(['Quit', 'Work'], loc='upper left') # Plot Residual demo.figure('Bellman Equation Residual', 'Wage', 'Percent Residual')
L = BasisSpline(n, a, b, k=1, f=ff) # Compute actual and fitted values on grid y = ff(x) # actual yc = C(x) # Chebychev approximant ys = S(x) # cubic spline approximant yl = L(x) # linear spline approximant # Plot function approximations plt.figure() ymin = np.floor(y.min()) ymax = np.ceil(y.max()) xlim = [a, b] ylim = [-0.2, 1.2] if ifunc==2 else [ymin, ymax] subfig(1, x, y, xlim, ylim, 'Function') subfig(2, x, yc, xlim, ylim, 'Chebyshev') subfig(3, x, ys, xlim, ylim, 'Cubic Spline') subfig(4, x, yl, xlim, ylim, 'Linear Spline') # Plot function approximation error plt.figure() plt.plot(x, np.c_[yc - y, ys - y], linewidth=3) plt.xlabel('x') plt.ylabel('Approximation Error') plt.legend(['Chebychev Polynomial','Cubic Spline']) # pltlegend('boxoff') plt.show()