├── .gitignore
├── Central Python concepts.ipynb
├── LICENSE
├── PS0
├── problem set 0.lyx
└── problem set 0.pdf
├── PS1
├── A1.py
├── A2.py
├── A3.py
├── A4.py
├── A5.py
├── A6.py
├── A7.py
├── A8.py
└── problem_set_1.ipynb
├── PS2
├── A1.py
├── A2.py
├── A3.py
├── A4.py
├── A5.py
├── A6.py
├── mymodule.py
└── problem_set_2.ipynb
├── PS3
├── A01.py
├── A02.py
├── A03.py
├── A04.py
├── A05.py
├── A06.py
├── A07.py
├── A08.py
├── A09.py
├── A10.py
├── A11.py
├── data
│ └── NAH1_pivoted.xlsx
└── problem_set_3.ipynb
├── PS4
├── A1.py
├── A2.py
├── A3.py
├── A4.py
├── A5.py
├── A6.py
├── data
│ ├── bm010_ejer.xlsx
│ ├── bm010_ejer_nedtagning.xlsx
│ ├── bm010_parcel.xlsx
│ └── bm010_parcel_nedtagning.xlsx
└── problem_set_4.ipynb
├── PS5
├── A1.py
├── A2.py
├── A3.py
├── A4.py
├── A5.py
└── problem_set_5.ipynb
├── PS6
├── A1.py
├── A10.py
├── A2.py
├── A3.py
├── A4.py
├── A5.py
├── A6.py
├── A7.py
├── A8.py
├── A9.py
├── numecon_linalg.py
└── problem_set_6.ipynb
├── PS7
├── A1.py
├── A10.py
├── A11.py
├── A12.py
├── A13.py
├── A14.py
├── A2.py
├── A3.py
├── A4.py
├── A5.py
├── A6.py
├── A7.py
├── A8.py
├── A9.py
├── contourplot.png
├── problem_set_7.ipynb
└── surfaceplot.png
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 | MANIFEST
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 | .pytest_cache/
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 | local_settings.py
57 | db.sqlite3
58 |
59 | # Flask stuff:
60 | instance/
61 | .webassets-cache
62 |
63 | # Scrapy stuff:
64 | .scrapy
65 |
66 | # Sphinx documentation
67 | docs/_build/
68 |
69 | # PyBuilder
70 | target/
71 |
72 | # Jupyter Notebook
73 | .ipynb_checkpoints
74 |
75 | # pyenv
76 | .python-version
77 |
78 | # celery beat schedule file
79 | celerybeat-schedule
80 |
81 | # SageMath parsed files
82 | *.sage.py
83 |
84 | # Environments
85 | .env
86 | .venv
87 | env/
88 | venv/
89 | ENV/
90 | env.bak/
91 | venv.bak/
92 |
93 | # Spyder project settings
94 | .spyderproject
95 | .spyproject
96 |
97 | # Rope project settings
98 | .ropeproject
99 |
100 | # mkdocs documentation
101 | /site
102 |
103 | # mypy
104 | .mypy_cache/
105 |
106 | # data
107 | *.p
108 | *.npz
109 |
110 | # lyx
111 | *.lyx~
--------------------------------------------------------------------------------
/Central Python concepts.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Some central Python concepts"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "**Table of contents** \n",
15 | "- 1. [Imports](#toc1_) \n",
16 | "- 2. [References](#toc2_) \n",
17 | "- 3. [Mutables and in-place operations](#toc3_) \n",
18 | "- 4. [Functions - scope and side-effects](#toc4_) \n",
19 | "- 5. [Looping](#toc5_) \n",
20 | "- 6. [Floating point arithmetics](#toc6_) \n",
21 | "- 7. [Random numbers](#toc7_) \n",
22 | "- 8. [Classes](#toc8_) \n",
23 | " - 8.1. [Operators](#toc8_1_) \n",
24 | " - 8.2. [MyList](#toc8_2_) \n",
25 | "\n",
26 | "\n",
33 | ""
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "## 1. [Imports](#toc0_)"
41 | ]
42 | },
43 | {
44 | "cell_type": "code",
45 | "execution_count": 1,
46 | "metadata": {},
47 | "outputs": [],
48 | "source": [
49 | "import numpy as np"
50 | ]
51 | },
52 | {
53 | "cell_type": "markdown",
54 | "metadata": {},
55 | "source": [
56 | "## 2. [References](#toc0_)"
57 | ]
58 | },
59 | {
60 | "cell_type": "code",
61 | "execution_count": 2,
62 | "metadata": {},
63 | "outputs": [
64 | {
65 | "name": "stdout",
66 | "output_type": "stream",
67 | "text": [
68 | "a = array([3, 3, 3])\n"
69 | ]
70 | }
71 | ],
72 | "source": [
73 | "a = np.array([1,2,3]) # creates a new array -> stores reference to it\n",
74 | "b = a # copy the reference\n",
75 | "c = a[1:] # slice -> new reference to sub-array\n",
76 | "b[0] = 3 # set element with index \n",
77 | "c[0] = 3\n",
78 | "print(f'{a = }')"
79 | ]
80 | },
81 | {
82 | "cell_type": "markdown",
83 | "metadata": {},
84 | "source": [
85 | "With a `list`, a slice creates a copy:"
86 | ]
87 | },
88 | {
89 | "cell_type": "code",
90 | "execution_count": 3,
91 | "metadata": {},
92 | "outputs": [
93 | {
94 | "name": "stdout",
95 | "output_type": "stream",
96 | "text": [
97 | "a = [3, 2, 3]\n",
98 | "c = [3, 3]\n"
99 | ]
100 | }
101 | ],
102 | "source": [
103 | "a = [1,2,3]\n",
104 | "b = a\n",
105 | "c = a[1:]\n",
106 | "b[0] = 3\n",
107 | "c[0] = 3\n",
108 | "print(f'{a = }')\n",
109 | "print(f'{c = }')"
110 | ]
111 | },
112 | {
113 | "cell_type": "markdown",
114 | "metadata": {},
115 | "source": [
116 | "## 3. [Mutables and in-place operations](#toc0_)"
117 | ]
118 | },
119 | {
120 | "cell_type": "code",
121 | "execution_count": 4,
122 | "metadata": {},
123 | "outputs": [
124 | {
125 | "name": "stdout",
126 | "output_type": "stream",
127 | "text": [
128 | "y = array([3, 4, 5])\n",
129 | "x = array([4, 5, 6])\n"
130 | ]
131 | }
132 | ],
133 | "source": [
134 | "x = np.array([1,2,3])\n",
135 | "y = x\n",
136 | "x += 1 # 2,3,4\n",
137 | "x[:] = x + 1 # 3,4,5\n",
138 | "x = x + 1 # 4,5,6 ?\n",
139 | "print(f'{y = }')\n",
140 | "print(f'{x = }')"
141 | ]
142 | },
143 | {
144 | "cell_type": "markdown",
145 | "metadata": {},
146 | "source": [
147 | "## 4. [Functions - scope and side-effects](#toc0_)"
148 | ]
149 | },
150 | {
151 | "cell_type": "code",
152 | "execution_count": 5,
153 | "metadata": {},
154 | "outputs": [
155 | {
156 | "name": "stdout",
157 | "output_type": "stream",
158 | "text": [
159 | "f(1) = 2\n",
160 | "f(1) = 3\n"
161 | ]
162 | }
163 | ],
164 | "source": [
165 | "a = 1\n",
166 | "\n",
167 | "def f(x):\n",
168 | "\treturn x+a\n",
169 | "\n",
170 | "print(f'{f(1) = }')\n",
171 | "a = 2\n",
172 | "print(f'{f(1) = }') # same line new output"
173 | ]
174 | },
175 | {
176 | "cell_type": "code",
177 | "execution_count": 6,
178 | "metadata": {},
179 | "outputs": [
180 | {
181 | "name": "stdout",
182 | "output_type": "stream",
183 | "text": [
184 | "f(1,a) = 2\n",
185 | "f(1,a) = 3\n"
186 | ]
187 | }
188 | ],
189 | "source": [
190 | "a = np.array([1])\n",
191 | "\n",
192 | "def f(x,a):\n",
193 | "\ty = x+a[0]\n",
194 | "\ta += 1 # side-effect\n",
195 | "\treturn y\n",
196 | "\n",
197 | "print(f'{f(1,a) = }')\n",
198 | "print(f'{f(1,a) = }') # same line new output"
199 | ]
200 | },
201 | {
202 | "cell_type": "markdown",
203 | "metadata": {},
204 | "source": [
205 | "## 5. [Looping](#toc0_)"
206 | ]
207 | },
208 | {
209 | "cell_type": "code",
210 | "execution_count": 7,
211 | "metadata": {},
212 | "outputs": [],
213 | "source": [
214 | "evaluate = lambda x: np.nan\n",
215 | "check = lambda x: False\n",
216 | "update = lambda x,y: np.nan "
217 | ]
218 | },
219 | {
220 | "cell_type": "code",
221 | "execution_count": 8,
222 | "metadata": {},
223 | "outputs": [],
224 | "source": [
225 | "n = 10\n",
226 | "x0 = np.nan"
227 | ]
228 | },
229 | {
230 | "cell_type": "code",
231 | "execution_count": 9,
232 | "metadata": {},
233 | "outputs": [
234 | {
235 | "name": "stdout",
236 | "output_type": "stream",
237 | "text": [
238 | "did not converge\n"
239 | ]
240 | }
241 | ],
242 | "source": [
243 | "try:\n",
244 | "\n",
245 | " x = x0\n",
246 | " for i in range(n):\n",
247 | " y = evaluate(x)\n",
248 | " if check(y): break\n",
249 | " x = update(x,y)\n",
250 | " else:\n",
251 | " raise ValueError('did not converge')\n",
252 | " \n",
253 | "except ValueError as e:\n",
254 | " \n",
255 | " print(e) "
256 | ]
257 | },
258 | {
259 | "cell_type": "code",
260 | "execution_count": 10,
261 | "metadata": {},
262 | "outputs": [
263 | {
264 | "name": "stdout",
265 | "output_type": "stream",
266 | "text": [
267 | "did not converge\n"
268 | ]
269 | }
270 | ],
271 | "source": [
272 | "try:\n",
273 | "\n",
274 | " x = x0\n",
275 | " i = 0\n",
276 | " \n",
277 | " while True:\n",
278 | "\n",
279 | " y = evaluate(x)\n",
280 | " if check(y): break\n",
281 | " x = update(x,y)\n",
282 | " i += 1\n",
283 | " if i >= n: raise ValueError('did not converge')\n",
284 | " \n",
285 | "except ValueError as e:\n",
286 | "\n",
287 | " print(e) "
288 | ]
289 | },
290 | {
291 | "cell_type": "markdown",
292 | "metadata": {},
293 | "source": [
294 | "## 6. [Floating point arithmetics](#toc0_)"
295 | ]
296 | },
297 | {
298 | "cell_type": "code",
299 | "execution_count": 11,
300 | "metadata": {},
301 | "outputs": [
302 | {
303 | "name": "stdout",
304 | "output_type": "stream",
305 | "text": [
306 | "0.1 + 0.2 == 0.3 = False\n",
307 | "0.5 + 0.5 == 1.0 = True\n",
308 | "np.isclose(0.1+0.2,0.3) = True\n",
309 | "np.isclose(1e-200*1e200*1e200*1e-200,1.0) = True\n",
310 | "np.isinf(1e-200*(1e200*1e200)*1e-200) = True\n",
311 | "np.isclose(1e200*(1e-200*1e-200)*1e200,0.0) = True\n"
312 | ]
313 | }
314 | ],
315 | "source": [
316 | "print(f'{0.1 + 0.2 == 0.3 = }')\n",
317 | "print(f'{0.5 + 0.5 == 1.0 = }')\n",
318 | "print(f'{np.isclose(0.1+0.2,0.3) = }')\n",
319 | "print(f'{np.isclose(1e-200*1e200*1e200*1e-200,1.0) = }')\n",
320 | "print(f'{np.isinf(1e-200*(1e200*1e200)*1e-200) = }')\n",
321 | "print(f'{np.isclose(1e200*(1e-200*1e-200)*1e200,0.0) = }')"
322 | ]
323 | },
324 | {
325 | "cell_type": "markdown",
326 | "metadata": {},
327 | "source": [
328 | "## 7. [Random numbers](#toc0_)"
329 | ]
330 | },
331 | {
332 | "cell_type": "code",
333 | "execution_count": 12,
334 | "metadata": {},
335 | "outputs": [
336 | {
337 | "name": "stdout",
338 | "output_type": "stream",
339 | "text": [
340 | "x = array([-0.98912135, -0.36778665, 1.28792526, 0.19397442, 0.9202309 ])\n",
341 | "y = array([ 0.57710379, -0.63646365, 0.54195222, -0.31659545, -0.32238912])\n",
342 | "z = array([-0.98912135, -0.36778665, 1.28792526, 0.19397442, 0.9202309 ])\n"
343 | ]
344 | }
345 | ],
346 | "source": [
347 | "rng = np.random.default_rng(123)\n",
348 | "s = rng.bit_generator.state\n",
349 | "\n",
350 | "x = rng.normal(size=5)\n",
351 | "y = rng.normal(size=5)\n",
352 | "\n",
353 | "rng.bit_generator.state = s\n",
354 | "z = rng.normal(size=5)\n",
355 | "\n",
356 | "print(f'{x = }')\n",
357 | "print(f'{y = }')\n",
358 | "print(f'{z = }')"
359 | ]
360 | },
361 | {
362 | "cell_type": "markdown",
363 | "metadata": {},
364 | "source": [
365 | "## 8. [Classes](#toc0_)"
366 | ]
367 | },
368 | {
369 | "cell_type": "markdown",
370 | "metadata": {},
371 | "source": [
372 | "### 8.1. [Operators](#toc0_)"
373 | ]
374 | },
375 | {
376 | "cell_type": "code",
377 | "execution_count": 13,
378 | "metadata": {},
379 | "outputs": [],
380 | "source": [
381 | "class SquareClass:\n",
382 | " \n",
383 | " def __init__(self,length,width):\n",
384 | " \n",
385 | " self.length = length\n",
386 | " self.width = width\n",
387 | "\n",
388 | " def size(self):\n",
389 | "\n",
390 | " return self.length*self.width\n",
391 | " \n",
392 | " def __add__(self,other):\n",
393 | "\n",
394 | " return SquareClass(\n",
395 | " length=self.length+other.length,\n",
396 | " width=self.width+other.width\n",
397 | " )\n",
398 | " \n",
399 | " # def __mul__(self,other):\n",
400 | " \n",
401 | " # return SquareClass(\n",
402 | " # length=self.length*other.length,\n",
403 | " # width=self.width*other.width\n",
404 | " # )\n",
405 | " \n",
406 | " def __str__(self):\n",
407 | "\n",
408 | " return f'length = {self.length}, width = {self.width}: size = {self.size()}'\n"
409 | ]
410 | },
411 | {
412 | "cell_type": "code",
413 | "execution_count": 14,
414 | "metadata": {},
415 | "outputs": [
416 | {
417 | "name": "stdout",
418 | "output_type": "stream",
419 | "text": [
420 | "length = 2, width = 2: size = 4\n"
421 | ]
422 | }
423 | ],
424 | "source": [
425 | "square = SquareClass (2,2)\n",
426 | "print(square)"
427 | ]
428 | },
429 | {
430 | "cell_type": "code",
431 | "execution_count": 15,
432 | "metadata": {},
433 | "outputs": [
434 | {
435 | "name": "stdout",
436 | "output_type": "stream",
437 | "text": [
438 | "length = 5, width = 5: size = 25\n"
439 | ]
440 | }
441 | ],
442 | "source": [
443 | "newsquare = square + SquareClass(3,3)\n",
444 | "print(newsquare)"
445 | ]
446 | },
447 | {
448 | "cell_type": "code",
449 | "execution_count": 16,
450 | "metadata": {},
451 | "outputs": [
452 | {
453 | "name": "stdout",
454 | "output_type": "stream",
455 | "text": [
456 | "unsupported operand type(s) for *: 'SquareClass' and 'SquareClass'\n"
457 | ]
458 | }
459 | ],
460 | "source": [
461 | "try:\n",
462 | " newsquare = square * SquareClass(3,3)\n",
463 | " print(newsquare)\n",
464 | "except TypeError as e:\n",
465 | " print(e)"
466 | ]
467 | },
468 | {
469 | "cell_type": "markdown",
470 | "metadata": {},
471 | "source": [
472 | "### 8.2. [MyList](#toc0_)"
473 | ]
474 | },
475 | {
476 | "cell_type": "code",
477 | "execution_count": 17,
478 | "metadata": {},
479 | "outputs": [],
480 | "source": [
481 | "class MyObject():\n",
482 | " \n",
483 | " def __init__(self,value):\n",
484 | "\n",
485 | " self.value = value\n",
486 | " self.next = None\n",
487 | "\n",
488 | "class MyList():\n",
489 | "\n",
490 | " def __init__(self):\n",
491 | "\n",
492 | " self.head = None\n",
493 | " self.cur = None\n",
494 | "\n",
495 | " def append(self,value):\n",
496 | "\n",
497 | " if self.head is None:\n",
498 | " self.head = self.cur = MyObject(value)\n",
499 | " else:\n",
500 | " self.cur.next = MyObject(value)\n",
501 | " self.cur = self.cur.next\n",
502 | "\n",
503 | " def __getitem__(self,index):\n",
504 | "\n",
505 | " cur = self.head\n",
506 | " for _ in range(index):\n",
507 | " cur = cur.next\n",
508 | "\n",
509 | " return cur\n",
510 | "\n",
511 | " def __iter__(self):\n",
512 | "\n",
513 | " self.cur = self.head\n",
514 | " return self\n",
515 | "\n",
516 | " def __next__(self):\n",
517 | "\n",
518 | " if self.cur is None: raise StopIteration\n",
519 | "\n",
520 | " cur = self.cur\n",
521 | " self.cur = self.cur.next\n",
522 | " return cur"
523 | ]
524 | },
525 | {
526 | "cell_type": "code",
527 | "execution_count": 18,
528 | "metadata": {},
529 | "outputs": [
530 | {
531 | "name": "stdout",
532 | "output_type": "stream",
533 | "text": [
534 | "indexing:\n",
535 | "x[2].value = 'c'\n",
536 | "\n",
537 | "iteration:\n",
538 | "x[0] = a\n",
539 | "x[1] = 2\n",
540 | "x[2] = c\n",
541 | "x[3] = ('d', 4)\n"
542 | ]
543 | }
544 | ],
545 | "source": [
546 | "x = MyList()\n",
547 | "x.append('a')\n",
548 | "x.append(2)\n",
549 | "x.append('c')\n",
550 | "x.append(('d',4))\n",
551 | "\n",
552 | "print('indexing:')\n",
553 | "print(f'{x[2].value = }')\n",
554 | "print('')\n",
555 | "print('iteration:')\n",
556 | "for i,obj in enumerate(x):\n",
557 | " print(f'x[{i}] = {obj.value}')"
558 | ]
559 | }
560 | ],
561 | "metadata": {
562 | "kernelspec": {
563 | "display_name": "base",
564 | "language": "python",
565 | "name": "python3"
566 | },
567 | "language_info": {
568 | "codemirror_mode": {
569 | "name": "ipython",
570 | "version": 3
571 | },
572 | "file_extension": ".py",
573 | "mimetype": "text/x-python",
574 | "name": "python",
575 | "nbconvert_exporter": "python",
576 | "pygments_lexer": "ipython3",
577 | "version": "3.11.5"
578 | }
579 | },
580 | "nbformat": 4,
581 | "nbformat_minor": 2
582 | }
583 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 NumEconCopenhagen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/PS0/problem set 0.lyx:
--------------------------------------------------------------------------------
1 | #LyX 2.3 created this file. For more info see http://www.lyx.org/
2 | \lyxformat 544
3 | \begin_document
4 | \begin_header
5 | \save_transient_properties true
6 | \origin unavailable
7 | \textclass article
8 | \begin_preamble
9 | \usepackage{hyperref}
10 | \hypersetup{colorlinks=true,urlcolor=blue}
11 | \date{}
12 |
13 | \usepackage{xcolor}
14 | \usepackage{listings}
15 |
16 | \definecolor{codegray}{rgb}{0.5,0.5,0.5}
17 | \definecolor{background}{HTML}{F5F5F5}
18 | \definecolor{keyword}{HTML}{4B69C6}
19 | \definecolor{string}{HTML}{448C27}
20 | \definecolor{comment}{HTML}{448C27}
21 |
22 | \usepackage{inconsolata}
23 | \lstdefinestyle{mystyle}{
24 | commentstyle=\color{comment},
25 | keywordstyle=\color{keyword},
26 | stringstyle=\color{string},
27 | basicstyle=\ttfamily,
28 | breakatwhitespace=false,
29 | breaklines=true,
30 | captionpos=b,
31 | keepspaces=true,
32 | numbersep=5pt,
33 | showspaces=false,
34 | showstringspaces=false,
35 | showtabs=false,
36 | tabsize=4,
37 | showlines=true
38 | }
39 |
40 | \lstset{style=mystyle}
41 | \end_preamble
42 | \use_default_options true
43 | \maintain_unincluded_children false
44 | \language english
45 | \language_package default
46 | \inputencoding auto
47 | \fontencoding global
48 | \font_roman "lmodern" "default"
49 | \font_sans "default" "default"
50 | \font_typewriter "default" "default"
51 | \font_math "auto" "auto"
52 | \font_default_family default
53 | \use_non_tex_fonts false
54 | \font_sc false
55 | \font_osf false
56 | \font_sf_scale 100 100
57 | \font_tt_scale 100 100
58 | \use_microtype false
59 | \use_dash_ligatures false
60 | \graphics default
61 | \default_output_format default
62 | \output_sync 0
63 | \bibtex_command default
64 | \index_command default
65 | \float_placement H
66 | \paperfontsize 11
67 | \spacing single
68 | \use_hyperref false
69 | \papersize default
70 | \use_geometry true
71 | \use_package amsmath 1
72 | \use_package amssymb 1
73 | \use_package cancel 1
74 | \use_package esint 1
75 | \use_package mathdots 0
76 | \use_package mathtools 1
77 | \use_package mhchem 1
78 | \use_package stackrel 1
79 | \use_package stmaryrd 1
80 | \use_package undertilde 1
81 | \cite_engine natbib
82 | \cite_engine_type authoryear
83 | \biblio_style plainnat
84 | \use_bibtopic false
85 | \use_indices false
86 | \paperorientation portrait
87 | \suppress_date false
88 | \justification true
89 | \use_refstyle 0
90 | \use_minted 0
91 | \index Index
92 | \shortcut idx
93 | \color #008000
94 | \end_index
95 | \leftmargin 3cm
96 | \topmargin 3cm
97 | \rightmargin 3cm
98 | \bottommargin 3cm
99 | \secnumdepth 3
100 | \tocdepth 3
101 | \paragraph_separation skip
102 | \defskip smallskip
103 | \is_math_indent 0
104 | \math_numbering_side default
105 | \quotes_style english
106 | \dynamic_quotes 0
107 | \papercolumns 1
108 | \papersides 1
109 | \paperpagestyle empty
110 | \tracking_changes false
111 | \output_changes false
112 | \html_math_output 0
113 | \html_css_as_file 0
114 | \html_be_strict false
115 | \end_header
116 |
117 | \begin_body
118 |
119 | \begin_layout Title
120 |
121 | \shape smallcaps
122 | \size largest
123 | Problem Set 0: Getting Started
124 | \end_layout
125 |
126 | \begin_layout Standard
127 | \begin_inset ERT
128 | status open
129 |
130 | \begin_layout Plain Layout
131 |
132 |
133 | \backslash
134 | vspace{-3mm}
135 | \backslash
136 | thispagestyle{empty}
137 | \end_layout
138 |
139 | \end_inset
140 |
141 |
142 | \end_layout
143 |
144 | \begin_layout Standard
145 |
146 | \series bold
147 | Installation:
148 | \series default
149 | Go through the following installation and getting started steps:
150 | \end_layout
151 |
152 | \begin_layout Enumerate
153 |
154 | \series bold
155 | Installation:
156 | \series default
157 | Follow the
158 | \begin_inset CommandInset href
159 | LatexCommand href
160 | name "intallation guide"
161 | target "https://sites.google.com/view/numeconcph-introprog/guides/installation"
162 | literal "false"
163 |
164 | \end_inset
165 |
166 | for
167 | \emph on
168 | Anaconda
169 | \emph default
170 | ,
171 | \emph on
172 | git
173 | \emph default
174 | and
175 | \emph on
176 | VSCode.
177 | \end_layout
178 |
179 | \begin_layout Enumerate
180 |
181 | \series bold
182 | VSCode+Jupyter:
183 | \series default
184 | Create a
185 | \emph on
186 | Jupyter Notebook
187 | \emph default
188 | in
189 | \emph on
190 | VSCode.
191 |
192 | \emph default
193 |
194 | \begin_inset Newline newline
195 | \end_inset
196 |
197 | Copy in the code below and run it.
198 | \end_layout
199 |
200 | \begin_deeper
201 | \begin_layout Standard
202 | \begin_inset ERT
203 | status open
204 |
205 | \begin_layout Plain Layout
206 |
207 |
208 | \backslash
209 | begin{lstlisting}[language=Python,basicstyle=
210 | \backslash
211 | linespread{1.3}
212 | \backslash
213 | ttfamily
214 | \backslash
215 | footnotesize,numbers=left,frame=single,backgroundcolor=
216 | \backslash
217 | color{background}]
218 | \end_layout
219 |
220 | \begin_layout Plain Layout
221 |
222 | a = 1
223 | \end_layout
224 |
225 | \begin_layout Plain Layout
226 |
227 | b = 2
228 | \end_layout
229 |
230 | \begin_layout Plain Layout
231 |
232 | c = a + b
233 | \end_layout
234 |
235 | \begin_layout Plain Layout
236 |
237 | print(c)
238 | \end_layout
239 |
240 | \begin_layout Plain Layout
241 |
242 |
243 | \backslash
244 | end{lstlisting}
245 | \end_layout
246 |
247 | \end_inset
248 |
249 |
250 | \end_layout
251 |
252 | \end_deeper
253 | \begin_layout Enumerate
254 |
255 | \series bold
256 | More VSCode:
257 | \series default
258 | Try out the tips for
259 | \emph on
260 | VSCode
261 | \emph default
262 | found
263 | \begin_inset CommandInset href
264 | LatexCommand href
265 | name "here"
266 | target "https://sites.google.com/view/numeconcph-introprog/guides/vscode"
267 | literal "false"
268 |
269 | \end_inset
270 |
271 | .
272 | \begin_inset Newline newline
273 | \end_inset
274 |
275 | (creating the
276 | \emph on
277 | Restart-and-Run-All
278 | \emph default
279 | short cut will be very useful)
280 | \end_layout
281 |
282 | \begin_layout Enumerate
283 |
284 | \series bold
285 | Git:
286 | \series default
287 | Download the course content from
288 | \emph on
289 | VSCode
290 | \emph default
291 | using
292 | \emph on
293 | git
294 | \emph default
295 | as explained
296 | \begin_inset CommandInset href
297 | LatexCommand href
298 | name "here"
299 | target "https://sites.google.com/view/numeconcph-introprog/guides/git"
300 | literal "false"
301 |
302 | \end_inset
303 |
304 | .
305 | \end_layout
306 |
307 | \begin_layout Standard
308 |
309 | \series bold
310 | Understanding code:
311 | \series default
312 | Consider the code snippets below.
313 | For each, write down your expected outcome on paper.
314 | Run the code and check whether you were correct.
315 |
316 | \end_layout
317 |
318 | \begin_layout Itemize
319 |
320 | \series bold
321 | slicing
322 | \end_layout
323 |
324 | \begin_deeper
325 | \begin_layout Standard
326 | \begin_inset ERT
327 | status open
328 |
329 | \begin_layout Plain Layout
330 |
331 |
332 | \backslash
333 | begin{lstlisting}[language=Python,basicstyle=
334 | \backslash
335 | linespread{1.3}
336 | \backslash
337 | ttfamily
338 | \backslash
339 | footnotesize,numbers=left,frame=single,backgroundcolor=
340 | \backslash
341 | color{background}]
342 | \end_layout
343 |
344 | \begin_layout Plain Layout
345 |
346 | x = [0,1,2,3,4,5]
347 | \end_layout
348 |
349 | \begin_layout Plain Layout
350 |
351 | print(x[:2])
352 | \end_layout
353 |
354 | \begin_layout Plain Layout
355 |
356 | print(x[2:])
357 | \end_layout
358 |
359 | \begin_layout Plain Layout
360 |
361 |
362 | \backslash
363 | end{lstlisting}
364 | \end_layout
365 |
366 | \end_inset
367 |
368 |
369 | \end_layout
370 |
371 | \end_deeper
372 | \begin_layout Itemize
373 |
374 | \series bold
375 | references
376 | \end_layout
377 |
378 | \begin_deeper
379 | \begin_layout Standard
380 | \begin_inset ERT
381 | status open
382 |
383 | \begin_layout Plain Layout
384 |
385 |
386 | \backslash
387 | begin{lstlisting}[language=Python,basicstyle=
388 | \backslash
389 | linespread{1.3}
390 | \backslash
391 | ttfamily
392 | \backslash
393 | footnotesize,numbers=left,frame=single,backgroundcolor=
394 | \backslash
395 | color{background}]
396 | \end_layout
397 |
398 | \begin_layout Plain Layout
399 |
400 | x = [1,2,3]
401 | \end_layout
402 |
403 | \begin_layout Plain Layout
404 |
405 | y = x
406 | \end_layout
407 |
408 | \begin_layout Plain Layout
409 |
410 | y[-1] = 4
411 | \end_layout
412 |
413 | \begin_layout Plain Layout
414 |
415 | print(x)
416 | \end_layout
417 |
418 | \begin_layout Plain Layout
419 |
420 |
421 | \backslash
422 | end{lstlisting}
423 | \end_layout
424 |
425 | \end_inset
426 |
427 |
428 | \end_layout
429 |
430 | \end_deeper
431 | \begin_layout Itemize
432 |
433 | \series bold
434 | loops - break
435 | \end_layout
436 |
437 | \begin_deeper
438 | \begin_layout Standard
439 | \begin_inset ERT
440 | status open
441 |
442 | \begin_layout Plain Layout
443 |
444 |
445 | \backslash
446 | begin{lstlisting}[language=Python,basicstyle=
447 | \backslash
448 | linespread{1.3}
449 | \backslash
450 | ttfamily
451 | \backslash
452 | footnotesize,numbers=left,frame=single,backgroundcolor=
453 | \backslash
454 | color{background}]
455 | \end_layout
456 |
457 | \begin_layout Plain Layout
458 |
459 | for i in range(5):
460 | \end_layout
461 |
462 | \begin_layout Plain Layout
463 |
464 | if i >= 2: break
465 | \end_layout
466 |
467 | \begin_layout Plain Layout
468 |
469 | print(i)
470 | \end_layout
471 |
472 | \begin_layout Plain Layout
473 |
474 |
475 | \backslash
476 | end{lstlisting}
477 | \end_layout
478 |
479 | \end_inset
480 |
481 |
482 | \end_layout
483 |
484 | \end_deeper
485 | \begin_layout Standard
486 | \begin_inset Newpage newpage
487 | \end_inset
488 |
489 |
490 | \end_layout
491 |
492 | \begin_layout Itemize
493 |
494 | \series bold
495 | loops - continue
496 | \end_layout
497 |
498 | \begin_deeper
499 | \begin_layout Standard
500 | \begin_inset ERT
501 | status open
502 |
503 | \begin_layout Plain Layout
504 |
505 |
506 | \backslash
507 | begin{lstlisting}[language=Python,basicstyle=
508 | \backslash
509 | linespread{1.3}
510 | \backslash
511 | ttfamily
512 | \backslash
513 | footnotesize,numbers=left,frame=single,backgroundcolor=
514 | \backslash
515 | color{background}]
516 | \end_layout
517 |
518 | \begin_layout Plain Layout
519 |
520 | for i in range(5):
521 | \end_layout
522 |
523 | \begin_layout Plain Layout
524 |
525 | if i == 2: continue
526 | \end_layout
527 |
528 | \begin_layout Plain Layout
529 |
530 | print(i)
531 | \end_layout
532 |
533 | \begin_layout Plain Layout
534 |
535 |
536 | \backslash
537 | end{lstlisting}
538 | \end_layout
539 |
540 | \end_inset
541 |
542 |
543 | \end_layout
544 |
545 | \end_deeper
546 | \begin_layout Itemize
547 |
548 | \series bold
549 | conditionals
550 | \end_layout
551 |
552 | \begin_deeper
553 | \begin_layout Standard
554 | \begin_inset ERT
555 | status open
556 |
557 | \begin_layout Plain Layout
558 |
559 |
560 | \backslash
561 | begin{lstlisting}[language=Python,basicstyle=
562 | \backslash
563 | linespread{1.3}
564 | \backslash
565 | ttfamily
566 | \backslash
567 | footnotesize,numbers=left,frame=single,backgroundcolor=
568 | \backslash
569 | color{background}]
570 | \end_layout
571 |
572 | \begin_layout Plain Layout
573 |
574 | x = 3
575 | \end_layout
576 |
577 | \begin_layout Plain Layout
578 |
579 | if x > 3:
580 | \end_layout
581 |
582 | \begin_layout Plain Layout
583 |
584 | print('too big')
585 | \end_layout
586 |
587 | \begin_layout Plain Layout
588 |
589 | elif x < 1:
590 | \end_layout
591 |
592 | \begin_layout Plain Layout
593 |
594 | print('too small')
595 | \end_layout
596 |
597 | \begin_layout Plain Layout
598 |
599 | else:
600 | \end_layout
601 |
602 | \begin_layout Plain Layout
603 |
604 | print('just right')
605 | \end_layout
606 |
607 | \begin_layout Plain Layout
608 |
609 |
610 | \end_layout
611 |
612 | \begin_layout Plain Layout
613 |
614 |
615 | \backslash
616 | end{lstlisting}
617 | \end_layout
618 |
619 | \end_inset
620 |
621 |
622 | \end_layout
623 |
624 | \end_deeper
625 | \begin_layout Itemize
626 |
627 | \series bold
628 | functions and scope
629 | \end_layout
630 |
631 | \begin_deeper
632 | \begin_layout Standard
633 | \begin_inset ERT
634 | status open
635 |
636 | \begin_layout Plain Layout
637 |
638 |
639 | \backslash
640 | begin{lstlisting}[language=Python,basicstyle=
641 | \backslash
642 | linespread{1.3}
643 | \backslash
644 | ttfamily
645 | \backslash
646 | footnotesize,numbers=left,frame=single,backgroundcolor=
647 | \backslash
648 | color{background}]
649 | \end_layout
650 |
651 | \begin_layout Plain Layout
652 |
653 | a = 1
654 | \end_layout
655 |
656 | \begin_layout Plain Layout
657 |
658 | def f(x):
659 | \end_layout
660 |
661 | \begin_layout Plain Layout
662 |
663 | return x+a # a is global variable
664 | \end_layout
665 |
666 | \begin_layout Plain Layout
667 |
668 | def g(x,a=1):
669 | \end_layout
670 |
671 | \begin_layout Plain Layout
672 |
673 | return x+a # a is local variable
674 | \end_layout
675 |
676 | \begin_layout Plain Layout
677 |
678 | print(f(1))
679 | \end_layout
680 |
681 | \begin_layout Plain Layout
682 |
683 | print(g(1))
684 | \end_layout
685 |
686 | \begin_layout Plain Layout
687 |
688 | a = 2
689 | \end_layout
690 |
691 | \begin_layout Plain Layout
692 |
693 | print(f(1))
694 | \end_layout
695 |
696 | \begin_layout Plain Layout
697 |
698 | print(g(1))
699 | \end_layout
700 |
701 | \begin_layout Plain Layout
702 |
703 |
704 | \backslash
705 | end{lstlisting}
706 | \end_layout
707 |
708 | \end_inset
709 |
710 |
711 | \end_layout
712 |
713 | \end_deeper
714 | \begin_layout Itemize
715 |
716 | \series bold
717 | floating points
718 | \end_layout
719 |
720 | \begin_deeper
721 | \begin_layout Standard
722 | \begin_inset ERT
723 | status open
724 |
725 | \begin_layout Plain Layout
726 |
727 |
728 | \backslash
729 | begin{lstlisting}[language=Python,basicstyle=
730 | \backslash
731 | linespread{1.3}
732 | \backslash
733 | ttfamily
734 | \backslash
735 | footnotesize,numbers=left,frame=single,backgroundcolor=
736 | \backslash
737 | color{background}]
738 | \end_layout
739 |
740 | \begin_layout Plain Layout
741 |
742 | import numpy as np
743 | \end_layout
744 |
745 | \begin_layout Plain Layout
746 |
747 | print(0.1 + 0.2 == 0.3)
748 | \end_layout
749 |
750 | \begin_layout Plain Layout
751 |
752 | print(0.5 + 0.5 == 1.0)
753 | \end_layout
754 |
755 | \begin_layout Plain Layout
756 |
757 | print(np.isclose(0.1+0.2,0.3))
758 | \end_layout
759 |
760 | \begin_layout Plain Layout
761 |
762 | print(np.isclose(1e-200*1e200*1e200*1e-200,1.0))
763 | \end_layout
764 |
765 | \begin_layout Plain Layout
766 |
767 | print(np.isinf(1e-200*(1e200*1e200)*1e-200))
768 | \end_layout
769 |
770 | \begin_layout Plain Layout
771 |
772 | print(np.isclose(1e200*(1e-200*1e-200)*1e200,0.0))
773 | \end_layout
774 |
775 | \begin_layout Plain Layout
776 |
777 |
778 | \backslash
779 | end{lstlisting}
780 | \end_layout
781 |
782 | \end_inset
783 |
784 |
785 | \end_layout
786 |
787 | \end_deeper
788 | \begin_layout Standard
789 | \begin_inset Newpage newpage
790 | \end_inset
791 |
792 |
793 | \end_layout
794 |
795 | \begin_layout Itemize
796 |
797 | \series bold
798 | numpy
799 | \end_layout
800 |
801 | \begin_deeper
802 | \begin_layout Standard
803 | \begin_inset ERT
804 | status open
805 |
806 | \begin_layout Plain Layout
807 |
808 |
809 | \backslash
810 | begin{lstlisting}[language=Python,basicstyle=
811 | \backslash
812 | linespread{1.3}
813 | \backslash
814 | ttfamily
815 | \backslash
816 | footnotesize,numbers=left,frame=single,backgroundcolor=
817 | \backslash
818 | color{background}]
819 | \end_layout
820 |
821 | \begin_layout Plain Layout
822 |
823 | import numpy as np
824 | \end_layout
825 |
826 | \begin_layout Plain Layout
827 |
828 | x = np.array([1,2,3])
829 | \end_layout
830 |
831 | \begin_layout Plain Layout
832 |
833 | y = x
834 | \end_layout
835 |
836 | \begin_layout Plain Layout
837 |
838 | x += 1
839 | \end_layout
840 |
841 | \begin_layout Plain Layout
842 |
843 | x[:] = x + 1
844 | \end_layout
845 |
846 | \begin_layout Plain Layout
847 |
848 | x = x + 1
849 | \end_layout
850 |
851 | \begin_layout Plain Layout
852 |
853 | print(y)
854 | \end_layout
855 |
856 | \begin_layout Plain Layout
857 |
858 |
859 | \backslash
860 | end{lstlisting}
861 | \end_layout
862 |
863 | \end_inset
864 |
865 |
866 | \end_layout
867 |
868 | \end_deeper
869 | \begin_layout Itemize
870 |
871 | \series bold
872 | classes
873 | \end_layout
874 |
875 | \begin_deeper
876 | \begin_layout Standard
877 | \begin_inset ERT
878 | status open
879 |
880 | \begin_layout Plain Layout
881 |
882 |
883 | \backslash
884 | begin{lstlisting}[language=Python,basicstyle=
885 | \backslash
886 | linespread{1.3}
887 | \backslash
888 | ttfamily
889 | \backslash
890 | footnotesize,numbers=left,frame=single,backgroundcolor=
891 | \backslash
892 | color{background}]
893 | \end_layout
894 |
895 | \begin_layout Plain Layout
896 |
897 | class SquareClass:
898 | \end_layout
899 |
900 | \begin_layout Plain Layout
901 |
902 | def __init__(self,length,width):
903 | \end_layout
904 |
905 | \begin_layout Plain Layout
906 |
907 | self.length = length
908 | \end_layout
909 |
910 | \begin_layout Plain Layout
911 |
912 | self.width = width
913 | \end_layout
914 |
915 | \begin_layout Plain Layout
916 |
917 | def size(self):
918 | \end_layout
919 |
920 | \begin_layout Plain Layout
921 |
922 | return self.length*self.width
923 | \end_layout
924 |
925 | \begin_layout Plain Layout
926 |
927 | square = SquareClass(2,2)
928 | \end_layout
929 |
930 | \begin_layout Plain Layout
931 |
932 | print(square.size())
933 | \end_layout
934 |
935 | \begin_layout Plain Layout
936 |
937 |
938 | \backslash
939 | end{lstlisting}
940 | \end_layout
941 |
942 | \end_inset
943 |
944 |
945 | \end_layout
946 |
947 | \end_deeper
948 | \end_body
949 | \end_document
950 |
--------------------------------------------------------------------------------
/PS0/problem set 0.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NumEconCopenhagen/IntroProg-exercises/0dee1719691f0f7cccb91cbf2a88f3a0c921fc74/PS0/problem set 0.pdf
--------------------------------------------------------------------------------
/PS1/A1.py:
--------------------------------------------------------------------------------
1 | def u(x1,x2,alpha=0.5,beta=1):
2 | return (alpha*x1**(-beta) + (1-alpha)*x2**(-beta))**(-1/beta)
--------------------------------------------------------------------------------
/PS1/A2.py:
--------------------------------------------------------------------------------
1 | def print_table(x1_vec,x2_vec):
2 |
3 | # a. empty text
4 | text = ''
5 |
6 | # b. top header
7 | text += f'{"":3s}'
8 | for j, x2 in enumerate(x2_vec):
9 | text += f'{j:6d}'
10 | text += '\n' # line shift
11 |
12 | # c. body
13 | for i,x1 in enumerate(x1_vec):
14 | if i > 0:
15 | text += '\n' # line shift
16 | text += f'{i:3d} ' # left header
17 | for j, x2 in enumerate(x2_vec):
18 | text += f'{u(x1,x2):6.3f}'
19 |
20 | # d. print
21 | print(text)
22 |
23 | print_table(x1_vec,x2_vec)
--------------------------------------------------------------------------------
/PS1/A3.py:
--------------------------------------------------------------------------------
1 | # a. plot
2 | fig = plt.figure()
3 | ax = fig.add_subplot(1,1,1,projection='3d')
4 | ax.plot_surface(x1_grid,x2_grid,u_grid,cmap=cm.jet)
5 |
6 | # b. add labels
7 | ax.set_xlabel('$x_1$')
8 | ax.set_ylabel('$x_2$')
9 | ax.set_zlabel('$utility,u$')
10 |
11 | # c. invert xaxis
12 | ax.invert_xaxis()
--------------------------------------------------------------------------------
/PS1/A4.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | # a. define function
4 | def f(x):
5 | return np.sin(x)+0.05*x**2
6 |
7 | # b. solution using a loop
8 | N = 100
9 | x_vec = np.linspace(-10,10,N)
10 | f_vec = np.empty(N)
11 |
12 | f_best = np.inf # initial maximum
13 | x_best = np.nan # not-a-number
14 |
15 | for i,x in enumerate(x_vec):
16 | f_now = f_vec[i] = f(x)
17 | if f_now < f_best:
18 | x_best = x
19 | f_best = f_now
20 |
21 | # c. solution using scipy optmize
22 | from scipy import optimize
23 | x_guess = [0]
24 | objective_function = lambda x: f(x[0])
25 | res = optimize.minimize(objective_function, x_guess, method='Nelder-Mead')
26 | x_best_scipy = res.x[0]
27 | f_best_scipy = res.fun
28 |
29 | # d. print
30 | print(f'best with loop is {f_best:.8f} at x = {x_best:.8f}')
31 | print(f'best with scipy.optimize is {f_best_scipy:.8f} at x = {x_best_scipy:.8f}')
32 |
33 | # e. figure
34 | import matplotlib.pyplot as plt
35 | fig = plt.figure() # dpi = dots-per-inch (resolution)
36 | ax = fig.add_subplot(1,1,1)
37 |
38 | ax.plot(x_vec,f_vec,ls='--',lw=2,color='black',label='$f(x)$')
39 | ax.plot(x_best,f_best,ls='',marker='s',color='blue',label='loop')
40 | ax.plot(x_best_scipy,f_best_scipy,ls='',marker='o',
41 | markersize=10,markerfacecolor='none',
42 | markeredgecolor='red',label='scipy.optimize')
43 |
44 | ax.set_xlabel('$x$')
45 | ax.set_ylabel('$f$')
46 | ax.grid(True)
47 | ax.legend(loc='upper center');
--------------------------------------------------------------------------------
/PS1/A5.py:
--------------------------------------------------------------------------------
1 | N = 15 # number of points in each dimension
2 | fac = np.linspace(0,1,N) # vector betweein 0 and 1
3 | x_max = I/p # maximum x so E = I
4 |
5 | u_best = -np.inf
6 | x_best = np.empty(5)
7 | for x1 in fac:
8 | for x2 in fac:
9 | for x3 in fac:
10 | for x4 in fac:
11 | for x5 in fac:
12 | x = np.array([x1,x2,x3,x4,x5])*x_max
13 | E = expenditures(x,p)
14 | if E <= I:
15 | u_now = utility_function(x,alpha)
16 | if u_now > u_best:
17 | x_best = x
18 | u_best = u_now
19 |
20 | print_solution(x_best,alpha,I,p)
--------------------------------------------------------------------------------
/PS1/A6.py:
--------------------------------------------------------------------------------
1 | import itertools as it
2 |
3 | N = 15 # number of points in each dimension
4 | fac = np.linspace(0,1,N) # vector betweein 0 and 1
5 | x_max = I/p # maximum x so E = I
6 |
7 | x_best = np.empty(5)
8 | u_best = -np.inf
9 | for x in it.product(fac,fac,fac,fac,fac):
10 | x *= x_max
11 | E = expenditures(x,p)
12 | if E <= I:
13 | u_now = utility_function(x,alpha)
14 | if u_now > u_best:
15 | x_best = x
16 | u_best = u_now
17 |
18 | print_solution(x_best,alpha,I,p)
--------------------------------------------------------------------------------
/PS1/A7.py:
--------------------------------------------------------------------------------
1 | # a. contraint function (negative if violated)
2 | constraints = ({'type': 'ineq', 'fun': lambda x: I-expenditures(x,p)})
3 | bounds = [(0,I/p_now) for p_now in p]
4 |
5 | # b. call optimizer
6 | initial_guess = (I/p)/6 # some guess, should be feasible
7 | res = optimize.minimize(
8 | lambda x: -utility_function(x,alpha),initial_guess,
9 | method='SLSQP',bounds=bounds,constraints=constraints)
10 |
11 | print(res.message) # check that the solver has terminated correctly
12 |
13 | # c. print result
14 | print_solution(res.x,alpha,I,p)
--------------------------------------------------------------------------------
/PS1/A8.py:
--------------------------------------------------------------------------------
1 | # a. define objective function
2 | def unconstrained_objective(x,alpha,I,p):
3 |
4 | penalty = 0
5 | E = expenditures(x,p)
6 | if E >= I:
7 | ratio = I/E
8 | x *= ratio # now p*x = I
9 | penalty = 1000*(E-I)**2
10 |
11 | u = utility_function(x,alpha)
12 | return -u + penalty
13 | # note:
14 | # "-u" because we are minimizing
15 | # "+ penalty" because the minimizer
16 | # will then avoid the E > I
17 |
18 | # b. call optimizer
19 | initial_guess = (I/p)/6
20 | res = optimize.minimize(
21 | unconstrained_objective,initial_guess,
22 | method='Nelder-Mead',args=(alpha,I,p),options={'maxiter':5000},tol=1e-10)
23 |
24 | print(res.message)
25 |
26 | # c. print result
27 | print_solution(res.x,alpha,I,p)
--------------------------------------------------------------------------------
/PS1/problem_set_1.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Problem set 1: Solving the consumer problem"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "In this first problem set, we will take a look at solving the canonical utility maximization problem for the consumer. "
15 | ]
16 | },
17 | {
18 | "cell_type": "markdown",
19 | "metadata": {},
20 | "source": [
21 | "**Problem set structure:** \n",
22 | "* Each problem set consists of tasks and problems. _Tasks_ train you in using specific techniques, while _problems_ train you in solving actual economic problems. \n",
23 | "* Each problem set also contains solutions, which can be found in separate Python files.\n",
24 | "* The Python files `A[..].py` do not run out of the box. But you can copy the code into your notebook or user module. \n",
25 | "* *You should really try to solve the tasks and problems on your own before looking at the answers!* \n",
26 | "* You goal should, however, not be to write everything from scratch. \n",
27 | "* Finding similar code from the lectures and adjusting it is completely ok. I rarely begin completely from scratch, I figure out when I last did something similar and copy in the code to begin with. A quick peak at the solution, and then trying to write the solution yourself is also a very beneficial approach."
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {},
33 | "source": [
34 | "**Multiple solutions:** Within the field of numerical analysis there is often many more than one way of solving a specific problem. So the solution provided is just one example. If you get the same result, but use another approach, that might be just as good (or even better)."
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "metadata": {},
40 | "source": [
41 | "**Extra problems:** Solutions to the extra problems are not provided, but we encourage you to take a look at them if you have the time."
42 | ]
43 | },
44 | {
45 | "cell_type": "markdown",
46 | "metadata": {},
47 | "source": [
48 | "# Tasks"
49 | ]
50 | },
51 | {
52 | "cell_type": "markdown",
53 | "metadata": {},
54 | "source": [
55 | "## functions"
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {},
61 | "source": [
62 | "Implement a Python version of this function:"
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {},
68 | "source": [
69 | "$$ \n",
70 | "u(x_1,x_2) = (\\alpha x_1^{-\\beta} + (1-\\alpha) x_2^{-\\beta})^{-1/\\beta} \n",
71 | "$$"
72 | ]
73 | },
74 | {
75 | "cell_type": "code",
76 | "execution_count": null,
77 | "metadata": {},
78 | "outputs": [],
79 | "source": [
80 | "# write your own code here"
81 | ]
82 | },
83 | {
84 | "cell_type": "markdown",
85 | "metadata": {},
86 | "source": [
87 | "**Answer:** see A1.py"
88 | ]
89 | },
90 | {
91 | "cell_type": "markdown",
92 | "metadata": {},
93 | "source": [
94 | "## print"
95 | ]
96 | },
97 | {
98 | "cell_type": "code",
99 | "execution_count": null,
100 | "metadata": {},
101 | "outputs": [],
102 | "source": [
103 | "x1_vec = [1.05,1.3,2.3,2.5,3.1]\n",
104 | "x2_vec = [1.05,1.3,2.3,2.5,3.1]"
105 | ]
106 | },
107 | {
108 | "cell_type": "markdown",
109 | "metadata": {},
110 | "source": [
111 | "Construct a Python function `print_table(x1_vec,x2_vec)` to print values of `u(x1,x2)` in the table form shown below."
112 | ]
113 | },
114 | {
115 | "cell_type": "code",
116 | "execution_count": null,
117 | "metadata": {},
118 | "outputs": [],
119 | "source": [
120 | "# update this code\n",
121 | "\n",
122 | "def print_table(x1_vec,x2_vec):\n",
123 | " \n",
124 | " # a. empty text\n",
125 | " text = ''\n",
126 | " \n",
127 | " # b. top header\n",
128 | " text += f'{\"\":3s}'\n",
129 | " for j, x2 in enumerate(x2_vec):\n",
130 | " text += f'{j:6d}' \n",
131 | " text += '\\n' # line shift\n",
132 | " \n",
133 | " # c. body\n",
134 | " # missing lines\n",
135 | " \n",
136 | " # d. print\n",
137 | " print(text) "
138 | ]
139 | },
140 | {
141 | "cell_type": "markdown",
142 | "metadata": {},
143 | "source": [
144 | "**Answer:** see A2.py"
145 | ]
146 | },
147 | {
148 | "cell_type": "markdown",
149 | "metadata": {},
150 | "source": [
151 | "## matplotlib"
152 | ]
153 | },
154 | {
155 | "cell_type": "markdown",
156 | "metadata": {},
157 | "source": [
158 | "Reproduce the figure below of $u(x_1,x_2)$ using the `meshgrid` function from _numpy_ and the `plot_surface` function from _matplotlib_. "
159 | ]
160 | },
161 | {
162 | "cell_type": "code",
163 | "execution_count": null,
164 | "metadata": {},
165 | "outputs": [],
166 | "source": [
167 | "# import plot modules\n",
168 | "import numpy as np\n",
169 | "%matplotlib inline\n",
170 | "import matplotlib.pyplot as plt\n",
171 | "plt.style.use('seaborn-whitegrid')\n",
172 | "from mpl_toolkits.mplot3d import Axes3D\n",
173 | "from matplotlib import cm # for colormaps"
174 | ]
175 | },
176 | {
177 | "cell_type": "code",
178 | "execution_count": null,
179 | "metadata": {},
180 | "outputs": [],
181 | "source": [
182 | "# evaluate utility function\n",
183 | "x1_grid,x2_grid = np.meshgrid(x1_vec,x2_vec,indexing='ij')\n",
184 | "u_grid = u(x1_grid,x2_grid)\n",
185 | "\n",
186 | "# write your code here"
187 | ]
188 | },
189 | {
190 | "cell_type": "markdown",
191 | "metadata": {},
192 | "source": [
193 | "**Answer:** see A3.py"
194 | ]
195 | },
196 | {
197 | "cell_type": "markdown",
198 | "metadata": {},
199 | "source": [
200 | "## optimize"
201 | ]
202 | },
203 | {
204 | "cell_type": "markdown",
205 | "metadata": {},
206 | "source": [
207 | "Consider the following minimization problem:\n",
208 | "\n",
209 | "$$\n",
210 | "\\min_x f(x) = \\min_x \\sin(x) + 0.05 \\cdot x^2\n",
211 | "$$"
212 | ]
213 | },
214 | {
215 | "cell_type": "markdown",
216 | "metadata": {},
217 | "source": [
218 | "Solve this problem and illustrate your results."
219 | ]
220 | },
221 | {
222 | "cell_type": "code",
223 | "execution_count": null,
224 | "metadata": {},
225 | "outputs": [],
226 | "source": [
227 | "# update this code\n",
228 | "import numpy as np\n",
229 | "\n",
230 | "# a. define function\n",
231 | "def f(x):\n",
232 | " return 0 # wrong line\n",
233 | "\n",
234 | "# b. solution using a loop\n",
235 | "N = 100\n",
236 | "x_vec = np.linspace(-10,10,N)\n",
237 | "f_vec = np.empty(N)\n",
238 | "\n",
239 | "f_best = np.inf # initial maximum\n",
240 | "x_best = np.nan # not-a-number\n",
241 | "\n",
242 | "for i,x in enumerate(x_vec):\n",
243 | " f_now = f_vec[i] = f(x)\n",
244 | " # missing lines\n",
245 | "\n",
246 | "# c. solution using scipy optmize\n",
247 | "from scipy import optimize\n",
248 | "x_guess = [0] \n",
249 | "# missing line, hint: objective_function = lambda x: ?\n",
250 | "# missing line, hint: res = optimize.minimize(?)\n",
251 | "# x_best_scipy = res.x[0]\n",
252 | "# f_best_scipy = res.fun\n",
253 | "\n",
254 | "# d. print\n",
255 | "# missing lines\n",
256 | "\n",
257 | "# e. figure\n",
258 | "# missing lines"
259 | ]
260 | },
261 | {
262 | "cell_type": "markdown",
263 | "metadata": {},
264 | "source": [
265 | "**Answer:** see A4.py"
266 | ]
267 | },
268 | {
269 | "cell_type": "markdown",
270 | "metadata": {},
271 | "source": [
272 | "# Problem"
273 | ]
274 | },
275 | {
276 | "cell_type": "markdown",
277 | "metadata": {},
278 | "source": [
279 | "Consider the following $M$-good, $x=(x_1,x_2,\\dots,x_M)$, **utility maximization problem** with exogenous income $I$, and price-vector $p=(p_1,p_2,\\dots,p_M)$,\n",
280 | "\n",
281 | "$$\n",
282 | "\\begin{aligned}\n",
283 | "V(p_{1},p_{2},\\dots,,p_{M},I) & = \\max_{x_{1},x_{2},\\dots,x_M} x_{1}^{\\alpha_1} x_{2}^{\\alpha_2} \\dots x_{M}^{\\alpha_M} \\\\\n",
284 | " & \\text{s.t.}\\\\\n",
285 | "E & = \\sum_{i=1}^{M}p_{i}x_{i} \\leq I,\\,\\,\\,p_{1},p_{2},\\dots,p_M,I>0\\\\\n",
286 | "x_{1},x_{2},\\dots,x_M & \\geq 0\n",
287 | "\\end{aligned}\n",
288 | "$$"
289 | ]
290 | },
291 | {
292 | "cell_type": "markdown",
293 | "metadata": {},
294 | "source": [
295 | "**Problem:** Solve the 5-good utility maximization problem for arbitrary preference parameters, $ \\alpha = (\\alpha_1,\\alpha_2,\\dots,\\alpha_5)$, prices and income. First, with a loop, and then with a numerical optimizer."
296 | ]
297 | },
298 | {
299 | "cell_type": "markdown",
300 | "metadata": {},
301 | "source": [
302 | "You can use the following functions:"
303 | ]
304 | },
305 | {
306 | "cell_type": "code",
307 | "execution_count": null,
308 | "metadata": {},
309 | "outputs": [],
310 | "source": [
311 | "def utility_function(x,alpha):\n",
312 | " # ensure you understand what this function is doing\n",
313 | "\n",
314 | " u = 1\n",
315 | " for x_now,alpha_now in zip(x,alpha):\n",
316 | " u *= np.max(x_now,0)**alpha_now\n",
317 | " return u\n",
318 | " \n",
319 | "def expenditures(x,p):\n",
320 | " # ensure you understand what this function is doing\n",
321 | "\n",
322 | " E = 0\n",
323 | " for x_now,p_now in zip(x,p):\n",
324 | " E += p_now*x_now\n",
325 | " return E\n",
326 | "\n",
327 | "def print_solution(x,alpha,I,p):\n",
328 | " # you can just use this function\n",
329 | " \n",
330 | " # a. x values\n",
331 | " text = 'x = ['\n",
332 | " for x_now in x:\n",
333 | " text += f'{x_now:.2f} '\n",
334 | " text += f']\\n'\n",
335 | " \n",
336 | " # b. utility\n",
337 | " u = utility_function(x,alpha) \n",
338 | " text += f'utility = {u:.3f}\\n'\n",
339 | " \n",
340 | " # c. expenditure vs. income\n",
341 | " E = expenditures(x,p)\n",
342 | " text += f'E = {E:.2f} <= I = {I:.2f}\\n'\n",
343 | " \n",
344 | " # d. expenditure shares\n",
345 | " e = p*x/I\n",
346 | " text += 'expenditure shares = ['\n",
347 | " for e_now in e:\n",
348 | " text += f'{e_now:.2f} '\n",
349 | " text += f']' \n",
350 | " \n",
351 | " print(text)"
352 | ]
353 | },
354 | {
355 | "cell_type": "markdown",
356 | "metadata": {},
357 | "source": [
358 | "You can initially use the following parameter choices:"
359 | ]
360 | },
361 | {
362 | "cell_type": "code",
363 | "execution_count": null,
364 | "metadata": {},
365 | "outputs": [],
366 | "source": [
367 | "alpha = np.ones(5)/5\n",
368 | "p = np.array([1,2,3,4,5])\n",
369 | "I = 10"
370 | ]
371 | },
372 | {
373 | "cell_type": "markdown",
374 | "metadata": {},
375 | "source": [
376 | "Solving with a loop:"
377 | ]
378 | },
379 | {
380 | "cell_type": "code",
381 | "execution_count": null,
382 | "metadata": {},
383 | "outputs": [],
384 | "source": [
385 | "# update this code\n",
386 | "\n",
387 | "N = 15 # number of points in each dimension\n",
388 | "fac = np.linspace(0,1,N) # vector betweein 0 and 1\n",
389 | "x_max = I/p # maximum x so E = I\n",
390 | "\n",
391 | "# missing lines\n",
392 | "for x1 in fac:\n",
393 | " for x2 in fac:\n",
394 | " for x3 in fac:\n",
395 | " for x4 in fac:\n",
396 | " for x5 in fac:\n",
397 | " x = np.array([x1,x2,x3,x4,x5])*x_max\n",
398 | " E = expenditures(x,p)\n",
399 | " if E <= I:\n",
400 | " u_now = utility_function(x,alpha)\n",
401 | " # misssing lines\n",
402 | "\n",
403 | "# print_solution(x_best,alpha,I,p)"
404 | ]
405 | },
406 | {
407 | "cell_type": "markdown",
408 | "metadata": {},
409 | "source": [
410 | "> **Extra:** The above code can be written nicer with the ``product`` function from ``itertools``."
411 | ]
412 | },
413 | {
414 | "cell_type": "markdown",
415 | "metadata": {},
416 | "source": [
417 | "Solving with a numerical optimizer:"
418 | ]
419 | },
420 | {
421 | "cell_type": "code",
422 | "execution_count": null,
423 | "metadata": {},
424 | "outputs": [],
425 | "source": [
426 | "# update this code\n",
427 | "\n",
428 | "from scipy import optimize\n",
429 | "\n",
430 | "# a. contraint function (negative if violated)\n",
431 | "# missing line, hint: constraints = ({'type': 'ineq', 'fun': lambda x: ?})\n",
432 | "# missing line, hint: bounds = [(?,?) for p_now in p]\n",
433 | "\n",
434 | "# b. call optimizer\n",
435 | "initial_guess = (I/p)/6 # some guess, should be feasible\n",
436 | "# missing line, hint: res = optimize.minimize(?,?,method='SLSQP',bounds=bounds,constraints=constraints)\n",
437 | "\n",
438 | "# print(res.message) # check that the solver has terminated correctly\n",
439 | "\n",
440 | "# c. print result\n",
441 | "# print_solution(res.x,alpha,I,p)"
442 | ]
443 | },
444 | {
445 | "cell_type": "markdown",
446 | "metadata": {},
447 | "source": [
448 | "## Solutions using loops"
449 | ]
450 | },
451 | {
452 | "cell_type": "markdown",
453 | "metadata": {},
454 | "source": [
455 | "Using **raw loops**:"
456 | ]
457 | },
458 | {
459 | "cell_type": "markdown",
460 | "metadata": {
461 | "tags": []
462 | },
463 | "source": [
464 | "See A5.py"
465 | ]
466 | },
467 | {
468 | "cell_type": "markdown",
469 | "metadata": {},
470 | "source": [
471 | "Using **smart itertools loop:**"
472 | ]
473 | },
474 | {
475 | "cell_type": "markdown",
476 | "metadata": {
477 | "tags": []
478 | },
479 | "source": [
480 | "see A6.py "
481 | ]
482 | },
483 | {
484 | "cell_type": "markdown",
485 | "metadata": {},
486 | "source": [
487 | "## Solutions using solvers"
488 | ]
489 | },
490 | {
491 | "cell_type": "code",
492 | "execution_count": null,
493 | "metadata": {},
494 | "outputs": [],
495 | "source": [
496 | "from scipy import optimize"
497 | ]
498 | },
499 | {
500 | "cell_type": "markdown",
501 | "metadata": {},
502 | "source": [
503 | "Solution using a **constrained optimizer:**"
504 | ]
505 | },
506 | {
507 | "cell_type": "markdown",
508 | "metadata": {
509 | "tags": []
510 | },
511 | "source": [
512 | "see A7.py"
513 | ]
514 | },
515 | {
516 | "cell_type": "markdown",
517 | "metadata": {},
518 | "source": [
519 | "Solution using an **unconstrained optimizer:**"
520 | ]
521 | },
522 | {
523 | "cell_type": "markdown",
524 | "metadata": {
525 | "tags": []
526 | },
527 | "source": [
528 | "see A8.py"
529 | ]
530 | },
531 | {
532 | "cell_type": "markdown",
533 | "metadata": {},
534 | "source": [
535 | "# Extra Problems"
536 | ]
537 | },
538 | {
539 | "cell_type": "markdown",
540 | "metadata": {},
541 | "source": [
542 | "## Cost minimization"
543 | ]
544 | },
545 | {
546 | "cell_type": "markdown",
547 | "metadata": {},
548 | "source": [
549 | "Consider the following 2-good **cost minimziation problem** with required utility $u_0$, and price-vector $p=(p_1,p_2)$,\n",
550 | "\n",
551 | "$$\n",
552 | "\\begin{aligned}\n",
553 | "E(p_{1},p_{2},u_0) & = \\min_{x_{1},x_{2}} p_1 x_1+p_2 x_2\\\\\n",
554 | " & \\text{s.t.}\\\\\n",
555 | "x_{1}^{\\alpha}x_{2}^{1-\\alpha} & \\geq u_0 \\\\\n",
556 | "x_{1},x_{2} & \\geq 0\n",
557 | "\\end{aligned}\n",
558 | "$$"
559 | ]
560 | },
561 | {
562 | "cell_type": "markdown",
563 | "metadata": {},
564 | "source": [
565 | "**Problem:** Solve the 2-good cost-minimization problem with arbitrary required utility, prices and income. Present your results graphically showing that the optimum is a point, where a budgetline is targent to the indifference curve through $u_0$."
566 | ]
567 | },
568 | {
569 | "cell_type": "markdown",
570 | "metadata": {},
571 | "source": [
572 | "## Classy solution"
573 | ]
574 | },
575 | {
576 | "cell_type": "markdown",
577 | "metadata": {},
578 | "source": [
579 | "**Problem:** Implement your solution to the utility maximization problem and/or the cost minimization problem above in a class as seen in Lecture 3. "
580 | ]
581 | }
582 | ],
583 | "metadata": {
584 | "kernelspec": {
585 | "display_name": "Python 3 (ipykernel)",
586 | "language": "python",
587 | "name": "python3"
588 | },
589 | "language_info": {
590 | "codemirror_mode": {
591 | "name": "ipython",
592 | "version": 3
593 | },
594 | "file_extension": ".py",
595 | "mimetype": "text/x-python",
596 | "name": "python",
597 | "nbconvert_exporter": "python",
598 | "pygments_lexer": "ipython3",
599 | "version": "3.9.10"
600 | },
601 | "toc-autonumbering": true
602 | },
603 | "nbformat": 4,
604 | "nbformat_minor": 4
605 | }
606 |
--------------------------------------------------------------------------------
/PS2/A1.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | np.random.seed(1986)
3 | state = np.random.get_state()
4 | for i in range(3):
5 | np.random.set_state(state)
6 | for j in range(2):
7 | x = np.random.uniform()
8 | print(f'({i},{j}): x = {x:.3f}')
9 |
--------------------------------------------------------------------------------
/PS2/A2.py:
--------------------------------------------------------------------------------
1 | # a. parameter choices
2 | sigma = 3.14
3 | omega = 2
4 | N = 10000
5 | np.random.seed(1986)
6 |
7 | # b. draw random numbers
8 | x = np.random.normal(loc=0, scale=sigma, size=N)
9 |
10 | # c. transformation function
11 |
12 |
13 | def g(x, omega):
14 | y = x.copy()
15 | y[x < -omega] = -omega
16 | y[x > omega] = omega
17 | return y
18 |
19 |
20 | # d. mean and variance
21 | mean = np.mean(g(x, omega))
22 | var = np.var(g(x-mean, omega))
23 | print(f'mean = {mean:.5f}, var = {var:.5f}')
24 |
--------------------------------------------------------------------------------
/PS2/A3.py:
--------------------------------------------------------------------------------
1 | # a. import
2 | import ipywidgets as widgets
3 | from scipy.stats import norm
4 | import matplotlib.pyplot as plt
5 | import numpy as np
6 | %matplotlib inline
7 |
8 | # b. plotting figure
9 |
10 |
11 | def fitting_normal(X, mu_guess, sigma_guess):
12 |
13 | # i. normal distribution from guess
14 | F = norm(loc=mu_guess, scale=sigma_guess)
15 |
16 | # ii. x-values
17 | x_low = F.ppf(0.001) # x value where cdf is 0.001
18 | x_high = F.ppf(0.999) # x value where cdf is 0.999
19 | x = np.linspace(x_low, x_high, 100)
20 |
21 | # iii. figure
22 | fig = plt.figure(dpi=100)
23 | ax = fig.add_subplot(1, 1, 1)
24 | ax.plot(x, F.pdf(x), lw=2)
25 | ax.hist(X, bins=100, density=True, histtype='stepfilled')
26 | ax.set_ylim([0, 0.5])
27 | ax.set_xlim([-6, 6])
28 |
29 |
30 | # c. parameters
31 | mu_true = 2
32 | sigma_true = 1
33 | mu_guess = 1
34 | sigma_guess = 2
35 |
36 | # d. figure
37 | X = np.random.normal(loc=mu_true, scale=sigma_true, size=10**6)
38 | #fitting_normal(X,mu_guess,sigma_guess)
39 |
40 | widgets.interact(fitting_normal,
41 | X=widgets.fixed(X),
42 | mu_guess=widgets.FloatSlider(
43 | description="$\mu$", min=0.1, max=5, step=0.05, value=1),
44 | sigma_guess=widgets.FloatSlider(
45 | description="$\sigma$", min=0.1, max=5, step=0.05, value=1)
46 | )
47 |
--------------------------------------------------------------------------------
/PS2/A4.py:
--------------------------------------------------------------------------------
1 | import mymodule
2 | mymodule.myfun(5)
3 |
--------------------------------------------------------------------------------
/PS2/A5.py:
--------------------------------------------------------------------------------
1 | # a. parameters
2 | N = 10000
3 | mu = 0.5
4 | sigma = 0.2
5 | mu_low = 0.1
6 | mu_high = 0.9
7 | beta1 = 1.3
8 | beta2 = 2.1
9 | seed = 1986
10 |
11 | # b. draws of random numbers
12 | np.random.seed(seed)
13 | alphas = np.random.normal(loc=mu, scale=sigma, size=N)
14 | alphas = np.fmax(np.fmin(alphas, mu_high), mu_low)
15 | e1 = np.random.exponential(beta1, size=N)
16 | e2 = np.random.exponential(beta2, size=N)
17 |
18 | # c. demand function
19 |
20 |
21 | def demand_good_1_func(alpha, p1, p2, e1, e2):
22 | I = p1*e1+p2*e2
23 | return alpha*I/p1
24 |
25 | # d. excess demand function
26 |
27 |
28 | def excess_demand_good_1_func(alphas, p1, p2, e1, e2):
29 |
30 | # a. demand
31 | demand = np.sum(demand_good_1_func(alphas, p1, p2, e1, e2))
32 |
33 | # b. supply
34 | supply = np.sum(e1)
35 |
36 | # c. excess demand
37 | excess_demand = demand-supply
38 |
39 | return excess_demand
40 |
41 | # e. find equilibrium function
42 |
43 |
44 | def find_equilibrium(alphas, p1, p2, e1, e2, kappa=0.5, eps=1e-8, maxiter=500):
45 |
46 | t = 0
47 | while True:
48 |
49 | # a. step 1: excess demand
50 | Z1 = excess_demand_good_1_func(alphas, p1, p2, e1, e2)
51 |
52 | # b: step 2: stop?
53 | if np.abs(Z1) < eps or t >= maxiter:
54 | print(f'{t:3d}: p1 = {p1:12.8f} -> excess demand -> {Z1:14.8f}')
55 | break
56 |
57 | # c. step 3: update p1
58 | p1 = p1 + kappa*Z1/alphas.size
59 |
60 | # d. step 4: return
61 | if t < 5 or t % 25 == 0:
62 | print(f'{t:3d}: p1 = {p1:12.8f} -> excess demand -> {Z1:14.8f}')
63 | elif t == 5:
64 | print(' ...')
65 |
66 | t += 1
67 |
68 | return p1
69 |
70 |
71 | # f. call find equilibrium function
72 | p1 = 1.4
73 | p2 = 1
74 | kappa = 0.5
75 | eps = 1e-8
76 | p1 = find_equilibrium(alphas, p1, p2, e1, e2, kappa=kappa, eps=eps)
77 |
--------------------------------------------------------------------------------
/PS2/A6.py:
--------------------------------------------------------------------------------
1 | import pickle
2 |
3 | # a. create some data
4 | my_data = {}
5 | my_data['A'] = {'a': 1, 'b': 2}
6 | my_data['B'] = np.array([1, 2, 3])
7 | my_data['C'] = (1, 4, 2)
8 |
9 | my_np_data = {}
10 | my_np_data['D'] = np.array([1, 2, 3])
11 | my_np_data['E'] = np.zeros((5, 8))
12 | my_np_data['F'] = np.ones((7, 3, 8))
13 |
14 | # c. save with pickle
15 | with open(f'data.p', 'wb') as f:
16 | pickle.dump(my_data, f)
17 |
18 | # d. save with numpy
19 | np.savez(f'data.npz', **my_np_data)
20 |
21 | # a. try
22 |
23 |
24 | def load_and_print():
25 | with open(f'data.p', 'rb') as f:
26 | data = pickle.load(f)
27 | A = data['A']
28 | B = data['B']
29 | C = data['C']
30 |
31 | with np.load(f'data.npz') as data:
32 | D = data['D']
33 | E = data['E']
34 | F = data['F']
35 |
36 | print('variables loaded without error')
37 |
38 |
39 | try:
40 | load_and_print()
41 | except:
42 | print('an error is found')
43 |
--------------------------------------------------------------------------------
/PS2/mymodule.py:
--------------------------------------------------------------------------------
1 | def myfun(n):
2 | for i in range(n):
3 | print('hello world!')
--------------------------------------------------------------------------------
/PS2/problem_set_2.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Problem set 2: Finding the Walras equilibrium in a multi-agent economy"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "%load_ext autoreload\n",
17 | "%autoreload 2"
18 | ]
19 | },
20 | {
21 | "cell_type": "markdown",
22 | "metadata": {},
23 | "source": [
24 | "# Tasks"
25 | ]
26 | },
27 | {
28 | "cell_type": "markdown",
29 | "metadata": {},
30 | "source": [
31 | "## Drawing random numbers"
32 | ]
33 | },
34 | {
35 | "cell_type": "markdown",
36 | "metadata": {},
37 | "source": [
38 | "Replace the missing lines in the code below to get the same output as in the answer."
39 | ]
40 | },
41 | {
42 | "cell_type": "code",
43 | "execution_count": null,
44 | "metadata": {},
45 | "outputs": [],
46 | "source": [
47 | "import numpy as np\n",
48 | "np.random.seed(1986)\n",
49 | "# missing line\n",
50 | "for i in range(3):\n",
51 | " # missing line\n",
52 | " for j in range(2):\n",
53 | " x = np.random.uniform()\n",
54 | " print(f'({i},{j}): x = {x:.3f}')"
55 | ]
56 | },
57 | {
58 | "cell_type": "markdown",
59 | "metadata": {},
60 | "source": [
61 | "**Answer:**"
62 | ]
63 | },
64 | {
65 | "cell_type": "markdown",
66 | "metadata": {},
67 | "source": [
68 | "See A1.py"
69 | ]
70 | },
71 | {
72 | "cell_type": "markdown",
73 | "metadata": {},
74 | "source": [
75 | "## Find the expectated value"
76 | ]
77 | },
78 | {
79 | "cell_type": "markdown",
80 | "metadata": {},
81 | "source": [
82 | "Find the expected value and the expected variance\n",
83 | "\n",
84 | "$$ \n",
85 | "\\mathbb{E}[g(x)] \\approx \\frac{1}{N}\\sum_{i=1}^{N} g(x_i)\n",
86 | "$$\n",
87 | "$$ \n",
88 | "\\mathbb{VAR}[g(x)] \\approx \\frac{1}{N}\\sum_{i=1}^{N} \\left( g(x_i) - \\frac{1}{N}\\sum_{i=1}^{N} g(x_i) \\right)^2\n",
89 | "$$\n",
90 | "\n",
91 | "where $ x_i \\sim \\mathcal{N}(0,\\sigma) $ and\n",
92 | "\n",
93 | "$$ \n",
94 | "g(x,\\omega)=\\begin{cases}\n",
95 | "x & \\text{if }x\\in[-\\omega,\\omega]\\\\\n",
96 | "-\\omega & \\text{if }x<-\\omega\\\\\n",
97 | "\\omega & \\text{if }x>\\omega\n",
98 | "\\end{cases} \n",
99 | "$$"
100 | ]
101 | },
102 | {
103 | "cell_type": "code",
104 | "execution_count": null,
105 | "metadata": {},
106 | "outputs": [],
107 | "source": [
108 | "sigma = 3.14\n",
109 | "omega = 2\n",
110 | "N = 10000\n",
111 | "np.random.seed(1986)\n",
112 | "# write your code here"
113 | ]
114 | },
115 | {
116 | "cell_type": "markdown",
117 | "metadata": {},
118 | "source": [
119 | "**Answer:**"
120 | ]
121 | },
122 | {
123 | "cell_type": "markdown",
124 | "metadata": {},
125 | "source": [
126 | "See A2.py"
127 | ]
128 | },
129 | {
130 | "cell_type": "markdown",
131 | "metadata": {},
132 | "source": [
133 | "## Interactive histogram"
134 | ]
135 | },
136 | {
137 | "cell_type": "markdown",
138 | "metadata": {},
139 | "source": [
140 | "**First task:** Consider the code below. Fill in the missing lines so the figure is plotted."
141 | ]
142 | },
143 | {
144 | "cell_type": "code",
145 | "execution_count": null,
146 | "metadata": {},
147 | "outputs": [],
148 | "source": [
149 | "# a. import\n",
150 | "%matplotlib inline\n",
151 | "import matplotlib.pyplot as plt\n",
152 | "# missing line\n",
153 | "\n",
154 | "# b. plotting figure\n",
155 | "def fitting_normal(X,mu_guess,sigma_guess):\n",
156 | " \n",
157 | " # i. normal distribution from guess\n",
158 | " F = norm(loc=mu_guess,scale=sigma_guess)\n",
159 | " \n",
160 | " # ii. x-values\n",
161 | " # missing line, x_low =\n",
162 | " # missing line, x_high =\n",
163 | " x = np.linspace(x_low,x_high,100)\n",
164 | "\n",
165 | " # iii. figure\n",
166 | " fig = plt.figure(dpi=100)\n",
167 | " ax = fig.add_subplot(1,1,1)\n",
168 | " ax.plot(x,F.pdf(x),lw=2)\n",
169 | " ax.hist(X,bins=100,density=True,histtype='stepfilled');\n",
170 | " ax.set_ylim([0,0.5])\n",
171 | " ax.set_xlim([-6,6])\n",
172 | "\n",
173 | "# c. parameters\n",
174 | "mu_true = 2\n",
175 | "sigma_true = 1\n",
176 | "mu_guess = 1\n",
177 | "sigma_guess = 2\n",
178 | "\n",
179 | "# d. random draws\n",
180 | "X = np.random.normal(loc=mu_true,scale=sigma_true,size=10**6)\n",
181 | "\n",
182 | "# e. figure\n",
183 | "try:\n",
184 | " fitting_normal(X,mu_guess,sigma_guess)\n",
185 | "except:\n",
186 | " print('failed')"
187 | ]
188 | },
189 | {
190 | "cell_type": "markdown",
191 | "metadata": {},
192 | "source": [
193 | "**Second task:** Create an interactive version of the figure with sliders for $\\mu$ and $\\sigma$."
194 | ]
195 | },
196 | {
197 | "cell_type": "code",
198 | "execution_count": null,
199 | "metadata": {},
200 | "outputs": [],
201 | "source": [
202 | "# write your code here"
203 | ]
204 | },
205 | {
206 | "cell_type": "markdown",
207 | "metadata": {},
208 | "source": [
209 | "**Answer:**"
210 | ]
211 | },
212 | {
213 | "cell_type": "markdown",
214 | "metadata": {},
215 | "source": [
216 | "See A3.py"
217 | ]
218 | },
219 | {
220 | "cell_type": "markdown",
221 | "metadata": {},
222 | "source": [
223 | "## Modules"
224 | ]
225 | },
226 | {
227 | "cell_type": "markdown",
228 | "metadata": {},
229 | "source": [
230 | "1. Call the function `myfun` from the module `mymodule` present in this folder.\n",
231 | "2. Open VSCode and open the `mymodule.py`, add a new function and call it from this notebook."
232 | ]
233 | },
234 | {
235 | "cell_type": "code",
236 | "execution_count": null,
237 | "metadata": {},
238 | "outputs": [],
239 | "source": [
240 | "# write your code here"
241 | ]
242 | },
243 | {
244 | "cell_type": "markdown",
245 | "metadata": {},
246 | "source": [
247 | "**Answer:**"
248 | ]
249 | },
250 | {
251 | "cell_type": "markdown",
252 | "metadata": {},
253 | "source": [
254 | "See A4.py"
255 | ]
256 | },
257 | {
258 | "cell_type": "markdown",
259 | "metadata": {},
260 | "source": [
261 | "## Git"
262 | ]
263 | },
264 | {
265 | "cell_type": "markdown",
266 | "metadata": {},
267 | "source": [
268 | "1. Try to go to your own personal GitHub main page and create a new repository. Then put your solution to this problem set in it.\n",
269 | "2. Pair up with a fellow student. Clone each others repositories and run the code in them."
270 | ]
271 | },
272 | {
273 | "cell_type": "markdown",
274 | "metadata": {},
275 | "source": [
276 | "**IMPORTANT:** You will need **git** for the data project in a few needs. Better learn it know. Remember, that the teaching assistants are there to help you."
277 | ]
278 | },
279 | {
280 | "cell_type": "markdown",
281 | "metadata": {},
282 | "source": [
283 | "# Problem"
284 | ]
285 | },
286 | {
287 | "cell_type": "markdown",
288 | "metadata": {},
289 | "source": [
290 | "Consider an **exchange economy** with\n",
291 | "\n",
292 | "1. 2 goods, $(x_1,x_2)$\n",
293 | "2. $N$ consumers indexed by $j \\in \\{1,2,\\dots,N\\}$\n",
294 | "3. Preferences are Cobb-Douglas with truncated normally *heterogenous* coefficients\n",
295 | "\n",
296 | " $$\n",
297 | " \\begin{aligned}\n",
298 | " u^{j}(x_{1},x_{2}) & = x_{1}^{\\alpha_{j}}x_{2}^{1-\\alpha_{j}}\\\\\n",
299 | " & \\tilde{\\alpha}_{j}\\sim\\mathcal{N}(\\mu,\\sigma)\\\\\n",
300 | " & \\alpha_j = \\max(\\underline{\\mu},\\min(\\overline{\\mu},\\tilde{\\alpha}_{j}))\n",
301 | " \\end{aligned}\n",
302 | " $$\n",
303 | "\n",
304 | "4. Endowments are *heterogenous* and given by\n",
305 | "\n",
306 | " $$\n",
307 | " \\begin{aligned}\n",
308 | " \\boldsymbol{e}^{j}&=(e_{1}^{j},e_{2}^{j}) \\\\\n",
309 | " & & e_i^j \\sim f, f(x,\\beta_i) = 1/\\beta_i \\exp(-x/\\beta)\n",
310 | " \\end{aligned}\n",
311 | " $$"
312 | ]
313 | },
314 | {
315 | "cell_type": "markdown",
316 | "metadata": {},
317 | "source": [
318 | "**Problem:** Write a function to solve for the equilibrium."
319 | ]
320 | },
321 | {
322 | "cell_type": "markdown",
323 | "metadata": {},
324 | "source": [
325 | "You can use the following parameters:"
326 | ]
327 | },
328 | {
329 | "cell_type": "code",
330 | "execution_count": null,
331 | "metadata": {},
332 | "outputs": [],
333 | "source": [
334 | "# a. parameters\n",
335 | "N = 10000\n",
336 | "mu = 0.5\n",
337 | "sigma = 0.2\n",
338 | "mu_low = 0.1\n",
339 | "mu_high = 0.9\n",
340 | "beta1 = 1.3\n",
341 | "beta2 = 2.1\n",
342 | "seed = 1986\n",
343 | "\n",
344 | "# b. draws of random numbers\n",
345 | "# c. demand function\n",
346 | "# d. excess demand function\n",
347 | "# e. find equilibrium function\n",
348 | "# f. call find equilibrium function"
349 | ]
350 | },
351 | {
352 | "cell_type": "markdown",
353 | "metadata": {},
354 | "source": [
355 | "**Hint:** The code structure is exactly the same as for the exchange economy considered in the lecture. The code for solving that exchange economy is reproduced in condensed form below."
356 | ]
357 | },
358 | {
359 | "cell_type": "code",
360 | "execution_count": null,
361 | "metadata": {},
362 | "outputs": [],
363 | "source": [
364 | "# a. parameters\n",
365 | "N = 1000\n",
366 | "k = 2\n",
367 | "mu_low = 0.1\n",
368 | "mu_high = 0.9\n",
369 | "seed = 1986\n",
370 | "\n",
371 | "# b. draws of random numbers\n",
372 | "np.random.seed(seed)\n",
373 | "alphas = np.random.uniform(low=mu_low,high=mu_high,size=N)\n",
374 | "\n",
375 | "# c. demand function\n",
376 | "def demand_good_1_func(alpha,p1,p2,k):\n",
377 | " I = k*p1+p2\n",
378 | " return alpha*I/p1\n",
379 | "\n",
380 | "# d. excess demand function\n",
381 | "def excess_demand_good_1_func(alphas,p1,p2,k):\n",
382 | " \n",
383 | " # a. demand\n",
384 | " demand = np.sum(demand_good_1_func(alphas,p1,p2,k))\n",
385 | " \n",
386 | " # b. supply\n",
387 | " supply = k*alphas.size\n",
388 | " \n",
389 | " # c. excess demand\n",
390 | " excess_demand = demand-supply\n",
391 | " \n",
392 | " return excess_demand\n",
393 | "\n",
394 | "# e. find equilibrium function\n",
395 | "def find_equilibrium(alphas,p1,p2,k,kappa=0.5,eps=1e-8,maxiter=500):\n",
396 | " \n",
397 | " t = 0\n",
398 | " while True:\n",
399 | "\n",
400 | " # a. step 1: excess demand\n",
401 | " Z1 = excess_demand_good_1_func(alphas,p1,p2,k)\n",
402 | " \n",
403 | " # b: step 2: stop?\n",
404 | " if np.abs(Z1) < eps or t >= maxiter:\n",
405 | " print(f'{t:3d}: p1 = {p1:12.8f} -> excess demand -> {Z1:14.8f}')\n",
406 | " break \n",
407 | " \n",
408 | " # c. step 3: update p1\n",
409 | " p1 = p1 + kappa*Z1/alphas.size\n",
410 | " \n",
411 | " # d. step 4: return \n",
412 | " if t < 5 or t%25 == 0:\n",
413 | " print(f'{t:3d}: p1 = {p1:12.8f} -> excess demand -> {Z1:14.8f}')\n",
414 | " elif t == 5:\n",
415 | " print(' ...')\n",
416 | " \n",
417 | " t += 1 \n",
418 | "\n",
419 | " return p1\n",
420 | "\n",
421 | "# e. call find equilibrium function\n",
422 | "p1 = 1.4\n",
423 | "p2 = 1\n",
424 | "kappa = 0.1\n",
425 | "eps = 1e-8\n",
426 | "p1 = find_equilibrium(alphas,p1,p2,k,kappa=kappa,eps=eps)"
427 | ]
428 | },
429 | {
430 | "cell_type": "markdown",
431 | "metadata": {},
432 | "source": [
433 | "**Answers:**"
434 | ]
435 | },
436 | {
437 | "cell_type": "markdown",
438 | "metadata": {},
439 | "source": [
440 | "See A5.py"
441 | ]
442 | },
443 | {
444 | "cell_type": "markdown",
445 | "metadata": {},
446 | "source": [
447 | "## Save and load"
448 | ]
449 | },
450 | {
451 | "cell_type": "markdown",
452 | "metadata": {},
453 | "source": [
454 | "Consider the code below and fill in the missing lines so the code can run without any errors."
455 | ]
456 | },
457 | {
458 | "cell_type": "code",
459 | "execution_count": null,
460 | "metadata": {},
461 | "outputs": [],
462 | "source": [
463 | "import pickle\n",
464 | "\n",
465 | "# a. create some data\n",
466 | "my_data = {}\n",
467 | "my_data['A'] = {'a':1,'b':2}\n",
468 | "my_data['B'] = np.array([1,2,3])\n",
469 | "# missing line\n",
470 | "\n",
471 | "my_np_data = {}\n",
472 | "my_np_data['D'] = np.array([1,2,3])\n",
473 | "my_np_data['E'] = np.zeros((5,8))\n",
474 | "# missing line\n",
475 | "\n",
476 | "# c. save with pickle\n",
477 | "with open(f'data.p', 'wb') as f:\n",
478 | " # missing line\n",
479 | " pass\n",
480 | " \n",
481 | "# d. save with numpy\n",
482 | "# missing line, np.savez(?)\n",
483 | " \n",
484 | "# a. try\n",
485 | "def load_all():\n",
486 | " with open(f'data.p', 'rb') as f:\n",
487 | " data = pickle.load(f)\n",
488 | " A = data['A']\n",
489 | " B = data['B']\n",
490 | " C = data['C']\n",
491 | "\n",
492 | " with np.load(f'data.npz') as data:\n",
493 | " D = data['D']\n",
494 | " E = data['E']\n",
495 | " F = data['F'] \n",
496 | " \n",
497 | " print('variables loaded without error')\n",
498 | " \n",
499 | "try:\n",
500 | " load_all()\n",
501 | "except:\n",
502 | " print('failed')"
503 | ]
504 | },
505 | {
506 | "cell_type": "markdown",
507 | "metadata": {},
508 | "source": [
509 | "**Answer:**"
510 | ]
511 | },
512 | {
513 | "cell_type": "markdown",
514 | "metadata": {},
515 | "source": [
516 | "See A6.py"
517 | ]
518 | },
519 | {
520 | "cell_type": "markdown",
521 | "metadata": {},
522 | "source": [
523 | "# Extra Problems"
524 | ]
525 | },
526 | {
527 | "cell_type": "markdown",
528 | "metadata": {},
529 | "source": [
530 | "## Multiple goods"
531 | ]
532 | },
533 | {
534 | "cell_type": "markdown",
535 | "metadata": {},
536 | "source": [
537 | "Solve the main problem extended with multiple goods:"
538 | ]
539 | },
540 | {
541 | "cell_type": "markdown",
542 | "metadata": {},
543 | "source": [
544 | "$$\n",
545 | "\\begin{aligned}\n",
546 | "u^{j}(x_{1},x_{2}) & = x_{1}^{\\alpha^1_{j}} \\cdot x_{2}^{\\alpha^2_{j}} \\cdots x_{M}^{\\alpha^M_{j}}\\\\\n",
547 | " & \\alpha_j = [\\alpha^1_{j},\\alpha^2_{j},\\dots,\\alpha^M_{j}] \\\\\n",
548 | " & \\log(\\alpha_j) \\sim \\mathcal{N}(0,\\Sigma) \\\\\n",
549 | "\\end{aligned}\n",
550 | "$$\n",
551 | "\n",
552 | "where $\\Sigma$ is a valid covariance matrix."
553 | ]
554 | },
555 | {
556 | "cell_type": "code",
557 | "execution_count": null,
558 | "metadata": {},
559 | "outputs": [],
560 | "source": [
561 | "# a. choose parameters\n",
562 | "N = 10000\n",
563 | "J = 3\n",
564 | "\n",
565 | "# b. choose Sigma\n",
566 | "Sigma_lower = np.array([[1, 0, 0], [0.5, 1, 0], [0.25, -0.5, 1]])\n",
567 | "Sigma_upper = Sigma_lower.T\n",
568 | "Sigma = Sigma_upper@Sigma_lower\n",
569 | "print(Sigma)\n",
570 | "\n",
571 | "# c. draw random numbers\n",
572 | "alphas = np.exp(np.random.multivariate_normal(np.zeros(J), Sigma, 10000))\n",
573 | "print(np.mean(alphas,axis=0))\n",
574 | "print(np.corrcoef(alphas.T))\n",
575 | "\n",
576 | "# write your code here"
577 | ]
578 | }
579 | ],
580 | "metadata": {
581 | "kernelspec": {
582 | "display_name": "Python 3 (ipykernel)",
583 | "language": "python",
584 | "name": "python3"
585 | },
586 | "language_info": {
587 | "codemirror_mode": {
588 | "name": "ipython",
589 | "version": 3
590 | },
591 | "file_extension": ".py",
592 | "mimetype": "text/x-python",
593 | "name": "python",
594 | "nbconvert_exporter": "python",
595 | "pygments_lexer": "ipython3",
596 | "version": "3.9.10"
597 | },
598 | "toc-autonumbering": true
599 | },
600 | "nbformat": 4,
601 | "nbformat_minor": 4
602 | }
603 |
--------------------------------------------------------------------------------
/PS3/A01.py:
--------------------------------------------------------------------------------
1 | # Q1
2 | N = 100
3 | mydata = {}
4 | mydata['id'] = range(N)
5 | mydata['income'] = np.exp(np.random.normal(size=N))
6 | mydata['consumption'] = np.sqrt(mydata['income'])
7 |
8 | dt_true = pd.DataFrame(mydata)
9 | dt_true.head()
--------------------------------------------------------------------------------
/PS3/A02.py:
--------------------------------------------------------------------------------
1 | # Q2
2 | dt_true['ratio'] = dt_true['consumption']/dt_true['income']
3 | dt_true.head()
--------------------------------------------------------------------------------
/PS3/A03.py:
--------------------------------------------------------------------------------
1 | # Q3
2 | dt_true.describe()
3 |
--------------------------------------------------------------------------------
/PS3/A04.py:
--------------------------------------------------------------------------------
1 | # Q4
2 | I = dt_true['income'] > 1
3 | dt_true.loc[I, :].head()
4 |
--------------------------------------------------------------------------------
/PS3/A05.py:
--------------------------------------------------------------------------------
1 | # Q5
2 | I = (dt_true['income'] > 1) & (dt_true['ratio'] > 0.7)
3 | dt_true.loc[I].head()
--------------------------------------------------------------------------------
/PS3/A06.py:
--------------------------------------------------------------------------------
1 | # Q6
2 | I = (dt_true['income'] < 0.5)
3 | dt_true.loc[I, ['consumption']] = 0.5
4 | dt_true['consumption'].mean()
--------------------------------------------------------------------------------
/PS3/A07.py:
--------------------------------------------------------------------------------
1 | # Q7
2 | I = (dt_true['income'] < 0.5)
3 | dt_true.loc[I, ['consumption']] = dt_true.loc[I, ['income']].values
4 | dt_true['consumption'].mean()
--------------------------------------------------------------------------------
/PS3/A08.py:
--------------------------------------------------------------------------------
1 | dt_alt = dt_true.copy()
2 |
3 | print(f'before: {dt_true.shape[0]} observations, {dt_true.shape[1]} variables')
4 | dt_true.drop('ratio',axis=1,inplace=True)
5 | I = dt_true['income'] > 1.5
6 | dt_true.drop(dt_true[I].index,inplace=True)
7 | dt_true.drop(dt_true.loc[:5].index,inplace=True)
8 | print(f'after: {dt_true.shape[0]} observations, {dt_true.shape[1]} variables')
9 |
10 | # alternative: keep where I is false
11 | del dt_alt['ratio']
12 | I = dt_alt['income'] > 1.5
13 | dt_alt = dt_alt[~I]
14 | dt_alt = dt_alt.iloc[5:,:]
15 | print(f'after (alt): {dt_alt.shape[0]} observations, {dt_alt.shape[1]} variables')
--------------------------------------------------------------------------------
/PS3/A09.py:
--------------------------------------------------------------------------------
1 | dt_true.rename(columns={'income':'inc','consumption':'con'},inplace=True)
2 | dt_true.head()
--------------------------------------------------------------------------------
/PS3/A10.py:
--------------------------------------------------------------------------------
1 | def assets_row_by_row(x,R,Y):
2 | return R*(x['inc']-x['con'])+Y
3 |
4 | def assets_all_at_once(income,consumption,R,Y):
5 | return R*(income-consumption)+Y
6 |
7 | def assets_adj(assets,R,Y):
8 | assets *= R
9 | assets += Y
10 |
11 | R = 1.2 # return rate
12 | Y = 1 # income
13 | dt_true['assets_1'] = R*(dt_true['inc']-dt_true['con'])+Y
14 | dt_true['assets_2'] = dt_true.apply(assets_row_by_row,axis=1,args=(R,Y))
15 | dt_true['assets_3'] = assets_all_at_once(dt_true['inc'].to_numpy(),dt_true['con'].to_numpy(),R,Y)
16 | dt_true['assets_4'] = dt_true['inc']-dt_true['con']
17 | assets_adj(dt_true['assets_4'],R,Y)
18 |
19 | dt_true.head()
--------------------------------------------------------------------------------
/PS3/A11.py:
--------------------------------------------------------------------------------
1 | # a. load data set
2 | nah1 = pd.read_excel('data/NAH1_pivoted.xlsx',skiprows=2)
3 |
4 | # b. rename variables
5 | rename_dict['Unnamed: 0'] = 'year'
6 | nah1.rename(columns=rename_dict,inplace=True)
7 |
8 | # c. remove rows where Y is nan
9 | I = nah1['Y'].notna()
10 | nah1 = nah1[I]
11 |
12 | # d. correct year column data
13 | I = nah1['year'].notna()
14 | J = nah1['year'].isna()
15 | nah1.loc[J,['year']] = nah1.loc[I,['year']].to_numpy()
16 |
17 | # e. only keep rows with '2010-prices, chained values'
18 | I = nah1['Unnamed: 1'] == '2010-prices, chained values'
19 | nah1 = nah1[I]
20 |
21 | # f. only keep renamed variables
22 | nah1 = nah1.loc[:,['year','Y','C','G','I','X','M']]
23 | nah1
--------------------------------------------------------------------------------
/PS3/data/NAH1_pivoted.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NumEconCopenhagen/IntroProg-exercises/0dee1719691f0f7cccb91cbf2a88f3a0c921fc74/PS3/data/NAH1_pivoted.xlsx
--------------------------------------------------------------------------------
/PS3/problem_set_3.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Problem set 3: Loading and structuring data from Denmark Statistics"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "%matplotlib inline\n",
17 | "import numpy as np\n",
18 | "import matplotlib.pyplot as plt\n",
19 | "plt.rcParams.update({\"axes.grid\":True,\"grid.color\":\"black\",\"grid.alpha\":\"0.25\",\"grid.linestyle\":\"--\"})\n",
20 | "plt.rcParams.update({'font.size': 14})\n",
21 | "\n",
22 | "import pandas as pd\n",
23 | "import ipywidgets as widgets"
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "# Tasks"
31 | ]
32 | },
33 | {
34 | "cell_type": "markdown",
35 | "metadata": {},
36 | "source": [
37 | "## Create a pandas DataFrame"
38 | ]
39 | },
40 | {
41 | "cell_type": "markdown",
42 | "metadata": {},
43 | "source": [
44 | "Modify the code below such that *income* and *consumption* are variables in the *dt* DataFrame."
45 | ]
46 | },
47 | {
48 | "cell_type": "code",
49 | "execution_count": null,
50 | "metadata": {},
51 | "outputs": [],
52 | "source": [
53 | "np.random.seed(1999)\n",
54 | " \n",
55 | "N = 100\n",
56 | "mydata = {}\n",
57 | "mydata['id'] = range(N)\n",
58 | "income = np.exp(np.random.normal(size=N))\n",
59 | "consumption = np.sqrt(income)\n",
60 | "\n",
61 | "dt = pd.DataFrame(mydata)\n",
62 | "dt.head()"
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {},
68 | "source": [
69 | "**Answer:** see A01.py"
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "metadata": {},
75 | "source": [
76 | "## Create new variable"
77 | ]
78 | },
79 | {
80 | "cell_type": "markdown",
81 | "metadata": {},
82 | "source": [
83 | "1) Add a new variable *ratio* which is the ratio of consumption to income."
84 | ]
85 | },
86 | {
87 | "cell_type": "code",
88 | "execution_count": null,
89 | "metadata": {},
90 | "outputs": [],
91 | "source": [
92 | "# write your code here\n",
93 | "dt.head()"
94 | ]
95 | },
96 | {
97 | "cell_type": "markdown",
98 | "metadata": {},
99 | "source": [
100 | "**Answer:** See A02.py"
101 | ]
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "metadata": {},
106 | "source": [
107 | "## Summary statistics"
108 | ]
109 | },
110 | {
111 | "cell_type": "markdown",
112 | "metadata": {},
113 | "source": [
114 | "Produce summary statistics using `.describe()`."
115 | ]
116 | },
117 | {
118 | "cell_type": "code",
119 | "execution_count": null,
120 | "metadata": {},
121 | "outputs": [],
122 | "source": [
123 | "# write your code here"
124 | ]
125 | },
126 | {
127 | "cell_type": "markdown",
128 | "metadata": {},
129 | "source": [
130 | "**Answer:** See A03.py"
131 | ]
132 | },
133 | {
134 | "cell_type": "markdown",
135 | "metadata": {},
136 | "source": [
137 | "## Indexing"
138 | ]
139 | },
140 | {
141 | "cell_type": "markdown",
142 | "metadata": {},
143 | "source": [
144 | "Select everybody with an income above 1."
145 | ]
146 | },
147 | {
148 | "cell_type": "code",
149 | "execution_count": null,
150 | "metadata": {},
151 | "outputs": [],
152 | "source": [
153 | "# write your code here\n",
154 | "dt.head()"
155 | ]
156 | },
157 | {
158 | "cell_type": "markdown",
159 | "metadata": {},
160 | "source": [
161 | "**Answer:** See A04.py"
162 | ]
163 | },
164 | {
165 | "cell_type": "markdown",
166 | "metadata": {},
167 | "source": [
168 | "Select everybody with an income *above* 1 and a ratio *above* 0.7."
169 | ]
170 | },
171 | {
172 | "cell_type": "code",
173 | "execution_count": null,
174 | "metadata": {},
175 | "outputs": [],
176 | "source": [
177 | "# write your code here"
178 | ]
179 | },
180 | {
181 | "cell_type": "markdown",
182 | "metadata": {},
183 | "source": [
184 | "**Answer:** See A05.py"
185 | ]
186 | },
187 | {
188 | "cell_type": "markdown",
189 | "metadata": {},
190 | "source": [
191 | "Set consumption equal to 0.5 if income is less than 0.5."
192 | ]
193 | },
194 | {
195 | "cell_type": "code",
196 | "execution_count": null,
197 | "metadata": {},
198 | "outputs": [],
199 | "source": [
200 | "# write your code here\n",
201 | "# dt['consumption'].mean() # <- compare with answer"
202 | ]
203 | },
204 | {
205 | "cell_type": "markdown",
206 | "metadata": {},
207 | "source": [
208 | "**Answer:** See A06.py"
209 | ]
210 | },
211 | {
212 | "cell_type": "markdown",
213 | "metadata": {},
214 | "source": [
215 | "Set consumption equal to income if income is less than 0.5."
216 | ]
217 | },
218 | {
219 | "cell_type": "code",
220 | "execution_count": null,
221 | "metadata": {},
222 | "outputs": [],
223 | "source": [
224 | "# write your code here\n",
225 | "# dt['consumption'].mean() # <- compare with answer"
226 | ]
227 | },
228 | {
229 | "cell_type": "markdown",
230 | "metadata": {},
231 | "source": [
232 | "**Answer:** See A07.py"
233 | ]
234 | },
235 | {
236 | "cell_type": "markdown",
237 | "metadata": {},
238 | "source": [
239 | "## Dropping"
240 | ]
241 | },
242 | {
243 | "cell_type": "markdown",
244 | "metadata": {},
245 | "source": [
246 | "Drop the *ratio* variable and all rows with an income above 1.5. After this, also drop the first 5 rows."
247 | ]
248 | },
249 | {
250 | "cell_type": "code",
251 | "execution_count": null,
252 | "metadata": {},
253 | "outputs": [],
254 | "source": [
255 | "print(f'before: {dt.shape[0]} observations, {dt.shape[1]} variables')\n",
256 | "# write your code here\n",
257 | "print(f'after: {dt.shape[0]} observations, {dt.shape[1]} variables')"
258 | ]
259 | },
260 | {
261 | "cell_type": "markdown",
262 | "metadata": {},
263 | "source": [
264 | "**Answer:** see A08.py"
265 | ]
266 | },
267 | {
268 | "cell_type": "markdown",
269 | "metadata": {},
270 | "source": [
271 | "## Renaming"
272 | ]
273 | },
274 | {
275 | "cell_type": "markdown",
276 | "metadata": {},
277 | "source": [
278 | "Rename *consumption* to *cons* and *income* to *inc*."
279 | ]
280 | },
281 | {
282 | "cell_type": "code",
283 | "execution_count": null,
284 | "metadata": {},
285 | "outputs": [],
286 | "source": [
287 | "# write your code\n",
288 | "dt.head()"
289 | ]
290 | },
291 | {
292 | "cell_type": "markdown",
293 | "metadata": {},
294 | "source": [
295 | "**Answer:** see A09.py"
296 | ]
297 | },
298 | {
299 | "cell_type": "markdown",
300 | "metadata": {},
301 | "source": [
302 | "## Functions"
303 | ]
304 | },
305 | {
306 | "cell_type": "markdown",
307 | "metadata": {},
308 | "source": [
309 | "Correct the wrong lines such that `assets_1 = assets_2 = assets_3 = assets_4`."
310 | ]
311 | },
312 | {
313 | "cell_type": "code",
314 | "execution_count": null,
315 | "metadata": {},
316 | "outputs": [],
317 | "source": [
318 | "def assets_row_by_row(x,R,Y):\n",
319 | " return 0 # wrong line\n",
320 | " \n",
321 | "def assets_all_at_once(income,consumption,R,Y):\n",
322 | " return 0 # wrong line\n",
323 | "\n",
324 | "def assets_adj(assets,R,Y):\n",
325 | " # missing lines\n",
326 | " pass\n",
327 | "\n",
328 | "R = 1.2 # return rate\n",
329 | "Y = 1 # income\n",
330 | "try:\n",
331 | " dt['assets_1'] = R*(dt['inc']-dt['con'])+Y\n",
332 | " dt['assets_2'] = dt.apply(assets_row_by_row,axis=1,args=(R,Y))\n",
333 | " dt['assets_3'] = assets_all_at_once(dt['inc'].to_numpy(),dt['con'].to_numpy(),R,Y)\n",
334 | " dt['assets_4'] = dt['inc']-dt['con']\n",
335 | " assets_adj(dt['assets_4'],R,Y)\n",
336 | "except:\n",
337 | " print('failed')\n",
338 | "dt.head() "
339 | ]
340 | },
341 | {
342 | "cell_type": "markdown",
343 | "metadata": {},
344 | "source": [
345 | "**Answer:** see A10.py"
346 | ]
347 | },
348 | {
349 | "cell_type": "markdown",
350 | "metadata": {},
351 | "source": [
352 | "# Problem"
353 | ]
354 | },
355 | {
356 | "cell_type": "markdown",
357 | "metadata": {},
358 | "source": [
359 | "Load the data set in *data/NAH1_pivoted.xlsx* and clean and structure it such that the `plot_timeseries(dataframe)` below can be run and produce an interactive figure. "
360 | ]
361 | },
362 | {
363 | "cell_type": "code",
364 | "execution_count": null,
365 | "metadata": {},
366 | "outputs": [],
367 | "source": [
368 | "def _plot_timeseries(dataframe, variable, years):\n",
369 | " \n",
370 | " fig = plt.figure(dpi=100)\n",
371 | " ax = fig.add_subplot(1,1,1)\n",
372 | " \n",
373 | " dataframe.loc[:,['year']] = pd.to_numeric(dataframe['year'])\n",
374 | " I = (dataframe['year'] >= years[0]) & (dataframe['year'] <= years[1])\n",
375 | " \n",
376 | " x = dataframe.loc[I,'year']\n",
377 | " y = dataframe.loc[I,variable]\n",
378 | " ax.plot(x,y)\n",
379 | " \n",
380 | " ax.set_xticks(list(range(years[0], years[1] + 1, 5))) \n",
381 | " \n",
382 | "def plot_timeseries(dataframe):\n",
383 | " \n",
384 | " widgets.interact(_plot_timeseries, \n",
385 | " dataframe = widgets.fixed(dataframe),\n",
386 | " variable = widgets.Dropdown(\n",
387 | " description='variable', \n",
388 | " options=['Y','C','G','I','X','M'], \n",
389 | " value='Y'),\n",
390 | " years=widgets.IntRangeSlider(\n",
391 | " description=\"years\",\n",
392 | " min=1966,\n",
393 | " max=2018,\n",
394 | " value=[1980, 2018],\n",
395 | " continuous_update=False,\n",
396 | " ) \n",
397 | "); "
398 | ]
399 | },
400 | {
401 | "cell_type": "markdown",
402 | "metadata": {},
403 | "source": [
404 | "**Hint 1:** You can base your renaming on this dictionary:"
405 | ]
406 | },
407 | {
408 | "cell_type": "code",
409 | "execution_count": null,
410 | "metadata": {},
411 | "outputs": [],
412 | "source": [
413 | "rename_dict = {}\n",
414 | "rename_dict['P.1 Output'] = 'Y'\n",
415 | "rename_dict['P.3 Final consumption expenditure'] = 'C'\n",
416 | "rename_dict['P.3 Government consumption expenditure'] = 'G'\n",
417 | "rename_dict['P.5 Gross capital formation'] = 'I'\n",
418 | "rename_dict['P.6 Export of goods and services'] = 'X'\n",
419 | "rename_dict['P.7 Import of goods and services'] = 'M'"
420 | ]
421 | },
422 | {
423 | "cell_type": "markdown",
424 | "metadata": {},
425 | "source": [
426 | "**Hint 2:** You code should have the following structure:"
427 | ]
428 | },
429 | {
430 | "cell_type": "code",
431 | "execution_count": null,
432 | "metadata": {},
433 | "outputs": [],
434 | "source": [
435 | "# a. load data set\n",
436 | "# nah1 = ?\n",
437 | "\n",
438 | "# b. rename variables\n",
439 | "\n",
440 | "# c. remove rows where Y is nan\n",
441 | "\n",
442 | "# d. correct year column data\n",
443 | "# hint, nah1.loc[J,['year']] = nah1.loc[I,['year']].to_numpy()\n",
444 | "\n",
445 | "# e. only keep rows with '2010-prices, chained values'\n",
446 | "\n",
447 | "# f. only keep renamed variables\n",
448 | "\n",
449 | "# g. interactive plot\n",
450 | "# plot_timeseries(nan)"
451 | ]
452 | },
453 | {
454 | "cell_type": "markdown",
455 | "metadata": {},
456 | "source": [
457 | "**Answer:** see A11.py"
458 | ]
459 | },
460 | {
461 | "cell_type": "code",
462 | "execution_count": null,
463 | "metadata": {},
464 | "outputs": [],
465 | "source": [
466 | "plot_timeseries(nah1)"
467 | ]
468 | },
469 | {
470 | "cell_type": "markdown",
471 | "metadata": {},
472 | "source": [
473 | "# Extra problems"
474 | ]
475 | },
476 | {
477 | "cell_type": "markdown",
478 | "metadata": {},
479 | "source": [
480 | "## Extend interactive plot"
481 | ]
482 | },
483 | {
484 | "cell_type": "markdown",
485 | "metadata": {},
486 | "source": [
487 | "Extend the interactive plot with a choice of *real* vs *nominal*."
488 | ]
489 | },
490 | {
491 | "cell_type": "markdown",
492 | "metadata": {},
493 | "source": [
494 | "## New data set"
495 | ]
496 | },
497 | {
498 | "cell_type": "markdown",
499 | "metadata": {},
500 | "source": [
501 | "Load data from an Excel or CSV file you have downloaded from e.g. [Statistikbanken.dk](https://www.statistikbanken.dk/). Clean, structure and present the data as you see fit."
502 | ]
503 | }
504 | ],
505 | "metadata": {
506 | "kernelspec": {
507 | "display_name": "Python 3 (ipykernel)",
508 | "language": "python",
509 | "name": "python3"
510 | },
511 | "language_info": {
512 | "codemirror_mode": {
513 | "name": "ipython",
514 | "version": 3
515 | },
516 | "file_extension": ".py",
517 | "mimetype": "text/x-python",
518 | "name": "python",
519 | "nbconvert_exporter": "python",
520 | "pygments_lexer": "ipython3",
521 | "version": "3.11.5"
522 | },
523 | "toc-autonumbering": true
524 | },
525 | "nbformat": 4,
526 | "nbformat_minor": 4
527 | }
528 |
--------------------------------------------------------------------------------
/PS4/A1.py:
--------------------------------------------------------------------------------
1 | # a. load
2 | nah1_api = DstApi('NAH1')
3 | params = nah1_api._define_base_params(language='en')
4 | nah1_true = nah1_api.get_data(params=params)
5 |
6 | # b. rename and replace
7 | nah1_true.rename(columns=columns_dict,inplace=True)
8 |
9 | # c. replace data
10 | for key,value in var_dict.items():
11 | nah1_true.variable.replace(key,value,inplace=True)
12 |
13 | for key,value in unit_dict.items():
14 | nah1_true.unit.replace(key,value,inplace=True)
15 |
16 | # d. keep if in var_dict
17 | I = False
18 | for key,value in var_dict.items():
19 | I = I | (nah1_true.variable == value)
20 | nah1_true = nah1_true[I]
21 |
22 | # e. convert values to numeric
23 | nah1_true.value = nah1_true.value.astype('float')
24 |
25 | # d. summary statistics
26 | nah1_true.groupby(['variable','unit']).describe()
27 |
28 | # f. Sort by year
29 | nah1_true.sort_values(by='year',inplace=True)
--------------------------------------------------------------------------------
/PS4/A2.py:
--------------------------------------------------------------------------------
1 | merged_true = pd.merge(nah1_true,pop,how='left',on=['year'])
2 | merged_true.tail(10)
--------------------------------------------------------------------------------
/PS4/A3.py:
--------------------------------------------------------------------------------
1 | pop_with_index = pop.set_index('year')
2 | pop_with_index.rename(columns={'population':'population_alt'},inplace=True)
3 | merged_true_with_index = merged_true.set_index('year')
4 | merged_true_alt = merged_true_with_index.join(pop_with_index)
5 | merged_true_alt.sample(10)
--------------------------------------------------------------------------------
/PS4/A4.py:
--------------------------------------------------------------------------------
1 | nah1_true_alt = nah1_true.copy()
2 | grouped = nah1_true_alt.groupby(['variable','unit'])
3 | nah1_true_alt['index_transform'] = grouped['value'].transform(lambda x: x/first(x))
4 | nah1_true_alt.head()
--------------------------------------------------------------------------------
/PS4/A5.py:
--------------------------------------------------------------------------------
1 | # a. merge
2 | full = pd.merge(pop, prices_long, on=['date','municipality'], how='left')
3 | full.sort_values(['municipality','date'], inplace=True)
4 |
5 | # b. take logs
6 | full['log_population'] = np.log(full['population'])
7 | full['log_price'] = np.log(full['price'])
8 |
9 | full[['d_log_population','d_log_price']] = full.groupby('municipality')[['log_population','log_price']].diff(1)
10 |
11 | # c. figur 1: log differences
12 | ax = full.plot(x = 'd_log_population', y = 'd_log_price', kind = 'scatter',
13 | c='log_population',cmap='Blues',alpha=0.5);
14 |
15 | ax.set_xlabel('log difference in population')
16 | ax.set_ylabel('log difference in price');
--------------------------------------------------------------------------------
/PS4/A6.py:
--------------------------------------------------------------------------------
1 | # c. figur 2: mean log differences
2 | mean_diff = lambda x: np.mean(x.diff())
3 | full_grouped = full.groupby('municipality').agg({'log_population':[mean_diff,'last'],'log_price':mean_diff})
4 | full_grouped.columns = ['md_log_population','last_log_population','md_log_price']
5 |
6 | ax = full_grouped.plot(x = 'md_log_population', y = 'md_log_price', kind = 'scatter',
7 | c='last_log_population',cmap='Blues');
8 | ax.set_xlabel('within-municipality mean log difference in population')
9 | ax.set_ylabel('within-municipality mean log difference in price',fontsize=10);
--------------------------------------------------------------------------------
/PS4/data/bm010_ejer.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NumEconCopenhagen/IntroProg-exercises/0dee1719691f0f7cccb91cbf2a88f3a0c921fc74/PS4/data/bm010_ejer.xlsx
--------------------------------------------------------------------------------
/PS4/data/bm010_ejer_nedtagning.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NumEconCopenhagen/IntroProg-exercises/0dee1719691f0f7cccb91cbf2a88f3a0c921fc74/PS4/data/bm010_ejer_nedtagning.xlsx
--------------------------------------------------------------------------------
/PS4/data/bm010_parcel.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NumEconCopenhagen/IntroProg-exercises/0dee1719691f0f7cccb91cbf2a88f3a0c921fc74/PS4/data/bm010_parcel.xlsx
--------------------------------------------------------------------------------
/PS4/data/bm010_parcel_nedtagning.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NumEconCopenhagen/IntroProg-exercises/0dee1719691f0f7cccb91cbf2a88f3a0c921fc74/PS4/data/bm010_parcel_nedtagning.xlsx
--------------------------------------------------------------------------------
/PS5/A1.py:
--------------------------------------------------------------------------------
1 | def factorial(n):
2 | if n == 1:
3 | return 1
4 | else:
5 | return n*factorial(n-1)
6 |
7 | for n in [1,2,3,4,5]:
8 | y = factorial(n)
9 | print(f'the factorial of {n} is {y}')
10 | assert(y == math.factorial(n))
--------------------------------------------------------------------------------
/PS5/A2.py:
--------------------------------------------------------------------------------
1 | def swap(L,i,j):
2 | temp = L[i] # save value at i
3 | L[i] = L[j] # overwrite value at i with value at j
4 | L[j] = temp # write original value at i to value at j
5 |
6 | def bubble_sort(L):
7 | for k in range(len(L)-1,0,-1):
8 | for i in range(k):
9 | if L[i] < L[i+1]:
10 | swap(L,i,i+1)
11 |
12 |
--------------------------------------------------------------------------------
/PS5/A3.py:
--------------------------------------------------------------------------------
1 | def linear_search(L,x):
2 |
3 | # a. prep
4 | i = 0
5 | N = len(L)
6 | found = False
7 |
8 | # b. main
9 | while i < N-1 and not found:
10 | if x >= L[i] and x < L[i+1]: # comparison
11 | found = True
12 | else:
13 | i += 1 # increment
14 |
15 | # c. return
16 | return i
17 |
--------------------------------------------------------------------------------
/PS5/A4.py:
--------------------------------------------------------------------------------
1 | def bisection(f,a,b,tol=1e-8):
2 | """ bisection
3 |
4 | Solve equation f(x) = 0 for a <= x <= b.
5 |
6 | Args:
7 |
8 | f (function): function
9 | a (float): left bound
10 | b (float): right bound
11 | tol (float): tolerance on solution
12 |
13 | Returns:
14 |
15 | """
16 |
17 | # test inputs
18 | if f(a)*f(b) >= 0:
19 | print("bisection method fails.")
20 | return None
21 |
22 | # step 1: initialize
23 | a_n = a
24 | b_n = b
25 |
26 | # step 2-4:
27 | while True:
28 |
29 | # step 2: midpoint and associated value
30 | m_n = (a_n+b_n)/2
31 | f_m_n = f(m_n)
32 |
33 | # step 3: determine sub-interval
34 | if abs(f_m_n) < tol:
35 | return m_n
36 | elif f(a_n)*f_m_n < 0:
37 | a_n = a_n
38 | b_n = m_n
39 | elif f(b_n)*f_m_n < 0:
40 | a_n = m_n
41 | b_n = b_n
42 | else:
43 | print("bisection method fails.")
44 | return None
45 |
46 | return (a_n + b_n)/2
47 |
48 | result = bisection(f,0,1,1e-8)
49 | print(f'result is {result:.3f} with f({result:.3f}) = {f(result):.16f}')
--------------------------------------------------------------------------------
/PS5/A5.py:
--------------------------------------------------------------------------------
1 | def sieve(n):
2 | """ sieve of Eratosthenes
3 |
4 | Return all primes between 2 and n.
5 |
6 | Args:
7 |
8 | n (integer): maximum number to consider
9 |
10 | """
11 |
12 | # a. step 1: create list of potential primes
13 | primes = list(range(2,n+1))
14 |
15 | # b. step 2: initialize i
16 | index = 0
17 | i = primes[index]
18 |
19 | # c. step 3-6
20 | while i < math.sqrt(n):
21 |
22 | # step 3: remove
23 | k = i
24 | while i <= n:
25 | i += k
26 | if i in primes:
27 | primes.remove(i)
28 |
29 | # step 4: next number
30 | index += 1
31 |
32 | # step 5: set i
33 | i = primes[index]
34 |
35 | return primes
36 |
37 | print('primes from 2 to 100:',sieve(100))
--------------------------------------------------------------------------------
/PS5/problem_set_5.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Problem set 5: Writing your own algorithms"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "This problem set has no tasks, but only problems of increasing complexity. See how far you can get :)"
15 | ]
16 | },
17 | {
18 | "cell_type": "code",
19 | "execution_count": 1,
20 | "metadata": {},
21 | "outputs": [],
22 | "source": [
23 | "import math"
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "# Factorial"
31 | ]
32 | },
33 | {
34 | "cell_type": "markdown",
35 | "metadata": {},
36 | "source": [
37 | "Remember that the factorial of $n$ is\n",
38 | "\n",
39 | "$$\n",
40 | "n\\cdot(n-1)\\cdot(n-2)\\cdot...\\cdot 1\n",
41 | "$$\n",
42 | "\n",
43 | "**Problem:** Correct the following function so that it returns the factorial of n using *functional recursion*."
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": 2,
49 | "metadata": {},
50 | "outputs": [
51 | {
52 | "name": "stdout",
53 | "output_type": "stream",
54 | "text": [
55 | "5\n"
56 | ]
57 | }
58 | ],
59 | "source": [
60 | "def factorial(n):\n",
61 | " if n == 1:\n",
62 | " return 1\n",
63 | " else:\n",
64 | " return n # + missing code\n",
65 | " \n",
66 | "print(factorial(5))"
67 | ]
68 | },
69 | {
70 | "cell_type": "markdown",
71 | "metadata": {},
72 | "source": [
73 | "**Answer:** see A1.py"
74 | ]
75 | },
76 | {
77 | "cell_type": "markdown",
78 | "metadata": {},
79 | "source": [
80 | "# Descending bubble sort"
81 | ]
82 | },
83 | {
84 | "cell_type": "markdown",
85 | "metadata": {},
86 | "source": [
87 | "**Problem:** Sort a list of numbers in-place descending (from high to low).\n",
88 | "\n",
89 | "**Inputs:** List of numbers.\n",
90 | "\n",
91 | "**Outputs:** None.\n",
92 | "\n",
93 | "**Algorithm:** "
94 | ]
95 | },
96 | {
97 | "cell_type": "code",
98 | "execution_count": 4,
99 | "metadata": {},
100 | "outputs": [],
101 | "source": [
102 | "L = [54, 26, 93, 17, 77, 31, 44, 55, 20] # test list\n",
103 | "\n",
104 | "# write your code here (hint: use the bubble_sort() algorithm from the lectures)\n",
105 | "def bubble_sort(L):\n",
106 | " pass\n",
107 | "\n",
108 | "bubble_sort(L)\n",
109 | "print('sorted',L)"
110 | ]
111 | },
112 | {
113 | "cell_type": "markdown",
114 | "metadata": {},
115 | "source": [
116 | "**Answer:** see A2.py"
117 | ]
118 | },
119 | {
120 | "cell_type": "markdown",
121 | "metadata": {},
122 | "source": [
123 | "# Linear search for index"
124 | ]
125 | },
126 | {
127 | "cell_type": "markdown",
128 | "metadata": {},
129 | "source": [
130 | "**Problem:** Consider a number `x` and a sorted list of numbers `L`. Assume `L[0] <= x < L[-1]`. Find the index `i` such that `L[i] <= x < L[i+1]` using a linear search.\n",
131 | "\n",
132 | "**Inputs:** A sorted list of numbers `L` and a number `x`.\n",
133 | " \n",
134 | "**Outputs:** Integer."
135 | ]
136 | },
137 | {
138 | "cell_type": "code",
139 | "execution_count": 6,
140 | "metadata": {},
141 | "outputs": [],
142 | "source": [
143 | "L = [0, 1, 2, 8, 13, 17, 19, 32, 42] # test list\n",
144 | "\n",
145 | "# write your code here (hint: use the linear_seach() algorithm from the lecture)\n",
146 | "def linear_search(L,x):\n",
147 | " pass\n",
148 | "\n",
149 | "# test your function\n",
150 | "for x in [3,7,13,18,32]:\n",
151 | " i = linear_search(L,x)\n",
152 | " print(f'{x} gives the index {i}')\n",
153 | " assert(x >= L[i] and x < L[i+1]),(x,i,L[i])"
154 | ]
155 | },
156 | {
157 | "cell_type": "markdown",
158 | "metadata": {},
159 | "source": [
160 | "**Answer:** see A3.py"
161 | ]
162 | },
163 | {
164 | "cell_type": "markdown",
165 | "metadata": {},
166 | "source": [
167 | "# Bisection"
168 | ]
169 | },
170 | {
171 | "cell_type": "markdown",
172 | "metadata": {},
173 | "source": [
174 | "**Problem:** Find an (apporximate) solution to $f(x) = 0$ in the interval $[a,b]$ where $f(a)f(b) < 0$ (i.e. one is positive and the other is negative). \n",
175 | "\n",
176 | "> If $f$ is a *continuous* function then the intermediate value theorem ensures that a solution exists.\n",
177 | "\n",
178 | "**Inputs:** Function $f$, float interval $[a,b]$, float tolerance $\\epsilon > 0$.\n",
179 | "\n",
180 | "**Outputs:** Float.\n",
181 | "\n",
182 | "**Algorithm:** `bisection()`\n",
183 | "\n",
184 | "1. Set $a_0 = a$ and $b_0 = b$.\n",
185 | "\n",
186 | "2. Compute $f(m_0)$ where $m_0 = (a_0 + b_0)/2$ is the midpoint\n",
187 | "\n",
188 | "3. Determine the next sub-interval $[a_1,b_1]$:\n",
189 | "\n",
190 | " i. If $f(a_0)f(m_0) < 0$ then $a_1 = a_0$ and $b_1 = m_0$\n",
191 | "\n",
192 | " ii. If $f(m_0)f(b_0) < 0$ then $a_1 = m_0$ and $b_1 = b_0$\n",
193 | "\n",
194 | "4. Repeat step 2 and step 3 until $|f(m_n)| < \\epsilon$"
195 | ]
196 | },
197 | {
198 | "cell_type": "code",
199 | "execution_count": 8,
200 | "metadata": {},
201 | "outputs": [
202 | {
203 | "name": "stdout",
204 | "output_type": "stream",
205 | "text": [
206 | "None\n"
207 | ]
208 | }
209 | ],
210 | "source": [
211 | "f = lambda x: (2.1*x-1.7)*(x-3.3) # test function\n",
212 | "def bisection(f,a,b,tau):\n",
213 | " pass\n",
214 | " # write your code here\n",
215 | " \n",
216 | "result = bisection(f,0,1,1e-8)\n",
217 | "print(result)"
218 | ]
219 | },
220 | {
221 | "cell_type": "markdown",
222 | "metadata": {},
223 | "source": [
224 | "**Answer:** see A4.py"
225 | ]
226 | },
227 | {
228 | "cell_type": "markdown",
229 | "metadata": {},
230 | "source": [
231 | "# Find prime numbers (hard)"
232 | ]
233 | },
234 | {
235 | "cell_type": "markdown",
236 | "metadata": {},
237 | "source": [
238 | "**Goal:** Implement a function in Python for the sieve of Eratosthenes.\n",
239 | "\n",
240 | "The **sieve of Eratosthenes** is a simple algorithm for finding all prime numbers up to a specified integer. It was created by the ancient Greek mathematician Eratosthenes. The algorithm to find all the prime numbers less than or equal to a given integer $n$.\n",
241 | "\n",
242 | "**Algorithm:** `sieve_()`\n",
243 | "\n",
244 | "1. Create a list of integers from $2$ to $n$: $2, 3, 4, ..., n$ (all potentially primes)\n",
245 | "\n",
246 | " `primes = list(range(2,n+1))`\n",
247 | "\n",
248 | "2. Start with a counter $i$ set to $2$, i.e. the first prime number\n",
249 | "\n",
250 | "3. Starting from $i+i$, count up by $i$ and remove those numbers from the list, i.e. $2i$, $3i$, $4i$ etc.\n",
251 | "\n",
252 | " `primes.remove(i)`\n",
253 | " \n",
254 | "4. Find the first number of the list following $i$. This is the next prime number.\n",
255 | "\n",
256 | "5. Set $i$ to the number found in the previous step.\n",
257 | "\n",
258 | "6. Repeat steps 3-5 until $i$ is greater than $\\sqrt {n}$.\n",
259 | "7. All the numbers, which are still in the list, are prime numbers."
260 | ]
261 | },
262 | {
263 | "cell_type": "markdown",
264 | "metadata": {},
265 | "source": [
266 | "**A more detailed explanation:** See this [video](https://www.youtube.com/watch?v=klcIklsWzrY&feature=youtu.be)"
267 | ]
268 | },
269 | {
270 | "cell_type": "code",
271 | "execution_count": 10,
272 | "metadata": {},
273 | "outputs": [
274 | {
275 | "name": "stdout",
276 | "output_type": "stream",
277 | "text": [
278 | "None\n"
279 | ]
280 | }
281 | ],
282 | "source": [
283 | "def sieve(n):\n",
284 | " pass # write your code here\n",
285 | "\n",
286 | "print(sieve(100))"
287 | ]
288 | },
289 | {
290 | "cell_type": "markdown",
291 | "metadata": {},
292 | "source": [
293 | "**Answer:** see A5.py"
294 | ]
295 | },
296 | {
297 | "cell_type": "markdown",
298 | "metadata": {},
299 | "source": [
300 | "# More Problems"
301 | ]
302 | },
303 | {
304 | "cell_type": "markdown",
305 | "metadata": {},
306 | "source": [
307 | "See [Project Euler](https://projecteuler.net/about)."
308 | ]
309 | }
310 | ],
311 | "metadata": {
312 | "kernelspec": {
313 | "display_name": "Python 3 (ipykernel)",
314 | "language": "python",
315 | "name": "python3"
316 | },
317 | "language_info": {
318 | "codemirror_mode": {
319 | "name": "ipython",
320 | "version": 3
321 | },
322 | "file_extension": ".py",
323 | "mimetype": "text/x-python",
324 | "name": "python",
325 | "nbconvert_exporter": "python",
326 | "pygments_lexer": "ipython3",
327 | "version": "3.9.10"
328 | },
329 | "toc-autonumbering": true
330 | },
331 | "nbformat": 4,
332 | "nbformat_minor": 4
333 | }
334 |
--------------------------------------------------------------------------------
/PS6/A1.py:
--------------------------------------------------------------------------------
1 | X = linalg.det(linalg.inv(A@A))
2 | print(X)
--------------------------------------------------------------------------------
/PS6/A10.py:
--------------------------------------------------------------------------------
1 | for beta in betas:
2 | f = lambda k: (alpha*k**beta + (1-alpha))**(1/beta)
3 | obj_kss = lambda kss: kss - (s*f(kss) + (1-delta)*kss)/((1+g)*(1+n))
4 | result = optimize.root_scalar(obj_kss,bracket=[0.1,100],method='brentq')
5 | print(f'for beta = {beta:.3f} the steady state for k is',result.root)
--------------------------------------------------------------------------------
/PS6/A2.py:
--------------------------------------------------------------------------------
1 | xb = linalg.solve(A,b)
2 | xc = linalg.solve(A,c)
3 | xd = linalg.solve(A,d)
4 | print('b:',xb)
5 | print('c:',xc)
6 | print('d:',xd)
--------------------------------------------------------------------------------
/PS6/A3.py:
--------------------------------------------------------------------------------
1 | LU,piv = linalg.lu_factor(A) # only done once
2 | xb = linalg.lu_solve((LU,piv),b) # much faster than regular solve
3 | xc = linalg.lu_solve((LU,piv),c)
4 | xd = linalg.lu_solve((LU,piv),d)
5 | print('b:',xb)
6 | print('c:',xc)
7 | print('d:',xd)
--------------------------------------------------------------------------------
/PS6/A4.py:
--------------------------------------------------------------------------------
1 | import numecon_linalg
2 | Y = np.column_stack((F,e))
3 | numecon_linalg.gauss_jordan(Y)
4 | print('solution',Y[:,-1])
5 | assert np.allclose(F@Y[:,-1],e)
--------------------------------------------------------------------------------
/PS6/A5.py:
--------------------------------------------------------------------------------
1 | print('the limit is:')
2 | x = sm.symbols('x')
3 | sm.limit(sm.sin(x)/x,x,0)
4 |
5 | print('the derivative is')
6 | x = sm.symbols('x')
7 | sm.diff(sm.sin(2*x),x)
--------------------------------------------------------------------------------
/PS6/A6.py:
--------------------------------------------------------------------------------
1 | sm.solve(sm.sin(x)/x)
--------------------------------------------------------------------------------
/PS6/A7.py:
--------------------------------------------------------------------------------
1 | f = k**alpha
2 | ss = sm.Eq(k,(s*f+(1-delta)*k)/((1+n)*(1+g)))
3 | kss = sm.solve(ss,k)[0]
4 | kss
--------------------------------------------------------------------------------
/PS6/A8.py:
--------------------------------------------------------------------------------
1 | ss_func = sm.lambdify((s,g,n,delta,alpha),kss)
2 |
3 | # Evaluate function
4 | ss_func(0.2,0.02,0.01,0.1,1/3)
--------------------------------------------------------------------------------
/PS6/A9.py:
--------------------------------------------------------------------------------
1 | f = lambda k: k**alpha
2 | obj_kss = lambda kss: kss - (s*f(kss) + (1-delta)*kss)/((1+g)*(1+n))
3 | result = optimize.root_scalar(obj_kss,bracket=[0.1,100],method='brentq')
4 |
5 | print('the steady state for k is',result.root)
--------------------------------------------------------------------------------
/PS6/numecon_linalg.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import scipy as sp
3 | import sympy as sm
4 |
5 | def gauss_jordan(A,no_reduction=False):
6 | """ Gauss-Jordan elimination
7 |
8 | Convert a matrix to its row (reduced) echelon form.
9 |
10 | Args:
11 |
12 | A (ndarray): input matrix to work on in-place
13 | no_reduction (bool): stop when non-reduced echelon form is reached
14 |
15 | """
16 |
17 | n,_m = A.shape
18 |
19 | # row echelon form (Gauss elimination)
20 | for i in range(0, n):
21 |
22 | # a. search for maximum in this column
23 | maxrow = i + np.argmax(abs(A[i:,i]))
24 |
25 | # b. swap maximum row with current row (column by column)
26 | temp = A[maxrow,i:].copy()
27 | A[maxrow,i:] = A[i,i:]
28 | A[i,i:] = temp
29 |
30 | # b. make all rows below this one 0 in current column
31 | for k in range(i+1, n):
32 | c = -A[k,i]/A[i,i]
33 | A[k,i] = 0
34 | A[k,i+1:] += c*A[i,i+1:]
35 |
36 | if no_reduction:
37 | return
38 |
39 | # reduced row echelon form (Gauss-Jordan elimination)
40 | for i in range(n-1,-1,-1):
41 |
42 | # a. normalize this row
43 | c = A[i,i]
44 | A[i,:] /= c
45 |
46 | # b. make all rows above this one 0 in the current column
47 | for j in range(0,i):
48 | c = A[j,i]
49 | A[j,:] -= c*A[i,:]
50 |
51 | def gauss_seidel_split(A):
52 | """ split A matrix in additive lower and upper triangular matrices
53 |
54 | Args:
55 |
56 | A (ndarray): input matrix
57 |
58 | Returns:
59 |
60 | L (ndarray): lower triangular matrix
61 | U (ndarray): upper triangular matrix (zero diagonal)
62 |
63 | """
64 |
65 | L = np.tril(A)
66 | U = np.triu(A)
67 | np.fill_diagonal(U,0)
68 | return L,U
69 |
70 | def solve_with_forward_substitution(L,RHS):
71 | """ solve matrix equation with forward substitution
72 |
73 | Args:
74 |
75 | L (ndarray): lower triangular matrix
76 | RHS (ndarray): vector of right-hand-side variables
77 |
78 | Returns:
79 |
80 | x (ndarray): Solution vector
81 |
82 | """
83 |
84 | n = RHS.size
85 | x = np.zeros(n)
86 | for i in range(n):
87 | x[i] = RHS[i]
88 | for j in range(i):
89 | x[i] -= L[i,j]*x[j]
90 | x[i] /= L[i,i]
91 |
92 | return x
93 |
94 | def solve_with_backward_substitution(U,RHS):
95 | """ solve matrix equation with backward substitution
96 |
97 | Args:
98 |
99 | L (ndarray): uppper triangular matrix
100 | RHS (ndarray): vector of right-hand-side variables
101 |
102 | Returns:
103 |
104 | x (ndarray): Solution vector
105 |
106 | """
107 |
108 | n = RHS.size
109 | x = np.zeros(n)
110 | for i in reversed(range(n)):
111 | x[i] = RHS[i]
112 | for j in range(i+1,n):
113 | x[i] -= U[i,j]*x[j]
114 | x[i] /= U[i,i]
115 |
116 | return x
117 |
118 | def gauss_seidel(A,b,x0,max_iter=500,tau=10**(-8),do_print=False):
119 | """ solve matrix equation with Gauss-Seidel
120 |
121 | Args:
122 |
123 | A (ndarray): LHS matrix
124 | b (ndarray): RHS vector
125 | x0 (ndarray): guess on solution
126 | max_iter (int): maximum number of iterations (optional)
127 | tau (float): tolerance level
128 | do_print (bool): indicator for whether to print or not
129 |
130 | Returns:
131 |
132 | x (ndarray): Solution vector
133 |
134 | """
135 |
136 | converged = False
137 |
138 | # a. split
139 | L,U = gauss_seidel_split(A)
140 |
141 | # b. iterate
142 | x = x0
143 | i = 0
144 |
145 | if do_print:
146 | print(' ',x)
147 |
148 | while i < max_iter and not converged:
149 |
150 | # i. save previous
151 | x_prev = x
152 |
153 | # ii. compute RHS
154 | y = b-U@x
155 |
156 | # iii. solve with forward substituion
157 | x = solve_with_forward_substitution(L,y)
158 | #x = sp.linalg.solve_triangular(L,y,lower=True) # equivalent, but faster
159 |
160 | # iv. check convergence
161 | max_abs_diff = np.max(np.abs(x-x_prev))
162 | if max_abs_diff < tau:
163 | converged = True
164 |
165 | # v. misc
166 | if do_print:
167 | print(f'{i:2d}',x)
168 |
169 | i += 1
170 |
171 | return x
172 |
173 | def lu_decomposition(A):
174 | """ compute LU decomposition
175 |
176 | Args:
177 |
178 | A (ndarray): input matrix
179 |
180 | Returns:
181 |
182 | L (ndarray): lower triangular matrix
183 | U (ndarray): upper triangular matrix
184 |
185 | """
186 |
187 | n = len(A)
188 |
189 | # a. create zero matrices for L and U
190 | L = np.zeros((n,n))
191 | U = np.zeros((n,n))
192 |
193 | # b. set diagonal of L to one
194 | np.fill_diagonal(L,1)
195 |
196 | # c. perform the LU Decomposition
197 | for j in range(n):
198 |
199 | for i in range(j+1):
200 | c = U[:,j]@L[i,:]
201 | U[i][j] = A[i][j] - c
202 |
203 | for i in range(j, n):
204 | c = U[:j,j]@L[i,:j]
205 | L[i][j] = (A[i][j] - c) / U[j][j]
206 |
207 | return L,U
208 |
209 | def construct_sympy_matrix(positions,name='a'):
210 | """ construct sympy matrix with non-zero elements in positions
211 |
212 | Args:
213 |
214 | Positions (list): list of positions in strings, e.g. ['11','31']
215 |
216 | Returns:
217 |
218 | mat (sympy.matrix): Sympy Matrix
219 |
220 | """
221 |
222 | # a. dictionary of element with position as key and a_position as value
223 | entries = {f'{ij}':sm.symbols(f'{name}_{ij}') for ij in positions}
224 |
225 | # b. function for creating element or zero
226 | add = lambda x: entries[x] if x in entries else 0
227 |
228 | # c. create matrix
229 | mat_as_list = [[add(f'{1+i}{1+j}') for j in range(3)] for i in range(3)]
230 | mat = sm.Matrix(mat_as_list)
231 |
232 | return mat
233 |
234 | def fill_sympy_matrix(A_sm,A,name='a'):
235 |
236 | n,m = A.shape
237 |
238 | # a. make all substitution
239 | A_sm_copy = A_sm
240 | for i in range(n):
241 | for j in range(m):
242 | if not A[i,j] == 0:
243 | A_sm_copy = A_sm_copy.subs(f'{name}_{1+i}{1+j}',A[i,j])
244 |
245 | # b. lambdify with no inputs
246 | f = sm.lambdify((),A_sm_copy)
247 |
248 | # c. return filled matrix
249 | return f()
250 |
251 |
252 |
--------------------------------------------------------------------------------
/PS6/problem_set_6.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Problem set 6: Solving the Solow model"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 1,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import numpy as np\n",
17 | "from scipy import linalg\n",
18 | "from scipy import optimize\n",
19 | "import sympy as sm"
20 | ]
21 | },
22 | {
23 | "cell_type": "markdown",
24 | "metadata": {},
25 | "source": [
26 | "# Tasks"
27 | ]
28 | },
29 | {
30 | "cell_type": "markdown",
31 | "metadata": {},
32 | "source": [
33 | "## Solving matrix equations I"
34 | ]
35 | },
36 | {
37 | "cell_type": "code",
38 | "execution_count": 2,
39 | "metadata": {},
40 | "outputs": [],
41 | "source": [
42 | "np.random.seed(1900)\n",
43 | "n = 5\n",
44 | "A = np.random.uniform(size=(n,n))\n",
45 | "b = np.random.uniform(size=n)\n",
46 | "c = np.random.uniform(size=n)\n",
47 | "d = np.random.uniform(size=n)"
48 | ]
49 | },
50 | {
51 | "cell_type": "markdown",
52 | "metadata": {},
53 | "source": [
54 | "**Question A:** Find the determinant of $[A \\cdot A]^{-1}$"
55 | ]
56 | },
57 | {
58 | "cell_type": "code",
59 | "execution_count": 3,
60 | "metadata": {},
61 | "outputs": [],
62 | "source": [
63 | "# write your code here"
64 | ]
65 | },
66 | {
67 | "cell_type": "markdown",
68 | "metadata": {},
69 | "source": [
70 | "**Answer:** see A1.py"
71 | ]
72 | },
73 | {
74 | "cell_type": "markdown",
75 | "metadata": {},
76 | "source": [
77 | "**Question B:** Solve the following equation systems directly using **scipy**.\n",
78 | "\n",
79 | "$$\n",
80 | "\\begin{aligned}\n",
81 | "Ax &= b \\\\\n",
82 | "Ax &= c \\\\\n",
83 | "Ax &= d \n",
84 | "\\end{aligned}\n",
85 | "$$"
86 | ]
87 | },
88 | {
89 | "cell_type": "markdown",
90 | "metadata": {},
91 | "source": [
92 | "**Answer:** A2.py"
93 | ]
94 | },
95 | {
96 | "cell_type": "markdown",
97 | "metadata": {},
98 | "source": [
99 | "**Question C:** Solve the same equation systems as above using `linalg.lu_factor()` and `linalg.lu_solve()`. What is the benefit of this approach?"
100 | ]
101 | },
102 | {
103 | "cell_type": "markdown",
104 | "metadata": {},
105 | "source": [
106 | "**Answer:** A3.py"
107 | ]
108 | },
109 | {
110 | "cell_type": "markdown",
111 | "metadata": {},
112 | "source": [
113 | "## Solving matrix equations II"
114 | ]
115 | },
116 | {
117 | "cell_type": "code",
118 | "execution_count": 7,
119 | "metadata": {},
120 | "outputs": [],
121 | "source": [
122 | "F = np.array([[2.0, 1.0, -1.0], [-3.0, -1.0, 2], [-2.0, 1.0, 2.0]])\n",
123 | "e = np.array([8.0, -11.0, -3.0])"
124 | ]
125 | },
126 | {
127 | "cell_type": "markdown",
128 | "metadata": {},
129 | "source": [
130 | "**Question:** Use the function `gauss_jordan()` in the `numecon_linalg` module located in this folder to solve\n",
131 | "\n",
132 | "$$\n",
133 | "Fx = e\n",
134 | "$$"
135 | ]
136 | },
137 | {
138 | "cell_type": "code",
139 | "execution_count": 8,
140 | "metadata": {},
141 | "outputs": [],
142 | "source": [
143 | "# write your code here"
144 | ]
145 | },
146 | {
147 | "cell_type": "markdown",
148 | "metadata": {},
149 | "source": [
150 | "**Answer:** see A4.py"
151 | ]
152 | },
153 | {
154 | "cell_type": "markdown",
155 | "metadata": {},
156 | "source": [
157 | "## Symbolic"
158 | ]
159 | },
160 | {
161 | "cell_type": "markdown",
162 | "metadata": {},
163 | "source": [
164 | "**Question A:** Find\n",
165 | "\n",
166 | "$$\n",
167 | "\\lim_{x \\rightarrow 0} \\frac{\\sin(x)}{x}\n",
168 | "$$\n",
169 | "\n",
170 | "and\n",
171 | "\n",
172 | "$$\n",
173 | "\\frac{\\partial\\sin(2x)}{\\partial x} \n",
174 | "$$"
175 | ]
176 | },
177 | {
178 | "cell_type": "code",
179 | "execution_count": 10,
180 | "metadata": {},
181 | "outputs": [],
182 | "source": [
183 | "# write your code here"
184 | ]
185 | },
186 | {
187 | "cell_type": "markdown",
188 | "metadata": {},
189 | "source": [
190 | "**Answer:** A5.py"
191 | ]
192 | },
193 | {
194 | "cell_type": "markdown",
195 | "metadata": {},
196 | "source": [
197 | "**Question B:** Solve the equation\n",
198 | "\n",
199 | "$$ \n",
200 | "\\frac{\\sin(x)}{x} = 0\n",
201 | "$$"
202 | ]
203 | },
204 | {
205 | "cell_type": "code",
206 | "execution_count": 13,
207 | "metadata": {},
208 | "outputs": [],
209 | "source": [
210 | "# write your code here"
211 | ]
212 | },
213 | {
214 | "cell_type": "markdown",
215 | "metadata": {},
216 | "source": [
217 | "**Answer:** A6.py"
218 | ]
219 | },
220 | {
221 | "cell_type": "markdown",
222 | "metadata": {},
223 | "source": [
224 | "# Problem: Solve the Solow model"
225 | ]
226 | },
227 | {
228 | "cell_type": "markdown",
229 | "metadata": {},
230 | "source": [
231 | "## Introduction"
232 | ]
233 | },
234 | {
235 | "cell_type": "markdown",
236 | "metadata": {},
237 | "source": [
238 | "Consider the **standard Solow-model** where:\n",
239 | "\n",
240 | "1. $K_t$ is capital\n",
241 | "2. $L_t$ is labor (growing with a constant rate of $n$)\n",
242 | "3. $A_t$ is technology (growing with a constant rate of $g$)\n",
243 | "4. $Y_t = F(K_t,A_tL_t)$ is GDP\n",
244 | "\n",
245 | "**Saving** is a constant fraction of GDP\n",
246 | "\n",
247 | "$$ \n",
248 | "S_t = sY_t,\\,s\\in(0,1)\n",
249 | "$$\n",
250 | "\n",
251 | "such that **capital accumulates** according to\n",
252 | "\n",
253 | "$$\n",
254 | "K_{t+1}=S_{t}+(1-\\delta)K_{t}=sF(K_{t},A_{t}L_{t})+(1-\\delta)K_{t}, \\delta \\in (0,1)\n",
255 | "$$\n",
256 | "\n",
257 | "The **production function** has **constant-return to scale** such that\n",
258 | "\n",
259 | "$$\n",
260 | "\\frac{Y_{t}}{A_{t}L_{t}}=\\frac{F(K_{t},A_{t}L_{t})}{A_{t}L_{t}}=F(\\tilde{k}_{t},1)\\equiv f(\\tilde{k}_{t})\n",
261 | "$$\n",
262 | "\n",
263 | "where $\\tilde{k}_t = \\frac{K_t}{A_{t}L_{t}}$ is the technology adjusted capital-labor ratio.\n",
264 | "\n",
265 | "The **transition equation** then becomes\n",
266 | "\n",
267 | "$$\n",
268 | "\\tilde{k}_{t+1}= \\frac{1}{(1+n)(1+g)}[sf(\\tilde{k}_{t})+(1-\\delta)\\tilde{k}_{t}]\n",
269 | "$$\n",
270 | "\n",
271 | "If the **production function** is **Cobb-Douglas** then\n",
272 | "\n",
273 | "$$\n",
274 | "F(K_{t},A_{t}L_{t})=K_{t}^{\\alpha}(A_{t}L_{t})^{1-\\alpha}\\Rightarrow f(\\tilde{k}_{t})=\\tilde{k}_{t}^{\\alpha}\n",
275 | "$$\n",
276 | "\n",
277 | "If it is **CES** (with $\\beta < 1, \\beta \\neq 0$) then\n",
278 | "\n",
279 | "$$\n",
280 | "F(K_{t},A_{t}L_{t})=(\\alpha K_{t}^{\\beta}+(1-\\alpha)(A_{t}L_{t})^{\\beta})^{\\frac{1}{\\beta}}\\Rightarrow f(\\tilde{k}_{t})=(\\alpha\\tilde{k}_{t}^{\\beta}+(1-\\alpha))^{\\frac{1}{\\beta}}\n",
281 | "$$"
282 | ]
283 | },
284 | {
285 | "cell_type": "markdown",
286 | "metadata": {},
287 | "source": [
288 | "## Steady state"
289 | ]
290 | },
291 | {
292 | "cell_type": "markdown",
293 | "metadata": {},
294 | "source": [
295 | "Assume the production function is **Cobb-Douglas**."
296 | ]
297 | },
298 | {
299 | "cell_type": "markdown",
300 | "metadata": {},
301 | "source": [
302 | "**Question A:** Use **sympy** to find an analytical expression for the steady state, i.e. solve\n",
303 | "\n",
304 | "$$\n",
305 | "\\tilde{k}^{\\ast}= \\frac{1}{(1+n)(1+g)}[sf(\\tilde{k}^{\\ast})+(1-\\delta)\\tilde{k}^{\\ast}]\n",
306 | "$$"
307 | ]
308 | },
309 | {
310 | "cell_type": "code",
311 | "execution_count": 15,
312 | "metadata": {},
313 | "outputs": [],
314 | "source": [
315 | "k = sm.symbols('k')\n",
316 | "alpha = sm.symbols('alpha')\n",
317 | "delta = sm.symbols('delta')\n",
318 | "s = sm.symbols('s')\n",
319 | "g = sm.symbols('g')\n",
320 | "n = sm.symbols('n')"
321 | ]
322 | },
323 | {
324 | "cell_type": "code",
325 | "execution_count": 16,
326 | "metadata": {},
327 | "outputs": [],
328 | "source": [
329 | "# write your code here"
330 | ]
331 | },
332 | {
333 | "cell_type": "markdown",
334 | "metadata": {},
335 | "source": [
336 | "**Answer:** see A7.py"
337 | ]
338 | },
339 | {
340 | "cell_type": "markdown",
341 | "metadata": {},
342 | "source": [
343 | "**Question B:** Turn you solution into a Python function called as `ss_func(s,g,n,delta,alpha)`. "
344 | ]
345 | },
346 | {
347 | "cell_type": "code",
348 | "execution_count": 18,
349 | "metadata": {},
350 | "outputs": [],
351 | "source": [
352 | "# write your code here"
353 | ]
354 | },
355 | {
356 | "cell_type": "markdown",
357 | "metadata": {},
358 | "source": [
359 | "**Answer:** A8.py"
360 | ]
361 | },
362 | {
363 | "cell_type": "markdown",
364 | "metadata": {},
365 | "source": [
366 | "**Question C**: Find the steady state numerically using root-finding with `optimize.root_scalar`."
367 | ]
368 | },
369 | {
370 | "cell_type": "code",
371 | "execution_count": 21,
372 | "metadata": {},
373 | "outputs": [],
374 | "source": [
375 | "s = 0.2\n",
376 | "g = 0.02\n",
377 | "n = 0.01\n",
378 | "alpha = 1/3\n",
379 | "delta = 0.1\n",
380 | "\n",
381 | "# write your code here"
382 | ]
383 | },
384 | {
385 | "cell_type": "markdown",
386 | "metadata": {},
387 | "source": [
388 | "**Answer:** A9.py"
389 | ]
390 | },
391 | {
392 | "cell_type": "markdown",
393 | "metadata": {},
394 | "source": [
395 | "**Question D:** Now assume the production function is CES. Find the steady state for $k$ for the various values of $\\beta$ shown below."
396 | ]
397 | },
398 | {
399 | "cell_type": "code",
400 | "execution_count": 23,
401 | "metadata": {},
402 | "outputs": [],
403 | "source": [
404 | "betas = [-0.5,-0.25,-0.1,-0.05,0.05,0.1,0.25,0.5]\n",
405 | "\n",
406 | "# write your code here"
407 | ]
408 | },
409 | {
410 | "cell_type": "markdown",
411 | "metadata": {
412 | "tags": []
413 | },
414 | "source": [
415 | "**Answer:** A10.py "
416 | ]
417 | }
418 | ],
419 | "metadata": {
420 | "kernelspec": {
421 | "display_name": "Python 3 (ipykernel)",
422 | "language": "python",
423 | "name": "python3"
424 | },
425 | "language_info": {
426 | "codemirror_mode": {
427 | "name": "ipython",
428 | "version": 3
429 | },
430 | "file_extension": ".py",
431 | "mimetype": "text/x-python",
432 | "name": "python",
433 | "nbconvert_exporter": "python",
434 | "pygments_lexer": "ipython3",
435 | "version": "3.9.10"
436 | },
437 | "toc-autonumbering": true
438 | },
439 | "nbformat": 4,
440 | "nbformat_minor": 4
441 | }
442 |
--------------------------------------------------------------------------------
/PS7/A1.py:
--------------------------------------------------------------------------------
1 | # a. grids
2 | x1_vec = np.linspace(-2,2,500)
3 | x2_vec = np.linspace(-2,2,500)
4 | x1_grid,x2_grid = np.meshgrid(x1_vec,x2_vec,indexing='ij')
5 | f_grid = _f(x1_grid,x2_grid)
6 |
7 | # b. main
8 | fig = plt.figure(dpi = 100, figsize=(7,4))
9 | ax = fig.add_subplot(1,1,1,projection='3d')
10 | cs = ax.plot_surface(x1_grid,x2_grid,f_grid,cmap=cm.jet)
11 |
12 | # c. add labels
13 | ax.set_xlabel('$x_1$')
14 | ax.set_ylabel('$x_2$')
15 | ax.set_zlabel('$f$')
16 |
17 | # d. invert xaxis
18 | ax.invert_xaxis()
19 |
20 | # e. add colorbar
21 | fig.colorbar(cs);
--------------------------------------------------------------------------------
/PS7/A10.py:
--------------------------------------------------------------------------------
1 | # a. main
2 | fig = plt.figure()
3 | ax = fig.add_subplot(1,1,1,projection='3d')
4 | cs = ax.scatter(x0s[:,0],x0s[:,1],fs,c=fs);
5 |
6 | # b. add labels
7 | ax.set_xlabel('$x_1$')
8 | ax.set_ylabel('$x_2$')
9 | ax.set_zlabel('$f$')
10 |
11 | # c. invert xaxis
12 | ax.invert_xaxis()
13 |
14 | # d. colorbar
15 | fig.colorbar(cs);
--------------------------------------------------------------------------------
/PS7/A11.py:
--------------------------------------------------------------------------------
1 | # b. solve
2 | def solve(rho,beta,r,Delta,nu,kappa,v1):
3 |
4 | # a. solve period 2
5 | m2_vec,v2_vec,c2_vec = solve_period_2(rho,nu,kappa,Delta)
6 |
7 | # b. construct interpolator
8 | v2_interp = interpolate.RegularGridInterpolator((m2_vec,), v2_vec,
9 | bounds_error=False,fill_value=None)
10 |
11 | # b. solve period 1
12 | m1_vec,v1_vec,c1_vec = solve_period_1(rho,beta,r,Delta,v1,v2_interp)
13 |
14 | return m1_vec,c1_vec
15 |
16 | m1_vec,c1_vec = solve(rho,beta,r,Delta,nu,kappa,v1)
17 |
18 | # c. plot
19 | fig = plt.figure()
20 | ax = fig.add_subplot(1,1,1)
21 | ax.plot(m1_vec,c1_vec)
22 | ax.set_xlabel('$m_1$')
23 | ax.set_ylabel('$c_1$')
24 | ax.set_title('consumption function in period 1')
25 | ax.set_xlim([0,4])
26 | ax.set_ylim([0,2.5]);
--------------------------------------------------------------------------------
/PS7/A12.py:
--------------------------------------------------------------------------------
1 | def v1_alt(c1,m1,rho,beta,r,Delta,v2_interp):
2 |
3 | # a. expected v2 value
4 | Ra = (1+r)*(m1-c1)
5 | v2 = 0
6 | y2s = [1-np.sqrt(Delta),1-Delta,1+Delta,1+np.sqrt(Delta)]
7 | probs = [0.1,0.4,0.4,0.1]
8 | for y2,prob in zip(y2s,probs):
9 | m2 = Ra + y2
10 | v2 += prob*v2_interp([m2])[0]
11 |
12 | # b. total value
13 | return utility(c1,rho) + beta*v2
14 |
15 | m1_vec_alt,c1_vec_alt = solve(rho,beta,r,Delta,nu,kappa,v1_alt)
16 |
17 | # plot
18 | fig = plt.figure()
19 | ax = fig.add_subplot(1,1,1)
20 | ax.plot(m1_vec,c1_vec,label='original')
21 | ax.plot(m1_vec_alt,c1_vec_alt,label='new')
22 | ax.legend(loc='upper left')
23 | ax.set_xlabel('$m_1$')
24 | ax.set_ylabel('$c_1$')
25 | ax.set_title('consumption function in periode 1')
26 | ax.set_xlim([0,4])
27 | ax.set_ylim([0,2.5]);
--------------------------------------------------------------------------------
/PS7/A13.py:
--------------------------------------------------------------------------------
1 | # a. solve
2 | m2_vec,d2_vec,v2_grid,c2_grid = solve_period_2(alpha,rho,nu,kappa,Delta)
3 |
4 | # b. grids
5 | m2_grid,d2_grid = np.meshgrid(m2_vec,d2_vec,indexing='ij')
6 |
7 | # c. main
8 | fig = plt.figure()
9 | ax = fig.add_subplot(1,1,1,projection='3d')
10 | cs = ax.plot_surface(m2_grid,d2_grid,c2_grid,cmap=cm.jet)
11 |
12 | # d. add labels
13 | ax.set_xlabel('$m_2$')
14 | ax.set_ylabel('$d_2$')
15 | ax.set_zlabel('$c_2$')
16 |
17 | # e. invert xaxis
18 | ax.invert_xaxis()
19 |
20 | # f. add colorbar
21 | fig.colorbar(cs);
--------------------------------------------------------------------------------
/PS7/A14.py:
--------------------------------------------------------------------------------
1 | # a. define solve function
2 | def solve_period_1(alpha,rho,beta,r,Delta,v1,v2_interp):
3 |
4 | # a. grids
5 | m1_vec = np.linspace(1e-4,4,100)
6 | v1_vec = np.empty(100)
7 | c1_vec = np.empty(100)
8 | d1_vec = np.empty(100)
9 |
10 | # b. solve for each m1 in grid
11 | for i,m1 in enumerate(m1_vec):
12 |
13 | # i. objective
14 | obj = lambda x: -v1(x[0],x[1],m1,alpha,rho,beta,r,Delta,v2_interp)
15 |
16 | # ii. initial guess
17 | x0 = [m1*1/3,m1*1/3]
18 |
19 | # iii. bounds and constraitns
20 | bound = (1e-8,m1-1e-8)
21 | bounds = (bound, bound)
22 | ineq_con = {'type': 'ineq', 'fun': lambda x: m1-x[0]-x[1]}
23 |
24 | # iv. optimize
25 | result = optimize.minimize(obj,x0, method='SLSQP',
26 | bounds=bounds,
27 | constraints=[ineq_con])
28 |
29 | # v. save
30 | v1_vec[i] = -result.fun
31 | c1_vec[i] = result.x[0]
32 | d1_vec[i] = result.x[1]
33 |
34 | return m1_vec,v1_vec,c1_vec,d1_vec
35 |
36 | # b. construct interpolator
37 | v2_interp = interpolate.RegularGridInterpolator((m2_vec,d2_vec), v2_grid,
38 | bounds_error=False,fill_value=None)
39 |
40 | # c. solve period 1
41 | m1_vec,v1_vec,c1_vec,d1_vec = solve_period_1(alpha,rho,beta,r,Delta,v1,v2_interp)
42 |
43 | # d. plot
44 | fig = plt.figure()
45 | ax = fig.add_subplot(1,1,1)
46 | ax.plot(m1_vec,c1_vec,label='non-durable consumption')
47 | ax.plot(m1_vec_alt,d1_vec,label='durable consumption')
48 | ax.legend(loc='upper left')
49 | ax.set_xlabel('$m_1$')
50 | ax.set_xlim([0,4])
51 | ax.set_ylim([0,2.5]);
--------------------------------------------------------------------------------
/PS7/A2.py:
--------------------------------------------------------------------------------
1 | fig = plt.figure(dpi = 100, figsize=(7,4))
2 | ax = fig.add_subplot(1,1,1)
3 | levels = np.sort([j*10**(-i) for i in [-1,0,1,2,3,4] for j in [0.5,1,1.5]])
4 | cs = ax.contour(x1_grid,x2_grid,f_grid,levels=levels,cmap=cm.jet)
5 | fig.colorbar(cs);
--------------------------------------------------------------------------------
/PS7/A3.py:
--------------------------------------------------------------------------------
1 | _f1 = sm.lambdify((x1,x2),f1)
2 | _f2 = sm.lambdify((x1,x2),f2)
3 | _f11 = sm.lambdify((x1,x2),f11)
4 | _f12 = sm.lambdify((x1,x2),f12)
5 | _f21 = sm.lambdify((x1,x2),f21)
6 | _f22 = sm.lambdify((x1,x2),f22)
7 |
8 | def f_jac(x):
9 | return np.array([_f1(x[0],x[1]),_f2(x[0],x[1])])
10 |
11 | def f_hess(x):
12 | row1 = [_f11(x[0],x[1]),_f12(x[0],x[1])]
13 | row2 = [_f21(x[0],x[1]),_f22(x[0],x[1])]
14 | return np.array([row1,row2])
15 |
--------------------------------------------------------------------------------
/PS7/A4.py:
--------------------------------------------------------------------------------
1 | print('Nelder-Mead:')
2 | evals = 0
3 | result = optimize.minimize(f_python,x0,method='Nelder-Mead',callback=collect,options={'disp':True})
4 | contour()
--------------------------------------------------------------------------------
/PS7/A5.py:
--------------------------------------------------------------------------------
1 | print('BFGS without analytical gradient:')
2 |
3 | evals = 0
4 | result = optimize.minimize(f_python,x0,method='BFGS',callback=collect,options={'disp':True})
5 | contour()
--------------------------------------------------------------------------------
/PS7/A6.py:
--------------------------------------------------------------------------------
1 | print('BFGS with analytical gradient:')
2 |
3 | evals = 0
4 | result = optimize.minimize(f_python,x0,jac=f_jac,method='BFGS',callback=collect,options={'disp':True})
5 | contour()
--------------------------------------------------------------------------------
/PS7/A7.py:
--------------------------------------------------------------------------------
1 | print('Newton-CG with analytical gradient and hessian:')
2 |
3 | evals = 0
4 | result = optimize.minimize(f_python,x0,jac=f_jac,hess=f_hess,method='Newton-CG',callback=collect,options={'disp':True})
5 | contour()
--------------------------------------------------------------------------------
/PS7/A8.py:
--------------------------------------------------------------------------------
1 | fopt = np.inf
2 | xopt = np.nan
3 | for i,x0 in enumerate(x0s):
4 |
5 | # a. optimize
6 | result = optimize.minimize(f_python,x0,method='BFGS')
7 | xs[i,:] = result.x
8 | fs[i] = result.fun
9 |
10 | # b. print first 20 or if better than seen yet
11 | if i < 20 or fs[i] < fopt: # plot 20 first or if improving
12 | if fs[i] < fopt:
13 | xopt = xs[i,:]
14 | fopt = fs[i]
15 | print(f'{i:4d}: x0 = ({x0[0]:6.2f},{x0[0]:6.2f})',end='')
16 | print(f' -> converged at ({xs[i][0]:6.2f},{xs[i][1]:6.2f}) with f = {fs[i]:.12f}')
17 |
18 | # best solution
19 | print(f'\nbest solution:\n x = ({xopt[0]:6.2f},{xopt[1]:6.2f}) -> f = {fopt:.12f}')
--------------------------------------------------------------------------------
/PS7/A9.py:
--------------------------------------------------------------------------------
1 | # a. main
2 | fig = plt.figure()
3 | ax = fig.add_subplot(1,1,1,projection='3d')
4 | cs = ax.scatter(xs[:,0],xs[:,1],fs,c=fs);
5 |
6 | # b. add labels
7 | ax.set_xlabel('$x_1$')
8 | ax.set_ylabel('$x_2$')
9 | ax.set_zlabel('$f$')
10 |
11 | # c. invert xaxis
12 | ax.invert_xaxis()
13 |
14 | # d. colorbar
15 | fig.colorbar(cs);
--------------------------------------------------------------------------------
/PS7/contourplot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NumEconCopenhagen/IntroProg-exercises/0dee1719691f0f7cccb91cbf2a88f3a0c921fc74/PS7/contourplot.png
--------------------------------------------------------------------------------
/PS7/surfaceplot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NumEconCopenhagen/IntroProg-exercises/0dee1719691f0f7cccb91cbf2a88f3a0c921fc74/PS7/surfaceplot.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [Visit course page](https://sites.google.com/view/numeconcph-introprog/home)
--------------------------------------------------------------------------------