Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ok-landscape
GitHub Repository: Ok-landscape/computational-pipeline
Path: blob/main/latex-templates/templates/economics/market_model.tex
51 views
unlisted
1
\documentclass[a4paper, 11pt]{report}
2
\usepackage[utf8]{inputenc}
3
\usepackage[T1]{fontenc}
4
\usepackage{amsmath, amssymb}
5
\usepackage{graphicx}
6
\usepackage{siunitx}
7
\usepackage{booktabs}
8
\usepackage{xcolor}
9
\usepackage[makestderr]{pythontex}
10
11
\definecolor{supply}{RGB}{46, 204, 113}
12
\definecolor{demand}{RGB}{231, 76, 60}
13
\definecolor{equilib}{RGB}{52, 152, 219}
14
15
\title{Market Economics:\\
16
Supply, Demand, Elasticity, and Welfare Analysis}
17
\author{Department of Economics\\Technical Report EC-2024-002}
18
\date{\today}
19
20
\begin{document}
21
\maketitle
22
23
\begin{abstract}
24
This report presents a computational analysis of market models. We examine supply and demand curves, compute market equilibrium, analyze price elasticity, measure consumer and producer surplus, and evaluate the welfare effects of taxes and price controls.
25
\end{abstract}
26
27
\tableofcontents
28
29
\chapter{Introduction}
30
31
Market equilibrium occurs where supply equals demand:
32
\begin{equation}
33
Q_d(P) = Q_s(P)
34
\end{equation}
35
36
\section{Linear Supply and Demand}
37
\begin{align}
38
Q_d &= a - bP \quad \text{(Demand)} \\
39
Q_s &= c + dP \quad \text{(Supply)}
40
\end{align}
41
42
Equilibrium: $P^* = \frac{a - c}{b + d}$, $Q^* = \frac{ad + bc}{b + d}$
43
44
\begin{pycode}
45
import numpy as np
46
import matplotlib.pyplot as plt
47
from scipy.optimize import fsolve
48
from scipy.integrate import quad
49
plt.rc('text', usetex=True)
50
plt.rc('font', family='serif')
51
52
np.random.seed(42)
53
54
# Market parameters
55
a, b = 100, 1 # Demand: Q = a - b*P
56
c, d = 0, 2 # Supply: Q = c + d*P
57
58
def demand(P):
59
return a - b * P
60
61
def supply(P):
62
return c + d * P
63
64
def inverse_demand(Q):
65
return (a - Q) / b
66
67
def inverse_supply(Q):
68
return (Q - c) / d
69
70
# Equilibrium
71
P_eq = (a - c) / (b + d)
72
Q_eq = a - b * P_eq
73
74
# Elasticity functions
75
def price_elasticity_demand(P, Q):
76
return -b * P / Q
77
78
def price_elasticity_supply(P, Q):
79
return d * P / Q
80
81
# Welfare measures
82
def consumer_surplus(P_eq, Q_eq):
83
return 0.5 * (a/b - P_eq) * Q_eq
84
85
def producer_surplus(P_eq, Q_eq):
86
return 0.5 * (P_eq - c/d) * Q_eq
87
88
CS = consumer_surplus(P_eq, Q_eq)
89
PS = producer_surplus(P_eq, Q_eq)
90
\end{pycode}
91
92
\chapter{Market Equilibrium}
93
94
\begin{pycode}
95
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
96
97
# Basic supply and demand
98
ax = axes[0, 0]
99
P_range = np.linspace(0, 50, 100)
100
Q_d = demand(P_range)
101
Q_s = supply(P_range)
102
103
ax.plot(Q_d, P_range, 'r-', linewidth=2, label='Demand')
104
ax.plot(Q_s, P_range, 'g-', linewidth=2, label='Supply')
105
ax.plot(Q_eq, P_eq, 'bo', markersize=10, zorder=5)
106
ax.axhline(P_eq, color='blue', linestyle='--', alpha=0.5)
107
ax.axvline(Q_eq, color='blue', linestyle='--', alpha=0.5)
108
ax.set_xlabel('Quantity $Q$')
109
ax.set_ylabel('Price $P$')
110
ax.set_title(f'Market Equilibrium: $P^* = {P_eq:.1f}$, $Q^* = {Q_eq:.1f}$')
111
ax.legend()
112
ax.set_xlim(0, 100)
113
ax.set_ylim(0, 50)
114
ax.grid(True, alpha=0.3)
115
116
# Consumer and producer surplus
117
ax = axes[0, 1]
118
ax.plot(Q_d, P_range, 'r-', linewidth=2, label='Demand')
119
ax.plot(Q_s, P_range, 'g-', linewidth=2, label='Supply')
120
121
# CS: area below demand, above price
122
Q_cs = np.linspace(0, Q_eq, 100)
123
P_cs = inverse_demand(Q_cs)
124
ax.fill_between(Q_cs, P_eq, P_cs, alpha=0.3, color='red', label='CS')
125
126
# PS: area above supply, below price
127
Q_ps = np.linspace(0, Q_eq, 100)
128
P_ps = inverse_supply(Q_ps)
129
ax.fill_between(Q_ps, P_ps, P_eq, alpha=0.3, color='green', label='PS')
130
131
ax.plot(Q_eq, P_eq, 'bo', markersize=10, zorder=5)
132
ax.set_xlabel('Quantity $Q$')
133
ax.set_ylabel('Price $P$')
134
ax.set_title(f'Welfare: CS = {CS:.1f}, PS = {PS:.1f}')
135
ax.legend()
136
ax.set_xlim(0, 100)
137
ax.set_ylim(0, 50)
138
ax.grid(True, alpha=0.3)
139
140
# Effect of tax
141
tax = 10
142
P_buyers = P_eq + tax * b / (b + d)
143
P_sellers = P_eq - tax * d / (b + d)
144
Q_tax = demand(P_buyers)
145
146
ax = axes[1, 0]
147
ax.plot(Q_d, P_range, 'r-', linewidth=2, label='Demand')
148
ax.plot(Q_s, P_range, 'g-', linewidth=2, label='Supply')
149
ax.plot(Q_s + tax * d, P_range, 'g--', linewidth=2, alpha=0.5, label='Supply + Tax')
150
151
ax.plot(Q_eq, P_eq, 'bo', markersize=8, label='No tax')
152
ax.plot(Q_tax, P_buyers, 'rs', markersize=8, label='Buyer price')
153
ax.plot(Q_tax, P_sellers, 'gs', markersize=8, label='Seller price')
154
155
# Tax revenue
156
ax.fill_between([Q_tax, Q_tax], [P_sellers, P_sellers], [P_buyers, P_buyers],
157
alpha=0.3, color='blue')
158
ax.annotate('Tax Revenue', xy=(Q_tax/2, (P_buyers + P_sellers)/2),
159
fontsize=9, ha='center')
160
161
# Deadweight loss
162
ax.fill([Q_tax, Q_eq, Q_tax], [P_sellers, P_eq, P_buyers],
163
alpha=0.3, color='gray')
164
165
ax.set_xlabel('Quantity $Q$')
166
ax.set_ylabel('Price $P$')
167
ax.set_title(f'Tax Effect: $\\tau = {tax}$')
168
ax.legend(loc='upper right', fontsize=8)
169
ax.set_xlim(0, 100)
170
ax.set_ylim(0, 50)
171
ax.grid(True, alpha=0.3)
172
173
# Elasticity along demand curve
174
ax = axes[1, 1]
175
Q_range = np.linspace(1, 99, 100)
176
P_range_el = inverse_demand(Q_range)
177
elasticity = np.abs(price_elasticity_demand(P_range_el, Q_range))
178
179
ax.plot(Q_range, elasticity, 'b-', linewidth=2)
180
ax.axhline(1, color='red', linestyle='--', alpha=0.5, label='Unit elastic')
181
ax.fill_between(Q_range, 0, elasticity, where=elasticity > 1, alpha=0.3, color='blue', label='Elastic')
182
ax.fill_between(Q_range, 0, elasticity, where=elasticity <= 1, alpha=0.3, color='green', label='Inelastic')
183
ax.set_xlabel('Quantity $Q$')
184
ax.set_ylabel('$|\\varepsilon_d|$')
185
ax.set_title('Price Elasticity of Demand')
186
ax.legend()
187
ax.grid(True, alpha=0.3)
188
ax.set_ylim(0, 10)
189
190
plt.tight_layout()
191
plt.savefig('market_analysis.pdf', dpi=150, bbox_inches='tight')
192
plt.close()
193
194
# Tax calculations
195
tax_revenue = tax * Q_tax
196
DWL = 0.5 * tax * (Q_eq - Q_tax)
197
elasticity_eq = price_elasticity_demand(P_eq, Q_eq)
198
\end{pycode}
199
200
\begin{figure}[htbp]
201
\centering
202
\includegraphics[width=0.95\textwidth]{market_analysis.pdf}
203
\caption{Market analysis: (a) equilibrium, (b) welfare surplus, (c) tax effects, (d) elasticity.}
204
\end{figure}
205
206
\chapter{Price Elasticity}
207
208
\section{Definition}
209
Price elasticity of demand:
210
\begin{equation}
211
\varepsilon_d = \frac{\partial Q_d}{\partial P} \cdot \frac{P}{Q_d}
212
\end{equation}
213
214
\begin{itemize}
215
\item $|\varepsilon_d| > 1$: Elastic (revenue increases with price decrease)
216
\item $|\varepsilon_d| < 1$: Inelastic (revenue decreases with price decrease)
217
\item $|\varepsilon_d| = 1$: Unit elastic
218
\end{itemize}
219
220
\chapter{Welfare Analysis}
221
222
\begin{pycode}
223
# Compare different market scenarios
224
fig, axes = plt.subplots(1, 3, figsize=(14, 4))
225
226
# Price ceiling (below equilibrium)
227
ax = axes[0]
228
P_ceiling = P_eq - 10
229
Q_supplied = supply(P_ceiling)
230
Q_demanded = demand(P_ceiling)
231
232
P_range = np.linspace(0, 50, 100)
233
ax.plot(demand(P_range), P_range, 'r-', linewidth=2, label='Demand')
234
ax.plot(supply(P_range), P_range, 'g-', linewidth=2, label='Supply')
235
ax.axhline(P_ceiling, color='blue', linestyle='-', linewidth=2, label='Price ceiling')
236
ax.fill_between([Q_supplied, Q_demanded], 0, P_ceiling, alpha=0.2, color='gray')
237
ax.annotate('Shortage', xy=((Q_supplied + Q_demanded)/2, P_ceiling/2),
238
fontsize=10, ha='center')
239
ax.set_xlabel('Quantity $Q$')
240
ax.set_ylabel('Price $P$')
241
ax.set_title('Price Ceiling (Shortage)')
242
ax.legend()
243
ax.set_xlim(0, 100)
244
ax.set_ylim(0, 50)
245
ax.grid(True, alpha=0.3)
246
247
# Price floor (above equilibrium)
248
ax = axes[1]
249
P_floor = P_eq + 10
250
Q_supplied = supply(P_floor)
251
Q_demanded = demand(P_floor)
252
253
ax.plot(demand(P_range), P_range, 'r-', linewidth=2, label='Demand')
254
ax.plot(supply(P_range), P_range, 'g-', linewidth=2, label='Supply')
255
ax.axhline(P_floor, color='orange', linestyle='-', linewidth=2, label='Price floor')
256
ax.fill_between([Q_demanded, Q_supplied], P_floor, 50, alpha=0.2, color='gray')
257
ax.annotate('Surplus', xy=((Q_demanded + Q_supplied)/2, (P_floor + 50)/2),
258
fontsize=10, ha='center')
259
ax.set_xlabel('Quantity $Q$')
260
ax.set_ylabel('Price $P$')
261
ax.set_title('Price Floor (Surplus)')
262
ax.legend()
263
ax.set_xlim(0, 100)
264
ax.set_ylim(0, 50)
265
ax.grid(True, alpha=0.3)
266
267
# Demand shift
268
ax = axes[2]
269
a_new = 120 # Increased demand
270
P_eq_new = (a_new - c) / (b + d)
271
Q_eq_new = a_new - b * P_eq_new
272
273
ax.plot(demand(P_range), P_range, 'r-', linewidth=2, alpha=0.5, label='$D_1$')
274
ax.plot(a_new - b * P_range, P_range, 'r--', linewidth=2, label='$D_2$')
275
ax.plot(supply(P_range), P_range, 'g-', linewidth=2, label='Supply')
276
ax.plot(Q_eq, P_eq, 'bo', markersize=8, label='Old eq')
277
ax.plot(Q_eq_new, P_eq_new, 'ro', markersize=8, label='New eq')
278
ax.annotate('', xy=(Q_eq_new, P_eq_new), xytext=(Q_eq, P_eq),
279
arrowprops=dict(arrowstyle='->', color='black'))
280
ax.set_xlabel('Quantity $Q$')
281
ax.set_ylabel('Price $P$')
282
ax.set_title('Demand Shift')
283
ax.legend()
284
ax.set_xlim(0, 120)
285
ax.set_ylim(0, 50)
286
ax.grid(True, alpha=0.3)
287
288
plt.tight_layout()
289
plt.savefig('market_interventions.pdf', dpi=150, bbox_inches='tight')
290
plt.close()
291
\end{pycode}
292
293
\begin{figure}[htbp]
294
\centering
295
\includegraphics[width=0.95\textwidth]{market_interventions.pdf}
296
\caption{Market interventions: price ceiling creates shortage, price floor creates surplus, demand shift moves equilibrium.}
297
\end{figure}
298
299
\chapter{Numerical Results}
300
301
\begin{pycode}
302
market_results = [
303
('Equilibrium price', f'{P_eq:.2f}', 'dollars'),
304
('Equilibrium quantity', f'{Q_eq:.2f}', 'units'),
305
('Consumer surplus', f'{CS:.2f}', 'dollars'),
306
('Producer surplus', f'{PS:.2f}', 'dollars'),
307
('Total welfare', f'{CS + PS:.2f}', 'dollars'),
308
('Elasticity at equilibrium', f'{abs(elasticity_eq):.2f}', ''),
309
('Tax revenue', f'{tax_revenue:.2f}', 'dollars'),
310
('Deadweight loss', f'{DWL:.2f}', 'dollars'),
311
]
312
\end{pycode}
313
314
\begin{table}[htbp]
315
\centering
316
\caption{Market equilibrium results}
317
\begin{tabular}{@{}lcc@{}}
318
\toprule
319
Variable & Value & Units \\
320
\midrule
321
\py{market_results[0][0]} & \py{market_results[0][1]} & \py{market_results[0][2]} \\
322
\py{market_results[1][0]} & \py{market_results[1][1]} & \py{market_results[1][2]} \\
323
\py{market_results[2][0]} & \py{market_results[2][1]} & \py{market_results[2][2]} \\
324
\py{market_results[3][0]} & \py{market_results[3][1]} & \py{market_results[3][2]} \\
325
\py{market_results[4][0]} & \py{market_results[4][1]} & \py{market_results[4][2]} \\
326
\py{market_results[5][0]} & \py{market_results[5][1]} & \py{market_results[5][2]} \\
327
\py{market_results[6][0]} & \py{market_results[6][1]} & \py{market_results[6][2]} \\
328
\py{market_results[7][0]} & \py{market_results[7][1]} & \py{market_results[7][2]} \\
329
\bottomrule
330
\end{tabular}
331
\end{table}
332
333
\chapter{Conclusions}
334
335
\begin{enumerate}
336
\item Market equilibrium maximizes total welfare (CS + PS)
337
\item Taxes create deadweight loss proportional to elasticities
338
\item Price controls create shortages or surpluses
339
\item Elasticity determines tax incidence between buyers and sellers
340
\item Welfare analysis quantifies policy effects
341
\end{enumerate}
342
343
\end{document}
344
345