# Compute and Plot Critical Unit Profit Contributions pcrit = [NLP(lambda s: model.Value_j(s)[i].dot([1,-1])).broyden(0.0)[0] for i in range(A)] vcrit = [model.Value(s)[i] for i, s in enumerate(pcrit)] # In[13]: fig1 = demo.figure('Action-Contingent Value Functions', 'Net Unit Profit','Value', figsize=[10,5]) cc = np.linspace(0.3,0.9,model.dims.ni) for a, i in enumerate(dstates): plt.plot(S.loc[i,'value[keep]'] ,color=plt.cm.Blues(cc[a]), label='Keep ' + i) if pmin < pcrit[a] < pmax: demo.annotate(pcrit[a], vcrit[a], f'$p^*_{a+1}$', 'wo',(0, 0), fs=11, ms=18) print(f'Age {a+1:d} Profit {pcrit[a]:5.2f}') plt.plot(S.loc['a=1','value[replace]'], color=plt.cm.Oranges(0.5),label='Replace') plt.legend() # ### Plot Residual # In[14]: S['resid2'] = 100*S['resid'] / S['value'] fig2 = demo.figure('Bellman Equation Residual','Net Unit Profit','Percent Residual') demo.qplot('unit profit','resid2','i',S)
print(f'Critical Search Wage = {wcrit0:5.1f}') wcrit1, vcrit1 = critical(S.loc['employed']) print(f'Critical Quit Wage = {wcrit1:5.1f}') # ### Plot Action-Contingent Value Function # In[10]: vv = ['value[idle]', 'value[active]'] fig1 = plt.figure(figsize=[12, 4]) # UNEMPLOYED demo.subplot(1, 2, 1, 'Action-Contingent Value, Unemployed', 'Wage', 'Value') plt.plot(S.loc['unemployed', vv]) demo.annotate(wcrit0, vcrit0, f'$w^*_0 = {wcrit0:.1f}$', 'wo', (5, -5), fs=12) plt.legend(['Do Not Search', 'Search'], loc='upper left') # EMPLOYED demo.subplot(1, 2, 2, 'Action-Contingent Value, Employed', 'Wage', 'Value') plt.plot(S.loc['employed', vv]) demo.annotate(wcrit1, vcrit1, f'$w^*_0 = {wcrit1:.1f}$', 'wo', (5, -5), fs=12) plt.legend(['Quit', 'Work'], loc='upper left') # ### Plot Residual # In[11]: S['resid2'] = 100 * (S['resid'] / S['value']) fig2 = demo.figure('Bellman Equation Residual', 'Wage', 'Percent Residual') plt.plot(S.loc['unemployed', 'resid2'])
offs = [(4, -8), (-8, 5)] msgs = ['Profit Entry', 'Profit Exit'] for i,iname in enumerate(dstates): plt.axes(axs[i]) subdata = S.loc[iname,['value[close]', 'value[open]']] plt.plot(subdata) plt.title('Value of a currently ' + iname + ' firm') plt.xlabel('Potential Profit') if not i: plt.ylabel('Value of Firm') plt.legend(dactions) subdata['v.diff'] = subdata['value[open]'] - subdata['value[close]'] pcrit = np.interp(0, subdata['v.diff'], subdata.index) vcrit = np.interp(pcrit, subdata.index, subdata['value[close]']) demo.annotate(pcrit, vcrit, f'$p^*_{i:d} = {pcrit:.2f}$', 'wo', offs[i], fs=11, ms=12,) print(f'{msgs[i]:12s} = {pcrit:5.2f}') # ### Plot Residual # # We normalize the residuals as percentage of the value function. Notice the spikes at the "Profit entry" and "Profit exit" points. # In[10]: S['resid2'] = 100 * (S.resid / S.value) fig2 = demo.figure('Bellman Equation Residual','Potential Profit','Percent Residual') demo.qplot('profit','resid2','i',S)
# ### Plot Conditional Value Functions # In[10]: fig1 =demo.figure('Conditional Value Functions','Biomass','Value of Stand') plt.plot(ss,vhat0(cc,ss),label='Grow') plt.plot(ss,vhat1(cc,ss),label='Clear-Cut') plt.legend() vcrit = vhat(cc,scrit) ymin = plt.ylim()[0] plt.vlines(scrit, ymin,vcrit,'grey',linestyles='--') demo.annotate(scrit,ymin,'$s^*$',ms=10) demo.bullet(scrit,vcrit) print(f'Optimal Biomass Harvest Level = {scrit:.4f}') # ### Plot Value Function Residual # In[ ]: fig2 = demo.figure('Bellman Equation Residual', 'Biomass', 'Percent Residual') plt.plot(ss, 100*resid(cc,ss) / vhat(cc,ss)) plt.hlines(0,0,smax,linestyles='--') plt.plot(snodes,resid(cc),'ro')
ss = np.linspace(0, smax, 1000) # ### Plot Conditional Value Functions # In[10]: fig1 = demo.figure('Conditional Value Functions', 'Biomass', 'Value of Stand') plt.plot(ss, vhat0(cc, ss), label='Grow') plt.plot(ss, vhat1(cc, ss), label='Clear-Cut') plt.legend() vcrit = vhat(cc, scrit) ymin = plt.ylim()[0] plt.vlines(scrit, ymin, vcrit, 'grey', linestyles='--') demo.annotate(scrit, ymin, '$s^*$', ms=10) demo.bullet(scrit, vcrit) print(f'Optimal Biomass Harvest Level = {scrit:.4f}') # ### Plot Value Function Residual # In[ ]: fig2 = demo.figure('Bellman Equation Residual', 'Biomass', 'Percent Residual') plt.plot(ss, 100 * resid(cc, ss) / vhat(cc, ss)) plt.hlines(0, 0, smax, linestyles='--') plt.plot(snodes, resid(cc), 'ro') # ### Compute ergodic mean annual harvest # In[ ]:
plt.axes(axs[i]) subdata = S.loc[iname, ['value[close]', 'value[open]']] plt.plot(subdata) plt.title('Value of a currently ' + iname + ' firm') plt.xlabel('Potential Profit') if not i: plt.ylabel('Value of Firm') plt.legend(dactions) subdata['v.diff'] = subdata['value[open]'] - subdata['value[close]'] pcrit = np.interp(0, subdata['v.diff'], subdata.index) vcrit = np.interp(pcrit, subdata.index, subdata['value[close]']) demo.annotate( pcrit, vcrit, f'$p^*_{i:d} = {pcrit:.2f}$', 'wo', offs[i], fs=11, ms=12, ) print(f'{msgs[i]:12s} = {pcrit:5.2f}') # ### Plot Residual # # We normalize the residuals as percentage of the value function. Notice the spikes at the "Profit entry" and "Profit exit" points. # In[10]: S['resid2'] = 100 * (S.resid / S.value) fig2 = demo.figure('Bellman Equation Residual', 'Potential Profit', 'Percent Residual')
d2 = deriv_error(x-h, x+h) e2 = np.log10(eps**(1/3)) # ## Plot finite difference derivatives # In[6]: ylim = [-15, 5] xlim = [-15, 0] lcolor = [z['color'] for z in plt.rcParams['axes.prop_cycle']] demo.figure('Error in Numerical Derivatives','$\log_{10}(h)$','$\log_{10}$ Approximation Error',xlim,ylim) plt.plot(c,d1, label='One-Sided') plt.plot(c,d2, label='Two-Sided') plt.vlines([e1,e2],*ylim, lcolor,linestyle=':') plt.xticks(np.arange(-15,5,5)) plt.yticks(np.arange(-15,10,5)) demo.annotate(e1,2,'$\sqrt{\epsilon}$',color=lcolor[0],ms=0) demo.annotate(e2,2,'$\sqrt[3]{\epsilon}$',color=lcolor[1],ms=0) plt.legend(loc='lower left') # In[7]: demo.savefig([plt.gcf()])
fig1 = demo.figure('Action-Contingent Value Functions', 'Net Unit Profit', 'Value', figsize=[10, 5]) cc = np.linspace(0.3, 0.9, model.dims.ni) for a, i in enumerate(dstates): plt.plot(S.loc[i, 'value[keep]'], color=plt.cm.Blues(cc[a]), label='Keep ' + i) if pmin < pcrit[a] < pmax: demo.annotate(pcrit[a], vcrit[a], f'$p^*_{a+1}$', 'wo', (0, 0), fs=11, ms=18) print(f'Age {a+1:d} Profit {pcrit[a]:5.2f}') plt.plot(S.loc['a=1', 'value[replace]'], color=plt.cm.Oranges(0.5), label='Replace') plt.legend() # ### Plot Residual # In[14]: S['resid2'] = 100 * S['resid'] / S['value']
# ## Two-sided finite difference derivative # In[5]: d2 = deriv_error(x - h, x + h) e2 = np.log10(eps**(1 / 3)) # ## Plot finite difference derivatives # In[6]: ylim = [-15, 5] xlim = [-15, 0] lcolor = [z['color'] for z in plt.rcParams['axes.prop_cycle']] demo.figure('Error in Numerical Derivatives', '$\log_{10}(h)$', '$\log_{10}$ Approximation Error', xlim, ylim) plt.plot(c, d1, label='One-Sided') plt.plot(c, d2, label='Two-Sided') plt.vlines([e1, e2], *ylim, lcolor, linestyle=':') plt.xticks(np.arange(-15, 5, 5)) plt.yticks(np.arange(-15, 10, 5)) demo.annotate(e1, 2, '$\sqrt{\epsilon}$', color=lcolor[0], ms=0) demo.annotate(e2, 2, '$\sqrt[3]{\epsilon}$', color=lcolor[1], ms=0) plt.legend(loc='lower left') # In[7]: demo.savefig([plt.gcf()])
plt.plot(prices, resid(S.c)) # ### Plot demand and effective supply for m=1, 3, 5, 10, 15, 20 firms # In[10]: fig3 = demo.figure('Industry Supply and Demand Functions', 'Quantity', 'Price', [0, 12], figsize=[9,4]) lcolor = [z['color'] for z in plt.rcParams['axes.prop_cycle']] for i, m in enumerate([1, 3, 5, 10, 15, 20]): plt.plot(m*S(prices), prices) # supply demo.annotate(m*S(1.2)-0.25,1.4-i/12,f'm={m:d}',color=lcolor[i],ms=0,fs=12) plt.plot(D(prices), prices, linewidth=4, color='grey') # demand demo.annotate(10,0.5,'demand',color='grey', ms=0, fs=12) # ### Plot equilibrium price as a function of number of firms m # In[14]: pp = (b + a) / 2 dp = (b - a) / 2 m = np.arange(1, 26) for i in range(50): dp /= 2
n, a, z = 11, 0, 1 def f(x): return np.sqrt(1/(2*np.pi))*np.exp(-0.5*x**2) # In[3]: x, w = qnwsimp(n, a, z) prob = 0.5 + w.dot(f(x)) # In[4]: a, b, n = -4, 4, 500 x = np.linspace(a, b, n) xz = np.linspace(a, z, n) plt.figure(figsize=[8,4]) plt.fill_between(xz,f(xz), color='yellow') plt.hlines(0, a, b,'k','solid') plt.vlines(z, 0, f(z),'r',linewidth=2) plt.plot(x,f(x), linewidth=3) demo.annotate(-1, 0.08,r'$\Pr\left(\tilde Z\leq z\right)$',fs=18,ms=0) plt.yticks([]) plt.xticks([z],['$z$'],size=20) demo.savefig([plt.gcf()])
wcrit1, vcrit1 = critical(S.loc['employed']) print(f'Critical Quit Wage = {wcrit1:5.1f}') # ### Plot Action-Contingent Value Function # In[10]: vv = ['value[idle]','value[active]'] fig1 = plt.figure(figsize=[12,4]) # UNEMPLOYED demo.subplot(1,2,1,'Action-Contingent Value, Unemployed', 'Wage', 'Value') plt.plot(S.loc['unemployed',vv]) demo.annotate(wcrit0, vcrit0, f'$w^*_0 = {wcrit0:.1f}$', 'wo', (5, -5), fs=12) plt.legend(['Do Not Search', 'Search'], loc='upper left') # EMPLOYED demo.subplot(1,2,2,'Action-Contingent Value, Employed', 'Wage', 'Value') plt.plot(S.loc['employed',vv]) demo.annotate(wcrit1, vcrit1, f'$w^*_0 = {wcrit1:.1f}$', 'wo',(5, -5), fs=12) plt.legend(['Quit', 'Work'], loc='upper left') # ### Plot Residual # In[11]:
return 50 - cos(pi*x)*(2*pi*x - pi + 0.5)**2 # In[3]: xmin, xmax = 0, 1 ymin, ymax = 25, 65 a, b, n = 0.25, 0.75, 401 # In[4]: z = linspace(a,b,n) x = linspace(xmin, xmax, n) plt.figure(figsize=[8,4]) plt.fill_between(z,ymin,f(z), color='yellow') plt.hlines(ymin, xmin, xmax, 'k',linewidth=2) plt.vlines(a, ymin, f(a), 'r',linestyle='--',linewidth=2) plt.vlines(b, ymin, f(b), 'r',linestyle='--',linewidth=2) plt.plot(x,f(x), linewidth=3) plt.xlim([xmin, xmax]) plt.ylim([ymin-5, ymax]) plt.yticks([ymin], ['0'], size=20) plt.xticks([a, b],['$a$', '$b$'],size=20) demo.annotate(xmax-0.1, f(xmax)-9, r'$f(x)$',fs=18,ms=0) demo.annotate((a+b)/2, ymin+10 ,r'$A = \int_a^bf(x)dx$',fs=18,ms=0) demo.savefig([plt.gcf()])