├── .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) --------------------------------------------------------------------------------