my-markdown-library 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/F24LS_md/ Lecture 4 - Public.md +347 -0
  3. data/F24LS_md/Lecture 1 - Introduction and Overview.md +327 -0
  4. data/F24LS_md/Lecture 10 - Development_.md +631 -0
  5. data/F24LS_md/Lecture 11 - Econometrics.md +345 -0
  6. data/F24LS_md/Lecture 12 - Finance.md +692 -0
  7. data/F24LS_md/Lecture 13 - Environmental Economics.md +299 -0
  8. data/F24LS_md/Lecture 15 - Conclusion.md +272 -0
  9. data/F24LS_md/Lecture 2 - Demand.md +349 -0
  10. data/F24LS_md/Lecture 3 - Supply.md +329 -0
  11. data/F24LS_md/Lecture 5 - Production C-D.md +291 -0
  12. data/F24LS_md/Lecture 6 - Utility and Latex.md +440 -0
  13. data/F24LS_md/Lecture 7 - Inequality.md +607 -0
  14. data/F24LS_md/Lecture 8 - Macroeconomics.md +704 -0
  15. data/F24LS_md/Lecture 8 - Macro.md +700 -0
  16. data/F24LS_md/Lecture 9 - Game Theory_.md +436 -0
  17. data/F24LS_md/summary.yaml +105 -0
  18. data/F24Lec_MD/LecNB_summary.yaml +206 -0
  19. data/F24Lec_MD/lec01/lec01.md +267 -0
  20. data/F24Lec_MD/lec02/Avocados_demand.md +425 -0
  21. data/F24Lec_MD/lec02/Demand_Steps_24.md +126 -0
  22. data/F24Lec_MD/lec02/PriceElasticity.md +83 -0
  23. data/F24Lec_MD/lec02/ScannerData_Beer.md +171 -0
  24. data/F24Lec_MD/lec02/demand-curve-Fa24.md +213 -0
  25. data/F24Lec_MD/lec03/3.0-CubicCostCurve.md +239 -0
  26. data/F24Lec_MD/lec03/3.1-Supply.md +274 -0
  27. data/F24Lec_MD/lec03/3.2-sympy.md +332 -0
  28. data/F24Lec_MD/lec03/3.3a-california-energy.md +120 -0
  29. data/F24Lec_MD/lec03/3.3b-a-really-hot-tuesday.md +121 -0
  30. data/F24Lec_MD/lec04/lec04-CSfromSurvey-closed.md +335 -0
  31. data/F24Lec_MD/lec04/lec04-CSfromSurvey.md +331 -0
  32. data/F24Lec_MD/lec04/lec04-Supply-Demand-closed.md +519 -0
  33. data/F24Lec_MD/lec04/lec04-Supply-Demand.md +514 -0
  34. data/F24Lec_MD/lec04/lec04-four-plot-24.md +34 -0
  35. data/F24Lec_MD/lec04/lec04-four-plot.md +34 -0
  36. data/F24Lec_MD/lec05/Lec5-Cobb-Douglas.md +131 -0
  37. data/F24Lec_MD/lec05/Lec5-CobbD-AER1928.md +283 -0
  38. data/F24Lec_MD/lec06/6.1-Sympy-Differentiation.md +253 -0
  39. data/F24Lec_MD/lec06/6.2-3D-utility.md +287 -0
  40. data/F24Lec_MD/lec06/6.3-QuantEcon-Optimization.md +399 -0
  41. data/F24Lec_MD/lec06/6.4-latex.md +138 -0
  42. data/F24Lec_MD/lec06/6.5-Edgeworth.md +269 -0
  43. data/F24Lec_MD/lec07/7.1-inequality.md +283 -0
  44. data/F24Lec_MD/lec07/7.2-historical-inequality.md +237 -0
  45. data/F24Lec_MD/lec08/macro-fred-api.md +313 -0
  46. data/F24Lec_MD/lec09/lecNB-prisoners-dilemma.md +88 -0
  47. data/F24Lec_MD/lec10/Lec10.2-waterguard.md +401 -0
  48. data/F24Lec_MD/lec10/lec10.1-mapping.md +199 -0
  49. data/F24Lec_MD/lec11/11.1-slr.md +305 -0
  50. data/F24Lec_MD/lec11/11.2-mlr.md +171 -0
  51. data/F24Lec_MD/lec12/Lec12-4-PersonalFinance.md +590 -0
  52. data/F24Lec_MD/lec12/lec12-1_Interest_Payments.md +267 -0
  53. data/F24Lec_MD/lec12/lec12-2-stocks-options.md +235 -0
  54. data/F24Lec_MD/lec13/Co2_ClimateChange.md +139 -0
  55. data/F24Lec_MD/lec13/ConstructingMAC.md +213 -0
  56. data/F24Lec_MD/lec13/EmissionsTracker.md +170 -0
  57. data/F24Lec_MD/lec13/KuznetsHypothesis.md +219 -0
  58. data/F24Lec_MD/lec13/RoslingPlots.md +217 -0
  59. data/F24Lec_MD/lec15/vibecession.md +485 -0
  60. data/F24Textbook_MD/00-intro/index.md +292 -0
  61. data/F24Textbook_MD/01-demand/01-demand.md +152 -0
  62. data/F24Textbook_MD/01-demand/02-example.md +131 -0
  63. data/F24Textbook_MD/01-demand/03-log-log.md +284 -0
  64. data/F24Textbook_MD/01-demand/04-elasticity.md +248 -0
  65. data/F24Textbook_MD/01-demand/index.md +15 -0
  66. data/F24Textbook_MD/02-supply/01-supply.md +203 -0
  67. data/F24Textbook_MD/02-supply/02-eep147-example.md +86 -0
  68. data/F24Textbook_MD/02-supply/03-sympy.md +138 -0
  69. data/F24Textbook_MD/02-supply/04-market-equilibria.md +204 -0
  70. data/F24Textbook_MD/02-supply/index.md +16 -0
  71. data/F24Textbook_MD/03-public/govt-intervention.md +73 -0
  72. data/F24Textbook_MD/03-public/index.md +10 -0
  73. data/F24Textbook_MD/03-public/surplus.md +351 -0
  74. data/F24Textbook_MD/03-public/taxes-subsidies.md +282 -0
  75. data/F24Textbook_MD/04-production/index.md +15 -0
  76. data/F24Textbook_MD/04-production/production.md +178 -0
  77. data/F24Textbook_MD/04-production/shifts.md +296 -0
  78. data/F24Textbook_MD/05-utility/budget-constraints.md +166 -0
  79. data/F24Textbook_MD/05-utility/index.md +15 -0
  80. data/F24Textbook_MD/05-utility/utility.md +136 -0
  81. data/F24Textbook_MD/06-inequality/historical-inequality.md +253 -0
  82. data/F24Textbook_MD/06-inequality/index.md +15 -0
  83. data/F24Textbook_MD/06-inequality/inequality.md +226 -0
  84. data/F24Textbook_MD/07-game-theory/bertrand.md +257 -0
  85. data/F24Textbook_MD/07-game-theory/cournot.md +333 -0
  86. data/F24Textbook_MD/07-game-theory/equilibria-oligopolies.md +96 -0
  87. data/F24Textbook_MD/07-game-theory/expected-utility.md +61 -0
  88. data/F24Textbook_MD/07-game-theory/index.md +19 -0
  89. data/F24Textbook_MD/07-game-theory/python-classes.md +340 -0
  90. data/F24Textbook_MD/08-development/index.md +35 -0
  91. data/F24Textbook_MD/09-macro/CentralBanks.md +101 -0
  92. data/F24Textbook_MD/09-macro/Indicators.md +77 -0
  93. data/F24Textbook_MD/09-macro/fiscal_policy.md +36 -0
  94. data/F24Textbook_MD/09-macro/index.md +14 -0
  95. data/F24Textbook_MD/09-macro/is_curve.md +76 -0
  96. data/F24Textbook_MD/09-macro/phillips_curve.md +70 -0
  97. data/F24Textbook_MD/10-finance/index.md +10 -0
  98. data/F24Textbook_MD/10-finance/options.md +178 -0
  99. data/F24Textbook_MD/10-finance/value-interest.md +60 -0
  100. data/F24Textbook_MD/11-econometrics/index.md +16 -0
  101. data/F24Textbook_MD/11-econometrics/multivariable.md +218 -0
  102. data/F24Textbook_MD/11-econometrics/reading-econ-papers.md +25 -0
  103. data/F24Textbook_MD/11-econometrics/single-variable.md +483 -0
  104. data/F24Textbook_MD/11-econometrics/statsmodels.md +58 -0
  105. data/F24Textbook_MD/12-environmental/KuznetsHypothesis-Copy1.md +187 -0
  106. data/F24Textbook_MD/12-environmental/KuznetsHypothesis.md +187 -0
  107. data/F24Textbook_MD/12-environmental/MAC.md +254 -0
  108. data/F24Textbook_MD/12-environmental/index.md +36 -0
  109. data/F24Textbook_MD/LICENSE.md +11 -0
  110. data/F24Textbook_MD/intro.md +26 -0
  111. data/F24Textbook_MD/references.md +25 -0
  112. data/F24Textbook_MD/summary.yaml +414 -0
  113. metadata +155 -0
@@ -0,0 +1,287 @@
1
+ ---
2
+ title: "6.2-3D-utility"
3
+ type: lecture-notebook
4
+ week: 6
5
+ source_path: "/Users/ericvandusen/Documents/Data88E-ForTraining/F24Lec_NBs/lec06/6.2-3D-utility.ipynb"
6
+ ---
7
+
8
+ <table style="width: 100%;" id="nb-header">
9
+ <tr style="background-color: transparent;"><td>
10
+ <img src="https://data-88e.github.io/assets/images/blue_text.png" width="250px" style="margin-left: 0;" />
11
+ </td><td>
12
+ <p style="text-align: right; font-size: 10pt;"><strong>Economic Models</strong>, <br>
13
+ Dr. Eric Van Dusen <br>
14
+ Akhil Venkatesh <br>
15
+ </table>
16
+
17
+ ```python
18
+ import pandas as pd
19
+ import numpy as np
20
+ #import chart_studio.plotly as py
21
+ import plotly.graph_objs as go
22
+ from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
23
+ from ipywidgets import interact, interactive, fixed, interact_manual
24
+ import ipywidgets as widgets
25
+ from IPython.display import display, HTML
26
+ import warnings
27
+ warnings.filterwarnings('ignore')
28
+ import plotly.io as pio
29
+ pio.renderers.default = 'notebook'
30
+ ```
31
+
32
+ # Utility Functions and Indifference Curves
33
+
34
+ ## What is Utility?
35
+
36
+ When we consume a good, we assume that the good will have some impact on our total utility. Utility is a fundamental measure that helps economists model how consumers make decisions. An assumed rule in economics is that consumers will always act rationally, which translates to the assumption that consumers will always attempt to maximize their own utility.
37
+
38
+ It is important to note that utility doesn't have specified units and even the face value of utility doesn't have any meaning. *What does an apple providing 5 utility units even mean?* What is valuable, however, is that utility can be compared; if an apple provides 5 utility units and an orange provides 3 utility units, then we prefer apples to oranges.
39
+
40
+ As a very simple example, say Anne has 6 dollars and she can choose to buy any combination of goods A and B. If good A costs 2 dollars and provides 5 utility units per unit of A consumed, while good B costs 3 dollars and provides 6 utility units per unit of B consumed, then Anne will buy 3 units of good A, since that maximizes her utility.
41
+
42
+ In economics, however, our models are a little more complex than that. Typically, utility is the product of the consumption of many goods; typically having a lot of one good but not another does not provide much utility. In addition, consumption of one good faces diminishing marginal returns, i.e. holding all things equal, the consumption of one additional unit of a good will provide less utility than the utility received from the previous unit. Intuitively, imagine Bob is very hungry and decides to eat slices of pizza. The first slice of pizza will bring Bob the most utility, but the 8th slice will be much less satisfying to eat.
43
+
44
+ ## Utility Functions
45
+ A consumer's utility is determined by the amount of consumption from all the goods they consume. Typically, utility functions are multivariate: they take in multiple inputs (which represent the different amounts of consumption for each good, which we call a consumption bundle), and output one value, the utility. Today, we'll only look at the case where consumers can only choose between 2 goods $x_1$ and $x_2$. Hence, a utility function can be represented by: $u(x_1,x_2)$.
46
+
47
+ With that in mind, let's start graphing some utility functions!
48
+
49
+ ### Cobb-Douglas Utility Function
50
+
51
+ Consider the following utility function across $x_1$ and $x_2$:
52
+
53
+ $$u(x_1, x_2)=x_1^{\alpha}x_2^{1-\alpha}\quad\text{where } 0<\alpha<1$$
54
+
55
+ This is known as the **Cobb-Douglas utility function**. To visualize this function, we'll need a 3D plot.
56
+
57
+ ```python
58
+ alpha = 0.5
59
+ def cobb_douglas(x1, x2):
60
+ return (x1 ** alpha) * (x2 ** (1-alpha))
61
+ x1 = np.linspace(0,10,10)
62
+ x2 = np.linspace(0,10,10)
63
+ X1,X2 = np.meshgrid(x1,x2)
64
+ z = cobb_douglas(X1,X2)
65
+ data = [go.Surface(z=z, contours=go.surface.Contours(z=go.surface.contours.Z(show=True,usecolormap=True,highlightcolor="#42f462",project=dict(z=True))))]
66
+ layout = go.Layout(title='Cobb-Douglas Utility Function (alpha = 0.5)',autosize=False,width=500,height=500,margin=dict(l=65,r=50,b=65,t=90),
67
+ scene = dict(xaxis = dict(title='X1'),yaxis = dict(title=r'X2'),zaxis = dict(title='Utility'),))
68
+ fig = go.Figure(data=data, layout=layout)
69
+
70
+ plot(fig, filename="fig1.html", auto_open=False)
71
+ display(HTML("fig1.html"))
72
+ ```
73
+
74
+ ## Examining the Utility Function
75
+
76
+ There are 2 rules that utility functions generally follow:
77
+
78
+ - Non-negative marginal utility: the consumption of a good will not decrease the utility. Economists generally assume that 'more is better.' If the consumption of a good decreased utility, then we would consume less of a good.
79
+ - Diminishing marginal returns: all else equal, as consumption increases the marginal utility derived from each additional unit declines.
80
+
81
+ ### Non-negative Marginal Utility
82
+ Say we are currently consuming 2 units of $x_1$ and $x_2$ each with $\alpha = \frac{1}{2}$, providing $u(2,2)=2^{0.5}2^{0.5}=2$ utility units. One additional unit of $x_1$ will provide me a higher point of utility: we can verify this result both graphically and numerically: $u(3,2)=3^{0.5}2^{0.5}\approx2.45$. Indeed, consuming one more unit of a good should increase our utility!
83
+
84
+ ### Marginal Utility and the Law of Diminishing Returns
85
+ Now let's check for the second result: diminishing marginal returns. From above, we know that holding the consumption of $x_2$ constant at 2, going from 2 to 3 units of $x_1$ increases our utility by $2.45-2=0.45$. Going from 3 to 4 units of $x_1$ brings our utility to $u(4,2)=4^{0.5}2^{0.5}\approx 2.83$, an increase of $2.83-2.45=0.38$ utility units.
86
+
87
+ Using calculus, we can more formally define the marginal utility of a good. Since marginal utility is the change in utility that one additional unit of consumption provides (holding all others constant), the marginal utility with respect to $x_1$ is its partial derivative: $\frac{\partial u}{\partial x_1}$. In our case:
88
+
89
+ $$
90
+ \begin{aligned}
91
+ \textrm{Marginal Utility of } x_1: &\quad\frac{\partial u}{\partial x_1} = \frac{1}{2}x_1^{-0.5}x_2^{0.5} \\
92
+ \textrm{Marginal Utility of } x_2: &\quad\frac{\partial u}{\partial x_2} = \frac{1}{2}x_1^{0.5}x_2^{-0.5}
93
+ \end{aligned}
94
+ $$
95
+
96
+ Or, more generally,
97
+
98
+ $$\begin{aligned}
99
+ \textrm{Marginal Utility of } x_1: &\quad\frac{\partial u}{\partial x_1} = \alpha x_1^{\alpha-1}x_2^{1-\alpha} \\
100
+ \textrm{Marginal Utility of } x_2: &\quad\frac{\partial u}{\partial x_2} = (1-\alpha) x_1^{\alpha}x_2^{-\alpha}
101
+ \end{aligned}$$
102
+
103
+
104
+ With marginal utility defined, note that both conditions can be explained using the marginal utility function $\frac{\partial u}{\partial x}$:
105
+
106
+ - Non-negative marginal utility: $\frac{\partial u}{\partial x} \geq 0$
107
+ - Diminishing marginal returns: $\frac{\partial^2 u}{\partial x^2} < 0$
108
+
109
+ ## Indifference Curves
110
+
111
+ Although the utility function above in 3D is cool, you'll typically find utility graphs to be in 2D with $x_1$ and $x_2$ as the axis (eliminating the utility axis).
112
+
113
+ To represent utility levels, we plot a set of indifference curves on the 2D graph. An indifference curve satisfies the property in which **any point on the curve has the exact same amount of utility**, so that consumers are _indifferent_ to any point on the curve. In our 3D plot, any point on the indifference curve has the exact same height, which represents the value of utility. If you're familar with contour plots, you can also think of indifference curves as following the same idea.
114
+
115
+ ```python
116
+ alpha = 0.5
117
+ utilities = np.arange(1, 9)
118
+ x1_indiff_val = np.linspace(0,50,1000)
119
+ x2_indiff_vals = []
120
+ for u in utilities:
121
+ x2_indiff_vals.append(((u/(x1_indiff_val ** alpha)) ** (1/(1-alpha))))
122
+ traces = []
123
+ colors = ['blue', 'red','green','purple'] + ['blue', 'red','green','purple']
124
+ for u, c, x2 in zip(utilities, colors, x2_indiff_vals):
125
+ traces.append(go.Scatter(
126
+ x = x1_indiff_val,
127
+ y = x2,
128
+ name = 'utility = ' + str(u),
129
+ line = dict(color = c,width = 1)))
130
+
131
+ data = traces
132
+
133
+ # Edit the layout
134
+ layout = dict(title = 'Indifference Curves for the Cobb-Douglas Utility Function (alpha = ' + str(alpha) + ')',
135
+ xaxis = dict(title = 'X1', range = [0,10]),
136
+ yaxis = dict(title = 'X2', range = [0,10]),)
137
+
138
+ fig = dict(data=data, layout=layout)
139
+
140
+ plot(fig, filename="fig2.html", auto_open=False)
141
+ display(HTML("fig2.html"))
142
+ ```
143
+
144
+
145
+
146
+ # Budget Constraints and Utility Maximization
147
+
148
+ In this section, we will assume that $\alpha = 0.5$ (i.e. the utility function is: $u(x_1, x_2) = x_1^{0.5}x_2^{0.5}$).
149
+
150
+ Now we introduce the concept of money into our model. Consumers face a budget constraint when choosing to maximize their utility. Given an income $M$ and prices $p_1$ for good $x_1$ and $p_2$ for good $x_2$, the consumer can at most spend up to $M$ for both goods:
151
+
152
+ $$M \geq p_1x_1 + p_2x_2$$
153
+
154
+ Since goods will always bring non-negative marginal utility, consumers will try to consume as many goods as they can. Hence, we can rewrite the budget constraint as an equality instead (since if they have more income leftover, they will use it to buy more goods).
155
+
156
+ $$M = p_1x_1 + p_2x_2$$
157
+
158
+ This means that any bundle of goods $(x_1,x_2)$ that consumers choose to consume will adhere to the equality above. What does this mean on our graph? Let's examine the indifference curve plots, assuming that $M = 32$, and $p_1 =2$ and $p_2 = 4$.
159
+
160
+ ```python
161
+ M = 32
162
+ p_1 = 2
163
+ p_2 = 4
164
+
165
+ # Plot default indifference curves
166
+ utilities = np.arange(1, 9)
167
+ x1_indiff_val = np.linspace(0,50,1000)
168
+ x2_indiff_vals = []
169
+ for u in utilities:
170
+ x2_indiff_vals.append(((u/(x1_indiff_val ** (1/2))) ** (2)))
171
+ traces = []
172
+ colors = ['blue', 'red','green','purple'] + ['blue', 'red','green','purple']
173
+ for u,c,x2 in zip(utilities,colors,x2_indiff_vals):
174
+ traces.append(go.Scatter(
175
+ x = x1_indiff_val,
176
+ y = x2,
177
+ name = 'utility = ' + str(u),
178
+ line = dict(color = c,width = 1)))
179
+
180
+ # for i in range(len(traces) - 4):
181
+ # del traces[-1] # This is a hacky method to not continually append to TRACES upon an update from the slider.
182
+ x2_bc_val = (M - (p_1*x1_indiff_val))/p_2
183
+ traces.append(go.Scatter(
184
+ x = x1_indiff_val,
185
+ y = x2_bc_val,
186
+ name = 'Budget Constraint',
187
+ line = dict(color = 'black',width = 1,dash="dot")))
188
+ data = traces
189
+ layout = dict(title = 'Budget Constraint and Indifference Curves for the Cobb-Douglas Utility Function (alpha = 0.5)',
190
+ xaxis = dict(title = 'X1', range = [0,18]),
191
+ yaxis = dict(title = 'X2', range = [0,10]),)
192
+ fig = dict(data=data, layout=layout)
193
+
194
+ plot(fig, filename="fig3.html", auto_open=False)
195
+ display(HTML("fig3.html"))
196
+ ```
197
+
198
+ The budget constraint is like a possibilities curve: moving up or down the constraint means gaining more of one good while sacrificing the other.
199
+
200
+ Let's take a look at what this budget constraint means. Because of the budget constraint, any bundle of goods $(x_1,x_2)$ that consumers ultimately decide to consume will lie on the budget constraint line. Adhering to this constraint where $M=32, p_1 = 2, p_2 = 4$, we can see that consumers will be able to achieve 2 units of utility, and can also achieve 4 units of utility. But what is the maximum amount of utility that consumers can achieve?
201
+
202
+ Notice an interesting property about indifference curves: **the utility level of the indifference curves gets larger as we move up and to the right.** Hence, the maximizing amount of utility in this budget constraint is the rightmost indifference curve that still touches the budget constraint line. In fact, it'll only 'touch' (and not intersect) the budget constraint and be tangential to it.
203
+
204
+ ```python
205
+ M = 32
206
+ p_1 = 2
207
+ p_2 = 4
208
+
209
+ # Plot default indifference curves
210
+ utilities = np.arange(1, 9)
211
+ x1_indiff_val = np.linspace(0,50,1000)
212
+ x2_indiff_vals = []
213
+ for u in utilities:
214
+ x2_indiff_vals.append(((u/(x1_indiff_val ** (1/2))) ** (2)))
215
+ traces = []
216
+ colors = ['blue', 'red','green','purple'] + ['blue', 'red','green','purple']
217
+ for u,c,x2 in zip(utilities,colors,x2_indiff_vals):
218
+ traces.append(go.Scatter(
219
+ x = x1_indiff_val,
220
+ y = x2,
221
+ name = 'utility = ' + str(u),
222
+ line = dict(color = c,width = 1)))
223
+
224
+ # PLOT BC
225
+ x2_bc_val = (M - (p_1*x1_indiff_val))/p_2
226
+ traces.append(go.Scatter(
227
+ x = x1_indiff_val,
228
+ y = x2_bc_val,
229
+ name = 'Budget Constraint',
230
+ line = dict(color = 'black',width = 1,dash="dot")))
231
+
232
+
233
+ # PLOT MAX UTIL INDIFF CURVE
234
+ max_utility = ((1/2*M/p_1) ** (1/2)) * ((1/2*M/p_2) ** (1/2))
235
+ x2_max_util = (max_utility/(x1_indiff_val ** (1/2))) ** 2
236
+ x2_max_util = (max_utility/(x1_indiff_val ** (1/2))) ** 2
237
+ traces.append(go.Scatter(
238
+ x = x1_indiff_val,
239
+ y = x2_max_util,
240
+ name = 'Maximized Utility = ' + str(round(max_utility, 2)),
241
+ line = dict(color = 'black',width = 2)))
242
+ data = traces
243
+
244
+ layout = dict(title = 'Budget Constraint and Indifference Curves for the Cobb-Douglas Utility Function (alpha = 0.5)',
245
+ xaxis = dict(title = 'X1', range = [0,20]),
246
+ yaxis = dict(title = 'X2', range = [0,15]),)
247
+ fig = dict(data=data, layout=layout)
248
+
249
+ plot(fig, filename="fig4.html", auto_open=False)
250
+ display(HTML("fig4.html"))
251
+ ```
252
+
253
+ Notice that as the price of one good increases, the indifference curve that represents the maximum attainable utility shifts towards the left (i.e. the max utility decreases). Intuitively, this makes sense. As the price of one good increases, consumers have to make adjustments to their consumption bundles and buy less of one, or both, goods. Hence, their maximum utility will decrease.
254
+
255
+ Let's visualize the budget constraint in 3D where $M=30, p_1=3, p_2=3$. Here, any point along the curve in which the 2 planes intersect represents an amount of utility in which the budget constraint holds true (i.e. where we've spent all our income). The utility maximizing quantity is a point on this intersecting curve at which the utility level is the highest.
256
+
257
+ ```python
258
+ def cobb_douglas(x1, x2):
259
+ return (x1 ** (1/2)) * (x2 ** (1/2))
260
+ x1 = np.linspace(0,10,10)
261
+ x2 = np.linspace(0,10,10)
262
+ X1,X2 = np.meshgrid(x1,x2)
263
+ z = cobb_douglas(X1,X2)
264
+
265
+ def budget_constraint(x1, x2):
266
+ return 10000*(3*x1 + 3*x2 - 30) # We multiply this by 10000 to get a very steep plane, which should be similar to the actual BC, a vertical plane.
267
+
268
+ z2 = budget_constraint(X1, X2)
269
+
270
+ data = [go.Surface(
271
+ z=z, contours=go.surface.Contours(z=go.surface.contours.Z(show=True,usecolormap=True,highlightcolor="#42f462",
272
+ project=dict(z=True))), name="Cobb-Douglas Utility Function"),
273
+ go.Surface(
274
+ z=z2, contours=go.surface.Contours(z=go.surface.contours.Z(show=True,usecolormap=False,
275
+ highlightcolor="#42f462",project=dict(z=True))),showscale=False, colorscale="balance", name="Budget Constraint")]
276
+ layout = go.Layout(
277
+ title='Cobb-Douglas Utility Function with Budget Constraint', autosize=False,width=500, height=500, margin=dict(l=65,r=50,b=65,t=90),
278
+ scene = dict(xaxis = dict(title='X1', range = [0,10]), yaxis = dict(title='X2'),
279
+ zaxis = dict(title = 'Utility', nticks=4, range = [0,10],)))
280
+ fig = go.Figure(data=data, layout=layout)
281
+
282
+ plot(fig, filename="fig5.html", auto_open=False)
283
+ display(HTML("fig5.html"))
284
+ ```
285
+
286
+
287
+
@@ -0,0 +1,399 @@
1
+ ---
2
+ title: "6.3-QuantEcon-Optimization"
3
+ type: lecture-notebook
4
+ week: 6
5
+ source_path: "/Users/ericvandusen/Documents/Data88E-ForTraining/F24Lec_NBs/lec06/6.3-QuantEcon-Optimization.ipynb"
6
+ ---
7
+
8
+ # Optimization from QuantEcon
9
+
10
+ This is a Lecture written by the QuantEcon project
11
+ https://datascience.quantecon.org/scientific/optimization.html
12
+
13
+
14
+
15
+ **Prerequisites**
16
+
17
+ - [Introduction to Numpy](https://datascience.quantecon.org/numpy_arrays.html)
18
+ - [Applied Linear Algebra](https://datascience.quantecon.org/applied_linalg.html)
19
+
20
+
21
+ **Outcomes**
22
+
23
+ - Perform optimization by hand using derivatives
24
+ - Understand ideas from gradient descent
25
+
26
+ ```python
27
+ import numpy as np
28
+ import matplotlib.pyplot as plt
29
+ %matplotlib inline
30
+ ```
31
+
32
+ ## What is Optimization?
33
+
34
+ Optimization is the branch of mathematics focused on finding extreme values (max or min) of
35
+ functions.
36
+
37
+ Optimization tools will appear in many places throughout this course, including:
38
+
39
+ - Building economic models in which individuals make decisions that maximize their utility.
40
+ - Building statistical models and maximizing the fit of these models by optimizing certain fit
41
+ functions.
42
+
43
+
44
+ In this lecture, we will focus mostly on the first to limit the moving pieces, but in other lectures, we’ll discuss the second in detail.
45
+
46
+ ### Derivatives and Optima
47
+
48
+ Here, we revisit some of the theory that you have already learned in your calculus class.
49
+
50
+ Consider function $ f(x) $ which maps a number into another number. We can say that any point
51
+ where $ f'(x) = 0 $ is a local extremum of $ f $.
52
+
53
+ Let’s work through an example. Consider the function
54
+
55
+ $$
56
+ f(x) = x^4 - 3 x^2
57
+ $$
58
+
59
+ Its derivative is given by
60
+
61
+ $$
62
+ \frac{\partial f}{\partial x} = 4 x^3 - 6 x
63
+ $$
64
+
65
+ Let’s plot the function and its derivative to pick out the local extremum by hand.
66
+
67
+ ```python
68
+ def f(x):
69
+ return x**4 - 3*x**2
70
+
71
+
72
+ def fp(x):
73
+ return 4*x**3 - 6*x
74
+
75
+ # Create 100 evenly spaced points between -2 and 2
76
+ x = np.linspace(-2., 2., 100)
77
+
78
+ # Evaluate the functions at x values
79
+ fx = f(x)
80
+ fpx = fp(x)
81
+
82
+ # Create plot
83
+ fig, ax = plt.subplots(1, 2)
84
+
85
+ ax[0].plot(x, fx)
86
+ ax[0].set_title("Function")
87
+
88
+ ax[1].plot(x, fpx)
89
+ ax[1].hlines(0.0, -2.5, 2.5, color="k", linestyle="--")
90
+ ax[1].set_title("Derivative")
91
+
92
+ for _ax in ax:
93
+ _ax.spines["right"].set_visible(False)
94
+ _ax.spines["top"].set_visible(False)
95
+ ```
96
+
97
+ If you stare at this picture, you can probably determine the the local maximum is at
98
+ $ x = 0 $ and the local minima at $ x \approx -1 $ and $ x \approx 1 $.
99
+
100
+ To properly determine the minima and maxima, we find the solutions to $ f'(x) = 0 $ below:
101
+
102
+ $$
103
+ f'(x) = 4 x^3 - 6 x = 0
104
+ $$
105
+
106
+ $$
107
+ \rightarrow x = \left\{0, \frac{\sqrt{6}}{2}, \frac{-\sqrt{6}}{2} \right\}
108
+ $$
109
+
110
+ Let’s check whether we can get the same answers with Python! To do this, we import a new
111
+ package that we haven’t seen yet.
112
+
113
+ ```python
114
+ import scipy.optimize as opt
115
+ ```
116
+
117
+ Then using the function definitions from earlier, we search for the minimum and maximum values.
118
+
119
+ ```python
120
+ # For a scalar problem, we give it the function and the bounds between
121
+ # which we want to search
122
+ neg_min = opt.minimize_scalar(f, [-2, -0.5])
123
+ pos_min = opt.minimize_scalar(f, [0.5, 2.0])
124
+ print("The negative minimum is: \n", neg_min)
125
+ print("The positive minimum is: \n", pos_min)
126
+ ```
127
+
128
+ The scipy optimize package only has functions that find minimums… You might be wondering, then, how we
129
+ will verify our maximum value.
130
+
131
+ It turns out that finding the maximum is equivalent to simply finding the minimum of the negative function.
132
+
133
+ ```python
134
+ # Create a function that evaluates to negative f
135
+ def neg_f(x):
136
+ return -f(x)
137
+
138
+ max_out = opt.minimize_scalar(neg_f, [-0.35, 0.35])
139
+ print("The maximum is: \n", max_out)
140
+ ```
141
+
142
+ We won’t dive into the details of optimization algorithms in this lecture, but we’ll impart some brief
143
+ intuition to help you understand the types of problems these algorithms are good at solving and
144
+ the types of problems they will struggle with:
145
+
146
+ The general intuition is that when you’re finding a maximum, an algorithm takes a step
147
+ in the direction of the derivative… (Conversely, to find a minimum, the algorithm takes a step opposite the direction of the derivative.)
148
+ This requires the function to be relatively smooth and continuous. The algorithm also has an easier time if there is only one (or very few) extremum to be found…
149
+
150
+ For minimization, you can imagine the algorithm as a marble in a bowl.
151
+
152
+ The marble will keep rolling down the slope of the bowl until it finds the bottom.
153
+
154
+ It may overshoot, but once it hits the slope on the other side, it will continue to roll back
155
+ and forth until it comes to rest.
156
+
157
+ Thus, when deciding whether numerical optimization is an effective method for a
158
+ particular problem, you could try visualizing the function to determine whether a marble
159
+ would be able to come to rest at the extreme values you are looking for.
160
+
161
+ ### Application: Consumer Theory
162
+
163
+ A common use of maximization in economics is to model
164
+ optimal consumption decisions [https://en.wikipedia.org/wiki/Consumer_choice](https://en.wikipedia.org/wiki/Consumer_choice).
165
+
166
+ #### Preferences and Utility Functions
167
+
168
+ To summarize introductory economics, take a set of
169
+ [preferences](https://en.wikipedia.org/wiki/Preference_%28economics%29) of consumers over “bundles”
170
+ of goods (e.g. 2 apples and 3 oranges is preferred to 3 apples and 2 oranges, or a 100% chance to
171
+ win $ 1 $ dollar is preferred to a 50% chance to win $ 2.10 $ dollars).
172
+
173
+ Under certain assumptions, you rationalize the preferences as a utility function over the different
174
+ goods (always remembering that the utility is simply a tool to order preferences and the numbers are
175
+ usually not meaningful themselves).
176
+
177
+ For example, consider a utility function over bundles of bananas (B) and apples (A)
178
+
179
+ $$
180
+ U(B, A) = B^{\alpha}A^{1-\alpha}
181
+ $$
182
+
183
+ Where $ \alpha \in [0,1] $.
184
+
185
+ First, let’s take a look at this particular utility function.
186
+
187
+ ```python
188
+ def U(A, B, alpha=1/3):
189
+ return B**alpha * A**(1-alpha)
190
+
191
+ fig, ax = plt.subplots()
192
+ B = 1.5
193
+ A = np.linspace(1, 10, 100)
194
+ ax.plot(A, U(A, B))
195
+ ax.set_xlabel("A")
196
+ ax.set_ylabel("U(B=1.5, A)")
197
+ ```
198
+
199
+ We note that
200
+
201
+ - $ U(B,1) $ is always higher with more B, hence, consuming more bananas has a
202
+ : positive marginal utility i.e. $ \frac{d U(B,1)}{d B} > 0 $.
203
+ - The more bananas we consume, the smaller the change in marginal utility, i.e.
204
+ $ \frac{d^2 U(B,1)}{d B^2} < 0 $.
205
+
206
+
207
+ If we plot both the $ B $ and the $ A $, we can see how the utility changes with different
208
+ bundles.
209
+
210
+ ```python
211
+ fig, ax = plt.subplots()
212
+ B = np.linspace(1, 20, 100).reshape((100, 1))
213
+ contours = ax.contourf(A, B.flatten(), U(A, B))
214
+ fig.colorbar(contours)
215
+ ax.set_xlabel("A")
216
+ ax.set_ylabel("B")
217
+ ax.set_title("U(A,B)")
218
+ ```
219
+
220
+ We can find the bundles between which the consumer would be indifferent by fixing a
221
+ utility $ \bar{U} $ and by determining all combinations of $ A $ and $ B $ where
222
+ $ \bar{U} = U(B, A) $.
223
+
224
+ In this example, we can implement this calculation by letting $ B $ be the variable on the
225
+ x-axis and solving for $ A(\bar{U}, B) $
226
+
227
+ $$
228
+ A(B, \bar{U}) = U^{\frac{1}{1-\alpha}}B^{\frac{-\alpha}{1-\alpha}}
229
+ $$
230
+
231
+ ```python
232
+ def A_indifference(B, ubar, alpha=1/3):
233
+ return ubar**(1/(1-alpha)) * B**(-alpha/(1-alpha))
234
+
235
+ def plot_indifference_curves(ax, alpha=1/3):
236
+ ubar = np.arange(1, 11, 2)
237
+ ax.plot(B, A_indifference(B, ubar, alpha))
238
+ ax.legend([r"$\bar{U}$" + " = {}".format(i) for i in ubar])
239
+ ax.set_xlabel("B")
240
+ ax.set_ylabel(r"$A(B, \bar{U}$)")
241
+
242
+ fig, ax = plt.subplots()
243
+ plot_indifference_curves(ax)
244
+ ```
245
+
246
+ Note that in every case, if you increase either the number of apples or bananas (holding the other
247
+ fixed), you reach a higher indifference curve.
248
+
249
+ Consequently, in a world without scarcity or budgets, consumers would consume
250
+ an arbitrarily high number of both to maximize their utility.
251
+
252
+ #### Budget Constraints
253
+
254
+ While the above example plots consumer preferences, it says nothing about what the consumers can afford.
255
+
256
+ The simplest sort of constraint is a budget constraint where bananas and apples both have a price
257
+ and the consumer has a limited amount of funds.
258
+
259
+ If the prices per banana and per apple are identical, no matter how many you consume, then the
260
+ affordable bundles are simply all pairs of apples and bananas below the line.
261
+ $ p_a A + p_b B \leq W $.
262
+
263
+ For example, if consumer has a budget of $ W $, the price of apples is $ p_A = 2 $ dollars per
264
+ apple, and the price of bananas is normalized to be $ p_B = 1 $ dollar per banana, then the consumer
265
+ can afford anything below the line.
266
+
267
+ $$
268
+ 2 A + B \leq W
269
+ $$
270
+
271
+ Or, letting $ W = 20 $ and plotting
272
+
273
+ ```python
274
+ def A_bc(B, W=20, pa=2):
275
+ "Given B, W, and pa return the max amount of A our consumer can afford"
276
+ return (W - B) / pa
277
+
278
+ def plot_budget_constraint(ax, W=20, pa=2):
279
+ B_bc = np.array([0, W])
280
+ A = A_bc(B_bc, W, pa)
281
+ ax.plot(B_bc, A)
282
+ ax.fill_between(B_bc, 0, A, alpha=0.2)
283
+ ax.set_xlabel("B")
284
+ ax.set_ylabel("A")
285
+ return ax
286
+
287
+ fig, ax = plt.subplots()
288
+ plot_budget_constraint(ax, 20, 2)
289
+ ```
290
+
291
+ While the consumer can afford any of the bundles in that area, most will not be optimal.
292
+
293
+ #### Optimal Choice
294
+
295
+ Putting the budget constraints and the utility functions together lets us visualize the optimal
296
+ decision of a consumer. Choose the bundle with the highest possible indifference curve within its
297
+ budget set.
298
+
299
+ ```python
300
+ fig, ax = plt.subplots()
301
+ plot_indifference_curves(ax)
302
+ plot_budget_constraint(ax)
303
+ ```
304
+
305
+ We have several ways to find the particular point $ A, B $ of maximum utility, such as
306
+ finding the point where the indifference curve and the budget constraint have the same slope, but a
307
+ simple approach is to just solve the direct maximization problem.
308
+
309
+ $$
310
+ \begin{aligned}
311
+ \max_{A, B} & B^{\alpha}A^{1-\alpha}\\
312
+ \text{s.t. } & p_A A + B \leq W
313
+ \end{aligned}
314
+ $$
315
+
316
+ Solving this problem directly requires solving a multi-dimensional constrained optimization problem,
317
+ where scipy [https://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html#constrained-minimization-of-multivariate-scalar-functions-minimize](https://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html#constrained-minimization-of-multivariate-scalar-functions-minimize)
318
+ has several options.
319
+
320
+ For this particular problem, we notice two things: (1) The utility function is increasing in both
321
+ $ A $ and $ B $, and (2) there are only 2 goods.
322
+
323
+ This allows us 1) to assume that the budget constraint holds at equality, $ p_a A + B = W $, 2) to
324
+ form a new function $ A(B) = (W - B) / p_a $ by rearranging the budget constraint at equality, and
325
+ 3) to substitute that function directly to form:
326
+
327
+ $$
328
+ \max_{B} B^{\alpha}A(B)^{1-\alpha}
329
+ $$
330
+
331
+ Compared to before, this problem has been turned into an unconstrained univariate optimization
332
+ problem.
333
+
334
+ To implement this in code, notice that the $ A(B) $ function is what we defined before
335
+ as `A_bc`.
336
+
337
+ We will solve this by using the function `scipy.optimize.minimize_scalar`, which takes a function
338
+ `f(x)` and returns the value of `x` that minimizes `f`.
339
+
340
+ ```python
341
+ from scipy.optimize import minimize_scalar
342
+
343
+ def objective(B, W=20, pa=2):
344
+ """
345
+ Return value of -U for a given B, when we consume as much A as possible
346
+
347
+ Note that we return -U because scipy wants to minimize functions,
348
+ and the value of B that minimizes -U will maximize U
349
+ """
350
+ A = A_bc(B, W, pa)
351
+ return -U(A, B)
352
+
353
+ result = minimize_scalar(objective)
354
+ optimal_B = result.x
355
+ optimal_A = A_bc(optimal_B, 20, 2)
356
+ optimal_U = U(optimal_A, optimal_B)
357
+
358
+ print("The optimal U is ", optimal_U)
359
+ print("and was found at (A,B) =", (optimal_A, optimal_B))
360
+ ```
361
+
362
+ This allows us to do experiments, such as examining how consumption patterns change as prices or
363
+ wealth levels change.
364
+
365
+ But First, Let's fix the graph!
366
+ Lets add UBar to the Set of Indifference Curves
367
+
368
+ ```python
369
+ def A_indifference(B, ubar, alpha=1/3):
370
+ return ubar**(1/(1-alpha)) * B**(-alpha/(1-alpha))
371
+
372
+ def plot_indifference_curves(ax, alpha=1/3):
373
+ ubar = np.arange(1, 11, 2)
374
+ ubar = np.append(ubar, optimal_U)
375
+ ax.plot(B, A_indifference(B, ubar, alpha))
376
+ ax.legend([r"$\bar{U}$" + " = {}".format(i) for i in ubar])
377
+ ax.set_xlabel("B")
378
+ ax.set_ylabel(r"$A(B, \bar{U}$)")
379
+
380
+ fig, ax = plt.subplots()
381
+ plot_indifference_curves(ax)
382
+ ```
383
+
384
+ Then lets set the optimal level of consumpton of A and B
385
+ and add them to the graph
386
+
387
+ ```python
388
+ fig, ax = plt.subplots()
389
+ plot_indifference_curves(ax)
390
+ plot_budget_constraint(ax)
391
+ ax.plot(optimal_B, optimal_A, 'go', label=f"Optimal Point (A, B) = ({optimal_A:.2f}, {optimal_B:.2f})")
392
+ ax.annotate(f"({optimal_A:.2f}, {optimal_B:.2f})", (optimal_B, optimal_A),
393
+ textcoords="offset points", xytext=(5,5), ha='center')
394
+ ```
395
+
396
+ ```python
397
+
398
+ ```
399
+