%pylab inline
# add customizations:
from IPython.html.services.config import ConfigManager
from IPython.utils.path import locate_profile
cm = ConfigManager(profile_dir=locate_profile(get_ipython().profile))
#cm.update('livereveal', {
# 'theme': 'serif',
# 'transition': 'zoom',
# 'start_slideshow_at': 'selected',
# 'width': 1024,
# 'height': 768,
# 'data-background': '#dddddd',
# })
# clear customizations:
cm.update('livereveal', {
'theme': None,
'transition': None,
'start_slideshow_at': None,
'width': None,
'height': None,
'data-background': None,
'help': None,
})
Populating the interactive namespace from numpy and matplotlib
WARNING: pylab import has clobbered these variables: ['cm'] `%matplotlib` prevents importing * from pylab and numpy
{}
What we know:
from IPython.display import Image
display(Image('http://www.forestcarbonasia.org/wp-content/uploads/2010/09/Sciencefig41.jpg'))
What we don't know:
display(Image('http://www.grida.no/images/series/vg-climate/large/33.jpg'))
display(Image('http://i.kinja-img.com/gawker-media/image/upload/s--UQ4oZZnu--/c_fit,fl_progressive,q_80,w_636/fvdlozrtgd52iidtjimy.png'))
display(Image('http://www.easterbrook.ca/steve/wp-content/IPCC-AR5-Fig-12.5.png'))
Most probabilistic estimates put sea level rise at approximately 1 meter for our region over the next century. There is evidence that in the past very large sea level changes have occured in relatively short periods of time:
To see what may happen scientists of CEREGE laboratory and the Universities of Tokyo and Oxford have studied the largest known ocean level rise: Melt-Water Pulse 1A. They found that during a relatively warm period called the Bølling Oscillation roughly 14,650 years ago sea levels rose an average of 14 meters in just 350 years.
To consider how cost benefit analysis works under uncertainty, consider the following simplicifications of the choice problem facing society:
We need to characterize the payoffs of the various states of the world that might happen in the future:
Policy Outcome | Impacts | GDP | Costs (% GDP) | Damages (%GDP) |
---|---|---|---|---|
No Abatement | None | $B$ | 0 | 0 |
No Abatement | High | $B$ | 0 | $D_H$ |
No Abatement | Low | $B$ | 0 | $D_L$ |
Abatement | None | $B$ | C | 0 |
Abatement | High | $B$ | C | $D_H^A$ |
Abatement | Low | $B$ | C | $D_L^A$ |
# we'll use annotations and matplotlib to depict the game tree:
plt.figure(figsize=(6, 6), dpi=100)
plt.subplot(111)
lw = 1
plt.axis('off')
plt.title("Climate Change Payoff Tree",fontsize=15)
plt.text(10, 500, 'Policy', fontsize=14)
plt.text(160,690,'No Abatement',rotation=31)
plt.text(160,410,'Abatement',rotation=-31)
# climate impact node
plt.text(410, 660, 'Climate \n Impact', fontsize=14)
plt.text(410, 280, 'Climate \n Impact', fontsize=14)
# outcome node
plt.text(710, 845, '$\pi_N B$', fontsize=14)
plt.text(710, 690, '$\pi_H (B - D_H)$', fontsize=14)
plt.text(710, 555, '$\pi_L (B - D_L)$', fontsize=14)
plt.text(710, 445, '$\pi_N (B - C$)', fontsize=14)
plt.text(710, 282, '$\pi_H (B - D^A_H - C$)', fontsize=14)
plt.text(710, 145, '$\pi_L (B - D^A_L - C$)', fontsize=14)
# These link policy to climate impact
plt.arrow(140, 540, 250, 150, head_width=0.5, head_length=0.5, fc='k', ec='k')
plt.arrow(140, 480, 250, -150, head_width=0.5, head_length=0.5, fc='k', ec='k')
# these link climate impact to outcome
# this is no abatement
plt.arrow(600, 735, 100, 100, head_width=0.5, head_length=0.5, fc='k', ec='k')
plt.arrow(600, 700, 100, 0, head_width=0.5, head_length=0.5, fc='k', ec='k')
plt.arrow(600, 650, 100, -75, head_width=0.5, head_length=0.5, fc='k', ec='k')
# this is no abatement
plt.arrow(600, 335, 100, 100, head_width=0.5, head_length=0.5, fc='k', ec='k')
plt.arrow(600, 300, 100, 0, head_width=0.5, head_length=0.5, fc='k', ec='k')
plt.arrow(600, 250, 100, -75, head_width=0.5, head_length=0.5, fc='k', ec='k')
plt.xlim((0,1000))
plt.ylim((0,1000))
plt.tight_layout
plt.savefig('climate_payoff_tree.png', dpi=100)
display(Image('climate_payoff_tree.png'))
For each node on the payoff tree, calculate the Net Present Value of GDP minus costs of abatement and damages due to climate change through time. For the abatement, high impact node the net present value of all future costs and benefits would be:
$$
B -D^A_H - C =\sum_{t=2015}^{2515}\frac{(B_{t} - D^A_{Ht} - C_t)}{(1+r)^{t-2015}}
$$
For the No Abatement portion of the tree calculate the expected payoffs:
$$
E(P_{NA}) = \pi_N B + \pi_H (B - D_H) + \pi_L (B - D_L)
$$
Do the same for the abatement portion of the tree:
$$
\begin{align}
E(P_{A}) = &\pi_N (B - C) + \pi_H (B - D^A_H - C) + \\
&\pi_L (B-D^A_L - C)
\end{align}
$$
We should undertake abatement if $$ E(P_A) > E(P_{NA}) $$
Since all variation across scenarios occurs via the abatement and damage costs, we can simplify this to
$$
\pi_H D^A_H + \pi_L D^A_L + C < \pi_H D_H + \pi_L D_L
$$
or if
$$
C < \pi_H (D_H - D^A_H) + \pi_L (D_L - D^A_L)
$$
which says that if the expected costs of doing nothing exceed the abatement costs we should abate. Notice in our model, abatement doesn't affect the probability of impact types, which is probably unrealistic.
t=arange(500)
GDP_0 = 1
r = .02
gdp_growth = 1.02
cost_abatement = .03
# the low scenario will take 3% of gdp per year beginning in year 20
# the high scenario will take 3% for year 10-50, 6% for year 51-100, 10% for year 100-150, and 15% thereafter
# this procedure simulates data for 500 year time horizon
def simulate(GDP_current,GDP_growth,COST_abatement,T):
GDP = zeros(T.shape[0])
damage_low = zeros(T.shape[0])
damage_high = zeros(T.shape[0])
cost_abatement = zeros(T.shape[0])
damage_rate_low = 0
damage_rate_high = 0
for t in T:
# defines current year
GDP[t] = GDP_current * GDP_growth
GDP_current=GDP[t]
cost_abatement[t] = COST_abatement*GDP_current
#print COST_abatement,GDP_current,cost_abatement
# damage for low impact event
damage_low[t] = (t>10)*.03*GDP_current + (1-(t>10))*0
# damage for high impact event
damage_high[t] = 0
if t>10 and t<50:
damage_high[t] = .03 * GDP_current
elif t>=50 and t<100:
damage_high[t] = .06 * GDP_current
elif t>=100 and t<150:
damage_high[t] = .1 * GDP_current
elif t>=150:
damage_high[t] = .15 * GDP_current
return [GDP,damage_low,damage_high,cost_abatement]
def npv(val,t,r):
npv_val = val/(1+r)**t
return npv_val
GDP,damage_low,damage_high,C = simulate(GDP_0,gdp_growth,cost_abatement,t)
damage_a_low = .5 * damage_low
damage_a_high = .5 * damage_high
plt.figure(figsize=(7, 4.5), dpi=300)
plt.subplot(111)
lw = 1
plt.xlim(0,200)
plt.ylim(0,2)
plt.title("Costs and Damages Throught Time",fontsize=20)
plt.plot(t,damage_high,color='y', label='Damage High')
plt.plot(t,damage_a_high,color='b',label='Damage High w/Abatement')
plt.plot(t,damage_low,color='r', label='Damage Low')
plt.plot(t,damage_a_low,color='k', label='Damage Low w/Abatement ')
plt.plot(t,C,color='c', label = 'Costs of Abatement')
plt.legend(loc='upper left')
plt.savefig('costs_damages.png', dpi=120)
npv_gdp = npv(GDP,t,r)
npv_damage_low = npv(damage_low,t,r)
npv_damage_high = npv(damage_high,t,r)
npv_costs = npv(C,t,r)
npv_damage_a_high = npv(damage_a_high,t,r)
npv_damage_a_low = npv(damage_a_low,t,r)
plt.figure(figsize=(7, 4.5), dpi=300)
plt.subplot(111)
lw = 1
plt.xlim(0,200)
plt.ylim(0,.18)
plt.title("Costs and Damages Throught Time (Discounted)",fontsize=17)
plt.plot(t,npv_damage_high,color='y', label='Damage High')
plt.plot(t,npv_damage_a_high,color='b',label='Damage High w/Abatement')
plt.plot(t,npv_damage_low,color='r', label='Damage Low')
plt.plot(t,npv_damage_a_low,color='k', label='Damage Low w/Abatement ')
plt.plot(t,npv_costs,color='c', label = 'Costs of Abatement')
plt.legend(loc='upper left')
plt.savefig('costs_damages_discounted.png', dpi=120)
# ok, given that we have the damage and costs calculated, we can plot the solution set:
# plot C and prob_high (as prob_high varies, we will hold prob_none fixed)
# solve for prob_high that leads to CBA equality for any level of C
from sympy.solvers import solve
from sympy import Symbol
prob_none =Symbol('prob_none')
prob_low = .5
C = arange(0.02,.05,.001)
count=0
prob_high_opt=zeros(C.shape[0])
Costs = zeros(C.shape[0])
for c in C:
cost_abatement = c
# simulate all vectors: on C will change
GDP,damage_low,damage_high,C = simulate(GDP_0,gdp_growth,cost_abatement,t)
total_C = sum(npv(C,t,r))
total_damage_low = sum(npv(damage_low,t,r))
total_damage_a_low = sum(npv(damage_a_low,t,r))
total_damage_high = sum(npv(damage_high,t,r))
total_damage_a_high = sum(npv(damage_a_high,t,r))
prob_none_solve = solve(total_C - (prob_low*(total_damage_low - total_damage_a_low) +
(prob_low-prob_none)*(total_damage_high - total_damage_a_high)),prob_none)
prob_high_opt[count] = prob_low - prob_none_solve[0]
Costs[count] = c
count+=1
from matplotlib.ticker import FuncFormatter
def myfunc(x, pos=0):
return '%1.1f%%'%(100*x)
# plot results:
x = Costs[prob_high_opt<.5]
y = prob_high_opt[prob_high_opt<.5]
ax = subplot(111)
ax.plot(x, y)
ax.xaxis.set_major_formatter(FuncFormatter(myfunc))
ax.yaxis.set_major_formatter(FuncFormatter(myfunc))
ax.plot(x,y,c='k')
ax.set_xlabel('Costs (% GDP)',fontsize=12)
ax.set_ylabel('Chance of High Impact',fontsize=12)
ax.fill_between(x, 0, y, alpha = .4,color='r')
ax.fill_between(x, y+1, y, alpha = .2,color='g')
ax.set_ylim(.15,.5)
ax.set_xlim(.02,.038)
ax.set_title("Abate Critical Regions",fontsize=20)
ax.text(.023,.40,"Abate")
ax.text(.031,.2,"Don't Abate")
plt.savefig('abate_or_not.png', dpi=150)
display(Image('costs_damages.png'))
display(Image('costs_damages_discounted.png'))
display(Image('abate_or_not.png'))
The Stern Review conducted an in-depth Cost Benefit Analysis for climate change mitigation and adaptation for the British Government. They conclude:
From all of these perspectives, the evidence gathered by the Review leads to a simple conclusion: the benefits of strong, early action considerably outweigh the costs.
Policy Approach: The Kyoto Protocol
display(Image('timeline.png'))
display(Image('annex1.png'))
display(Image('emissions_sources.png'))
display(Image('emissions_sources2.png'))
display(Image('historical_account.png'))
display(Image('per_cap_emissions.png'))
Most of the reductions in carbon emissions over the next twenty years will occur because of a shift away from high intensity (high carbon content) fossil fuels.
Idea: Charge per unit tax based on carbon content of fossil fuel
Coal (ton) | Gas (Gallon) | Natural Gas (1000 cf) | |
---|---|---|---|
Tons of Carbon per Unit | .605 | .0098 | .06 |
Average price (2015) | \$55.00 | \$2.50 | \$12.00 |
Carbon Tax: | |||
Absolute Tax: | \$/ton | \$/Gallon | \$/1000 cf |
\$20/ton Carbon | \$12.10 | \$0.198 | \$1.20 |
Tax as % of price: | 22.0% | 7.84% | 10.0% |
Currently, in the European Permit Trading System, the carbon price is around \$5/ton.
# generate data for slides illustrating tax:
q_oil = lambda p_oil,p_ngas: 50 - .5 * p_oil + .25 * p_ngas
q_ngas = lambda p_oil,p_ngas: 50 - .5* p_ngas + .25 * p_oil
p_oil_equil = 40
p_ngas_equil = 40
#solve for q_oil_equilibrium at prices above
q_oil_equilibrium = q_oil(p_oil_equil,p_ngas_equil)
q_ngas_equilibrium = q_ngas(p_oil_equil,p_ngas_equil)
# generate data to plot demand curve
pngas = arange(0,120,.1)
poil = arange(0,120,.1)
graph_q_oil_0 = q_oil(poil,p_ngas_equil)
graph_q_ngas_0 = q_ngas(p_oil_equil,pngas)
plt.figure(figsize=(10,4),dpi=100)
plt.tight_layout
plt.subplot(1, 2, 1)
plt.plot(graph_q_oil_0,poil,c='r')
plt.plot((0,q_oil_equilibrium),(p_oil_equil,p_oil_equil),'k--')
plt.plot((q_oil_equilibrium,q_oil_equilibrium),(0,p_oil_equil),'k--')
plt.xlim(0,55)
plt.title('More Carbon Intensive')
plt.ylabel('Price')
plt.xlabel('Quantity of Coal')
plt.subplot(1, 2, 2)
plt.plot(graph_q_ngas_0,pngas,c='g')
plt.plot((0,q_ngas_equilibrium),(p_ngas_equil,p_ngas_equil),'k--')
plt.plot((q_ngas_equilibrium,q_ngas_equilibrium),(0,p_ngas_equil),'k--')
plt.xlim(0,55)
plt.title('Less Carbon Intensive')
plt.xlabel('Quantity of Natural Gas')
plt.savefig('tax1.png', dpi=150)
# plot direct effect of tax (ignoring shifts due to price changes in related markets):
p_oil_equil_t = p_ngas_equil*1.25
p_ngas_equil_t = p_ngas_equil*1.1
#solve for q_oil_equilibrium at own price above, holding substitute
#prince at pretax levels: partial equilibrium
q_oil_equilibrium_tp = q_oil(p_oil_equil_t,p_ngas_equil)
q_ngas_equilibrium_tp = q_ngas(p_oil_equil,p_ngas_equil_t)
plt.figure(figsize=(12,5),dpi=100)
plt.tight_layout
plt.subplot(1, 2, 1)
plt.plot(graph_q_oil_0,poil,c='r')
plt.plot((0,q_oil_equilibrium_tp),(p_oil_equil_t,p_oil_equil_t),'k--')
plt.plot((q_oil_equilibrium_tp,q_oil_equilibrium_tp),(0,p_oil_equil_t),'k--')
plt.plot((0,q_oil_equilibrium),(p_oil_equil,p_oil_equil),'k--')
plt.plot((q_oil_equilibrium,q_oil_equilibrium),(0,p_oil_equil),'k--')
plt.arrow(q_oil_equilibrium-.2, 7, -.8*(q_oil_equilibrium - q_oil_equilibrium_tp),0, head_width=3, head_length=.7, fc='k', ec='k')
plt.arrow(7,p_oil_equil+.2, 0,.7*(p_oil_equil_t-p_oil_equil), head_width=1.3, head_length=.8, fc='k', ec='k')
plt.annotate('new price = $40 x (1.25)', xy=(0,50.5), xytext=(10, 70),arrowprops=dict(facecolor='black', shrink=0.05,
width=2,headwidth=9))
plt.xlim(0,55)
plt.title('More Carbon Intensive (t=25%)')
plt.ylabel('Price')
plt.xlabel('Quantity of Coal')
plt.subplot(1, 2, 2)
plt.plot(graph_q_ngas_0,pngas,c='g')
plt.plot((0,q_ngas_equilibrium_tp),(p_ngas_equil_t,p_ngas_equil_t),'k--')
plt.plot((q_ngas_equilibrium_tp,q_ngas_equilibrium_tp),(0,p_ngas_equil_t),'k--')
plt.plot((0,q_ngas_equilibrium),(p_ngas_equil,p_ngas_equil),'k--')
plt.plot((q_ngas_equilibrium,q_ngas_equilibrium),(0,p_ngas_equil),'k--')
plt.arrow(q_ngas_equilibrium-.2, 7, -.5*(q_ngas_equilibrium - q_ngas_equilibrium_tp),0, head_width=5, head_length=.7, fc='k', ec='k')
plt.arrow(7,p_ngas_equil+.2, 0,.8*(p_ngas_equil_t-p_ngas_equil), head_width=1.3, head_length=.8, fc='k', ec='k')
plt.annotate('new price = $40 x (1.1)', xy=(0,44.5), xytext=(10, 70),arrowprops=dict(facecolor='black', shrink=0.05,
width=2,headwidth=9))
plt.xlim(0,55)
plt.title('Less Carbon Intensive (t=10%)')
plt.xlabel('Quantity of Natural Gas')
plt.savefig('tax2.png', dpi=150)
# now model impact of substitute prices:
#solve for q_oil_equilibrium at own price above, holding substitute
q_oil_equilibrium_t = q_oil(p_oil_equil_t,p_ngas_equil_t)
q_ngas_equilibrium_t = q_ngas(p_oil_equil_t,p_ngas_equil_t)
#Need to calculate shifted demand curve (since subs price increased):
# generate data to plot demand curve
graph_q_oil_1 = q_oil(poil,p_ngas_equil_t)
graph_q_ngas_1 = q_ngas(p_oil_equil_t,pngas)
plt.figure(figsize=(12,5),dpi=100)
plt.tight_layout
plt.subplot(1, 2, 1)
plt.plot(graph_q_oil_0,poil,c='r')
plt.plot(graph_q_oil_1,poil,'r--',label='Demand After Substitutes')
plt.plot((0,q_oil_equilibrium_t),(p_oil_equil_t,p_oil_equil_t),'r--')
plt.plot((q_oil_equilibrium_tp,q_oil_equilibrium_tp),(0,p_oil_equil_t),'k--')
plt.plot((0,q_oil_equilibrium),(p_oil_equil,p_oil_equil),'k--')
plt.plot((q_oil_equilibrium,q_oil_equilibrium),(0,p_oil_equil),'k--')
plt.arrow(q_oil_equilibrium-.2, 7, -.8*(q_oil_equilibrium - q_oil_equilibrium_tp),0, head_width=3, head_length=.7, fc='k', ec='k')
plt.arrow(7,p_oil_equil+.2, 0,.7*(p_oil_equil_t-p_oil_equil), head_width=1.3, head_length=.8, fc='k', ec='k')
plt.annotate('new price = $40 x (1.25)', xy=(0,50.5), xytext=(10, 70),arrowprops=dict(facecolor='black', shrink=0.05,
width=2,headwidth=9))
plt.plot((q_oil_equilibrium_t,q_oil_equilibrium_t),(0,p_oil_equil_t),'r--')
plt.legend()
plt.xlim(0,55)
plt.title('More Carbon Intensive (t=25%)')
plt.ylabel('Price')
plt.xlabel('Quantity of Coal')
plt.subplot(1, 2, 2)
plt.plot(graph_q_ngas_0,pngas,c='g')
plt.plot(graph_q_ngas_1,pngas,'g--',label='Demand After Substitutes')
plt.plot((0,q_ngas_equilibrium_t),(p_ngas_equil_t,p_ngas_equil_t),'g--')
plt.plot((q_ngas_equilibrium_tp,q_ngas_equilibrium_tp),(0,p_ngas_equil_t),'k--')
plt.plot((0,q_ngas_equilibrium),(p_ngas_equil,p_ngas_equil),'k--')
plt.plot((q_ngas_equilibrium,q_ngas_equilibrium),(0,p_ngas_equil),'k--')
plt.arrow(q_ngas_equilibrium-.2, 7, -.5*(q_ngas_equilibrium - q_ngas_equilibrium_tp),0, head_width=5, head_length=.7, fc='k', ec='k')
plt.arrow(7,p_ngas_equil+.2, 0,.8*(p_ngas_equil_t-p_ngas_equil), head_width=1.3, head_length=.8, fc='k', ec='k')
plt.annotate('new price = $40 x (1.1)', xy=(0,44.5), xytext=(10, 70),arrowprops=dict(facecolor='black', shrink=0.05,
width=2,headwidth=9))
plt.plot((q_ngas_equilibrium_t,q_ngas_equilibrium_t),(0,p_ngas_equil_t),'g--')
plt.legend()
plt.xlim(0,55)
plt.title('Less Carbon Intensive (t=10%)')
plt.xlabel('Quantity of Natural Gas')
plt.savefig('tax3.png', dpi=150)
print q_ngas_equilibrium,q_ngas_equilibrium_tp,q_ngas_equilibrium_t
print q_oil_equilibrium, q_oil_equilibrium_tp,q_oil_equilibrium_t
40.0 38.0 40.5 40.0 35.0 36.0
display(Image('tax1.png'))
display(Image('tax2.png'))
display(Image('tax3.png'))
Market | Original Demand | Own Price Demand | Demand After Substitutes |
---|---|---|---|
Coal | 40 | 35 | 36 |
Gas | 40 | 38 | 40.5 |
display(Image('cdm.png'))
from IPython.display import YouTubeVideo
# European ETS Main Video
YouTubeVideo('yfNgsKrPKsg')
display(Image('http://cdn.static-economist.com/sites/default/files/imagecache/full-width/images/2013/02/blogs/schumpeter/20130216_woc070_0_0.png'))
display(Image('design1.png'))
display(Image('design2.png'))
display(Image('design3.png'))
display(Image('nyt.png'))
display(Image('forbes.png'))