diff --git a/synced_files/GA_1_7/Solution/Discharge/Analysis_discharge_solution.ipynb b/synced_files/GA_1_7/Solution/Discharge/Analysis_discharge_solution.ipynb index 54cef162c5890f39f48e260612e658e4c83396f0..b7c6680649fccc678d110e1828870c95297eddaa 100644 --- a/synced_files/GA_1_7/Solution/Discharge/Analysis_discharge_solution.ipynb +++ b/synced_files/GA_1_7/Solution/Discharge/Analysis_discharge_solution.ipynb @@ -606,7 +606,7 @@ }, { "cell_type": "markdown", - "id": "f287dc3c", + "id": "f6f76cd1", "metadata": {}, "source": [ "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", diff --git a/synced_files/GA_1_7/Solution/Emissions/Analysis_emissions_solution.ipynb b/synced_files/GA_1_7/Solution/Emissions/Analysis_emissions_solution.ipynb index a251610818aa30e9cb652846e5b64912ec5dd16a..a7c57898957abcf2298ad14051d6ef93b8778347 100644 --- a/synced_files/GA_1_7/Solution/Emissions/Analysis_emissions_solution.ipynb +++ b/synced_files/GA_1_7/Solution/Emissions/Analysis_emissions_solution.ipynb @@ -159,7 +159,7 @@ }, { "cell_type": "markdown", - "id": "bae33376", + "id": "c8d54b28", "metadata": {}, "source": [ "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", @@ -262,7 +262,7 @@ }, { "cell_type": "markdown", - "id": "b433f6d0", + "id": "5d9ada72", "metadata": {}, "source": [ "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", @@ -374,7 +374,7 @@ { "cell_type": "code", "execution_count": null, - "id": "bd478d76", + "id": "757c95b3", "metadata": {}, "outputs": [], "source": [ @@ -437,7 +437,7 @@ }, { "cell_type": "markdown", - "id": "788aa9ad", + "id": "d8cc4f5f", "metadata": {}, "source": [ "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", @@ -538,7 +538,7 @@ }, { "cell_type": "markdown", - "id": "202f42e6", + "id": "b55ee61f", "metadata": {}, "source": [ "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", @@ -552,7 +552,7 @@ }, { "cell_type": "markdown", - "id": "504d090e", + "id": "f83ad575", "metadata": {}, "source": [ "If you run the code in the cell below, you will obtain a scatter plot of both variables. Explore the relationship between both variables and answer the following questions:\n", @@ -573,7 +573,7 @@ { "cell_type": "code", "execution_count": null, - "id": "48f9bc6c", + "id": "ae4183c0", "metadata": {}, "outputs": [], "source": [ @@ -589,7 +589,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2c41c5ed", + "id": "0ef1780b", "metadata": {}, "outputs": [], "source": [ @@ -602,7 +602,7 @@ }, { "cell_type": "markdown", - "id": "bffaa549", + "id": "3d833323", "metadata": {}, "source": [ "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", diff --git a/synced_files/GA_1_7/Solution/Force/Analysis_force_solution.ipynb b/synced_files/GA_1_7/Solution/Force/Analysis_force_solution.ipynb index 72e6196b5db49515a87dd3a3ff2f0503e9af404c..3f3eb26a1d8dd5578fb782fe6b243876780957c2 100644 --- a/synced_files/GA_1_7/Solution/Force/Analysis_force_solution.ipynb +++ b/synced_files/GA_1_7/Solution/Force/Analysis_force_solution.ipynb @@ -164,7 +164,7 @@ }, { "cell_type": "markdown", - "id": "ec00df4e", + "id": "5f1b8b0a", "metadata": {}, "source": [ "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", @@ -269,7 +269,7 @@ }, { "cell_type": "markdown", - "id": "9930cfcc", + "id": "9a07b86c", "metadata": {}, "source": [ "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", @@ -382,7 +382,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2e4f160f", + "id": "223bf52f", "metadata": {}, "outputs": [], "source": [ @@ -445,7 +445,7 @@ }, { "cell_type": "markdown", - "id": "e9ba432b", + "id": "ae5dd331", "metadata": {}, "source": [ "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", @@ -546,7 +546,7 @@ }, { "cell_type": "markdown", - "id": "169a87ff", + "id": "3998ff99", "metadata": {}, "source": [ "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", @@ -561,7 +561,7 @@ }, { "cell_type": "markdown", - "id": "492a0d05", + "id": "932c677b", "metadata": {}, "source": [ "If you run the code in the cell below, you will obtain a scatter plot of both variables. Explore the relationship between both variables and answer the following questions:\n", @@ -582,7 +582,7 @@ { "cell_type": "code", "execution_count": null, - "id": "df898022", + "id": "04ad887c", "metadata": {}, "outputs": [], "source": [ @@ -598,7 +598,7 @@ { "cell_type": "code", "execution_count": null, - "id": "872ca02f", + "id": "3f774da1", "metadata": {}, "outputs": [], "source": [ @@ -611,7 +611,7 @@ }, { "cell_type": "markdown", - "id": "ef0a83d0", + "id": "b1fe4208", "metadata": {}, "source": [ "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", diff --git a/synced_files/GA_1_7/Student/Discharge/Analysis_discharge.ipynb b/synced_files/GA_1_7/Student/Discharge/Analysis_discharge.ipynb index 8512bd3834384ad72e54a6de8a5e22009fbbcaee..f70634b66d146c274577586dd1e050920b29bd5c 100644 --- a/synced_files/GA_1_7/Student/Discharge/Analysis_discharge.ipynb +++ b/synced_files/GA_1_7/Student/Discharge/Analysis_discharge.ipynb @@ -384,7 +384,7 @@ }, { "cell_type": "markdown", - "id": "e6e7eae3", + "id": "8f0f9b25", "metadata": {}, "source": [ "If you run the code in the cell below, you will obtain a scatter plot of both variables. Explore the relationship between both variables and answer the following questions:\n", @@ -405,7 +405,7 @@ { "cell_type": "code", "execution_count": null, - "id": "a452a3e3", + "id": "6df89b84", "metadata": {}, "outputs": [], "source": [ @@ -421,7 +421,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7a4cfc54", + "id": "7f564803", "metadata": {}, "outputs": [], "source": [ diff --git a/synced_files/GA_1_7/Student/Emissions/Analysis_emissions.ipynb b/synced_files/GA_1_7/Student/Emissions/Analysis_emissions.ipynb index 594212be9364197f03b869b28ebe964f26259ca7..c0ead1feea1896a5ce1611a80cf56998a3ff73b6 100644 --- a/synced_files/GA_1_7/Student/Emissions/Analysis_emissions.ipynb +++ b/synced_files/GA_1_7/Student/Emissions/Analysis_emissions.ipynb @@ -378,7 +378,7 @@ }, { "cell_type": "markdown", - "id": "3376e69c", + "id": "484416fa", "metadata": {}, "source": [ "If you run the code in the cell below, you will obtain a scatter plot of both variables. Explore the relationship between both variables and answer the following questions:\n", @@ -399,7 +399,7 @@ { "cell_type": "code", "execution_count": null, - "id": "428ab6d7", + "id": "855fd85e", "metadata": {}, "outputs": [], "source": [ @@ -415,7 +415,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ab0636fd", + "id": "7750ec99", "metadata": {}, "outputs": [], "source": [ diff --git a/synced_files/GA_1_7/Student/Force/Analysis_force.ipynb b/synced_files/GA_1_7/Student/Force/Analysis_force.ipynb index 2e21799c0c27e6ed442f95a361ce7d1c8a72d045..c9e651957577b3e5a57ebf99ed68c6123d3ae948 100644 --- a/synced_files/GA_1_7/Student/Force/Analysis_force.ipynb +++ b/synced_files/GA_1_7/Student/Force/Analysis_force.ipynb @@ -384,7 +384,7 @@ }, { "cell_type": "markdown", - "id": "8a786297", + "id": "6355b398", "metadata": {}, "source": [ "If you run the code in the cell below, you will obtain a scatter plot of both variables. Explore the relationship between both variables and answer the following questions:\n", @@ -405,7 +405,7 @@ { "cell_type": "code", "execution_count": null, - "id": "84d99a02", + "id": "3b58197f", "metadata": {}, "outputs": [], "source": [ @@ -421,7 +421,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2e3aa9b8", + "id": "272a6471", "metadata": {}, "outputs": [], "source": [ diff --git a/synced_files/GA_1_7/Unused/Temp/Distribution_Fitting_T.ipynb b/synced_files/GA_1_7/Unused/Temp/Distribution_Fitting_T.ipynb index 0caee1ef50bc8952edf5820bfec74aaad079367c..346aec8dec5c19515e73af738d166fc84f402e07 100644 --- a/synced_files/GA_1_7/Unused/Temp/Distribution_Fitting_T.ipynb +++ b/synced_files/GA_1_7/Unused/Temp/Distribution_Fitting_T.ipynb @@ -163,7 +163,7 @@ }, { "cell_type": "markdown", - "id": "cd74f73b", + "id": "399bd407", "metadata": {}, "source": [ "<div style=\"background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", @@ -263,7 +263,7 @@ }, { "cell_type": "markdown", - "id": "36a58511", + "id": "02108738", "metadata": {}, "source": [ "<div style=\"background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", @@ -372,7 +372,7 @@ { "cell_type": "code", "execution_count": null, - "id": "45a44b5f", + "id": "b9d941f9", "metadata": {}, "outputs": [], "source": [ @@ -434,7 +434,7 @@ }, { "cell_type": "markdown", - "id": "9866e568", + "id": "e8444d97", "metadata": {}, "source": [ "<div style=\"background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", @@ -533,7 +533,7 @@ }, { "cell_type": "markdown", - "id": "49f10b00", + "id": "3fc044e0", "metadata": {}, "source": [ "<div style=\"background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", @@ -546,7 +546,7 @@ }, { "cell_type": "markdown", - "id": "63c79077", + "id": "87e883b9", "metadata": {}, "source": [ "If you run the code in the cell below, you will obtain a scatter plot of both variables. Explore the relationship between both variables and answer the following questions:\n", @@ -567,7 +567,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1bcf6eba", + "id": "68891ba8", "metadata": {}, "outputs": [], "source": [ diff --git a/synced_files/Week_2_2/old/PA_2_1_solution_sympy.ipynb b/synced_files/Week_2_2/old/PA_2_1_solution_sympy.ipynb index faafe9ceeb5a9d3dc5fc7115e0458872d3e230a7..9a97ff0968c9171492d88c1338311494cedc125c 100644 --- a/synced_files/Week_2_2/old/PA_2_1_solution_sympy.ipynb +++ b/synced_files/Week_2_2/old/PA_2_1_solution_sympy.ipynb @@ -404,7 +404,7 @@ }, { "cell_type": "markdown", - "id": "65acb0cf", + "id": "e0048850", "metadata": {}, "source": [ "You could also solve this problem using sympy! What would be the benefit of doing this? Check below how long it will take! You won't need timeit for this one..." @@ -413,7 +413,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d9d979b9", + "id": "e0c89f38", "metadata": {}, "outputs": [], "source": [ @@ -423,7 +423,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6c3ac9c0", + "id": "08512ff9", "metadata": {}, "outputs": [], "source": [ @@ -433,7 +433,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b45c5bd7", + "id": "1881a0cf", "metadata": {}, "outputs": [], "source": [ @@ -445,7 +445,7 @@ { "cell_type": "code", "execution_count": null, - "id": "238a5b95", + "id": "e73d630e", "metadata": {}, "outputs": [], "source": [ @@ -456,7 +456,7 @@ { "cell_type": "code", "execution_count": null, - "id": "bfa443a5", + "id": "3b74274b", "metadata": {}, "outputs": [], "source": [ @@ -465,7 +465,7 @@ }, { "cell_type": "markdown", - "id": "679b29c0", + "id": "bd15df9c", "metadata": {}, "source": [ "What is the result for the 501th value using float values?" @@ -474,7 +474,7 @@ { "cell_type": "code", "execution_count": null, - "id": "52ae39ca", + "id": "451142cf", "metadata": {}, "outputs": [], "source": [ @@ -514,7 +514,7 @@ }, { "cell_type": "markdown", - "id": "57f347bb", + "id": "0943c1d7", "metadata": {}, "source": [] } diff --git a/synced_files/Week_2_2/old/old_PA10_solution_sympy.ipynb b/synced_files/Week_2_2/old/old_PA10_solution_sympy.ipynb index 7c8be744662a220ceeff3f51efaa6b91a697f0b6..4b937f5b98bc7767b882f03569223b5daf4ab524 100644 --- a/synced_files/Week_2_2/old/old_PA10_solution_sympy.ipynb +++ b/synced_files/Week_2_2/old/old_PA10_solution_sympy.ipynb @@ -404,7 +404,7 @@ }, { "cell_type": "markdown", - "id": "7ecd53fd", + "id": "db1d78e1", "metadata": {}, "source": [ "You could also solve this problem using sympy! What would be the benefit of doing this? Check below how long it will take! You won't need timeit for this one..." @@ -413,7 +413,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2f6a23bb", + "id": "71a7541a", "metadata": {}, "outputs": [], "source": [ @@ -423,7 +423,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1ac00960", + "id": "893c8871", "metadata": {}, "outputs": [], "source": [ @@ -433,7 +433,7 @@ { "cell_type": "code", "execution_count": null, - "id": "236cef8b", + "id": "c7e2f62a", "metadata": {}, "outputs": [], "source": [ @@ -445,7 +445,7 @@ { "cell_type": "code", "execution_count": null, - "id": "35cf64c9", + "id": "038855e1", "metadata": {}, "outputs": [], "source": [ @@ -456,7 +456,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d300aab0", + "id": "4f35fd98", "metadata": {}, "outputs": [], "source": [ @@ -465,7 +465,7 @@ }, { "cell_type": "markdown", - "id": "fdb9b881", + "id": "7be33885", "metadata": {}, "source": [ "What is the result for the 501th value using float values?" @@ -474,7 +474,7 @@ { "cell_type": "code", "execution_count": null, - "id": "742aa988", + "id": "903fffb7", "metadata": {}, "outputs": [], "source": [ @@ -514,7 +514,7 @@ }, { "cell_type": "markdown", - "id": "1c64419b", + "id": "d795b2b5", "metadata": {}, "source": [] } diff --git a/synced_files/students/GA_2_3/Analysis.ipynb b/synced_files/students/GA_2_3/Analysis.ipynb deleted file mode 100644 index 647c9ed4a717419a8ebc582500dddb5e19bc02cc..0000000000000000000000000000000000000000 --- a/synced_files/students/GA_2_3/Analysis.ipynb +++ /dev/null @@ -1,899 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# GA 2.3: Beam Beats\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px\"\\>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px\"\\>\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): week 2.3. Due: Friday, November 29, 2024.*" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Analyzing cantilever-beam accelerations and global Mean Sea-Level measurements\n", - "\n", - "This project covers the week on Signal Processing (week 2.3).\n", - "\n", - "As a warming up you will create and analyze some elementary signals yourself, and next, you will carry out frequency domain analyses on two given data-sets, namely acceleration measurements of a Cantilever-Beam experiment, and (in optional Task 10) Global Mean Sea-Level measurements.\n", - "\n", - "Most of the Tasks in this notebook consist of both coding, producing a plot, and answering (open) questions. Typically, as you work your way through the Tasks, you can often re-use code, or part of it, from earlier Tasks and assignments. That will save you a lot of work!!" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "0491cc69" - }, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\"> <p>In many of the code blocks below, template code to create figures is provided. Note that there is a lot of code missing, and one line of <code>YOUR_CODE_HERE</code> does not imply that only one line of code is missing!</p></div>" - ] - }, - { - "attachments": { - "verticalcantileverbeam.png": { - "image/png": "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Bi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYu68871yOIGeEoz7tX/7riWj6Ftnwebfk82vJ5tOXzaMvnsU3LRebfAIt+pFUH3+/odQ/8sOan9eo/X2TVwfc7et0DP6yP6Vl9+I+XWXXw/Y5e98CP6tWntei9ZtXB9zt63QM/rNfpWS1Muebg+x297oEf1vyxsehprTr4fkeve+CHNT+tfuuJ58fGx6Knterg+x297oEf1fwNYNGXuVUH3+/odQ/8sPqt52nMHxuLntaqg+939LoHfljz01r0sbHq4Psdve6BH9b8sbHoaa06uN96rqvfep5Gv/U8jfljY9HTWnXw/Y5e98APa35aiz42Vh18v6PXPfDDmj82Fj2tVQf3W8+VzU/Lf7zMqoPvd/S6B35U/dbzNOaPjUVPa9XB9zt63QM/rKZ8GvPTWvQNYNXB9zt63QM/rH7reRb91vM0mvJpzB8bi57WqoPvd/S6B35Y89Pqt5548zeARU9r1cH3O3rdAz+q/mXl0+i3nqcxf2wselqrDr7f0ese+GHNT2vRx8aqg+939LoHfljzx8aip7Xq4H7rua5+63ka/dbzNOaPjUVPa9XB9zt63QM/rPlpLfrYWHXw/Y5e98APa/7YWPS0Vh3cbz3X1W89T6Pfep7G/LGx6GmtOvh+R6974Ic1P61FHxurDr7f0ese+GH5tJZ9A1h18P2OXvfAD2vVN4B1Xx/udnS/9Rzpt56H4u/QZU9r1cH3O3rdAz+u6ffowqe16uD7Hb3ugR/Y+MQWfwNYdfD9jl73wA/sfc03gFUH3+/odQ9ctaU/f/4PDvMXtjrnOloAAAAASUVORK5CYII=" - } - }, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Data Acquisition System\n", - "\n", - "A data acquisition (DAQ) system usually consists of four components:\n", - "\n", - "<img src=\"https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/DAQ.png\" style=\"margin:auto\"/>\n", - "\n", - "\n", - "- A sensor transforms a physical signal into a small voltage. The transformation is often frequency dependent or nonlinear, and can show drift or bias.\n", - "- Signal conditioning electronics (often included in the sensor housing) filter unwanted frequencies, such as the 50 Hz line frequency caused by power plant generators, using low-pass or notch filters. In addition the sensor voltage may be amplified.\n", - "- An analog-to-digital (A/D) converter samples the analog voltage with a certain rate, such as 100 Hz. The A/D converter can measure analog voltages within a certain range, the measurement range. The measured voltage is quantized with a certain resolution, such as 14-bit, which means that the full measurement range is divided into $2^{14}=16,384$ discrete intervals. Together, the resolution and measurement range determine the precision. Usually the sample rate, the measurement range, and the sample resolution are configurable. Sampling and quantizing together turns an analog signal into a digital signal.\n", - "- A digital computer reads the sampled data from the A/D converter at specific times, and allows for further processing, analysis and storage of the (digital) signal.\n", - "\n", - "The result is that an analog, physical signal, is turned into a series of numbers (samples of the signal, in the time domain), ready for processing and analysis in a digital computer.\n", - "\n", - "\n", - "\n", - "One of the data sets that you will analyze during this MUDE Q2 project was acquired by an accelerometer in a smartphone, on top of a vertical cantilever-beam. The accelerometer measures the side-ward accelerations, expressed in m/s<sup>2</sup>, and sampled at 50 Hz. Detailed information about the experiment and the sensor can be found in \"Experimental evaluation of smartphone accelerometer and low-cost dual frequency GNSS sensors for deformation monitoring\", by Alexandru Lapadat, Christian Tiberius and Peter Teunissen, Sensors 2021, 21, 7946, https://doi.org/10.3390/s21237946.\n", - "\n", - "A quick impression of the test setup can be gained by watching the short video [Cantilever Beam Experiment](https://youtu.be/o4moRwvlBLU?si=aKelBMWm3HB2Of26) (1 minute).\n", - "\n", - "A theoretical description of the motion of the smartphone accelerometer fixed to the cantilever beam is presented in Appendix A. Pulling the beam at the tip and releasing it, results in a (nearly) horizontal side-ward motion of the smartphone, and the (horizontal) position can be described by a *damped harmonic* as a function of time. Consequently, also the first and second derivative with respect to time, the velocity and acceleration as a function of time as the smartphone will measure it, are harmonics.\n", - "\n", - "### Basic sinusoid signal\n", - "\n", - "You will start with first creating (and analyzing) a few simple signals yourself. In the first few Tasks of this project, we will take the damping ratio zero and use a fairly short measurement time (duration), and hence the acceleration measured by the smartphone is a plain (undamped) sinusoid as shown in Appendix A (a stationary signal). In the following Tasks we also add a phase offset $\\varphi$ to the plain sinusoid:\n", - "\n", - "$$\n", - "x(t) = A \\sin(2 \\pi f_c t + \\varphi)\n", - "$$\n", - "\n", - "The result is taken from the last equation in Appendix A. We consider here acceleration, though for convenience, we omit the dots on top of the $x(t)$." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import matplotlib.pyplot as plt\n", - "\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 1:</b>\n", - "\n", - "- Create a time-array starting at $t=0$ s, ending at $t=5.0$ s, with a sampling rate of 100 Hz. Hint: what is the number of samples $N$? And what should then be the last value in the time-array? Note that, for example, with $N=10$ samples at a sampling rate of $f_s = 100$ Hz, we have signal samples at times $t=0.00, 0.01, 0.02, ... , 0.08, 0.09$ seconds, hence $T_{meas}= N \\Delta t =0.1$ seconds (the sample-and-hold convention).\n", - "- Create a sinusoidal signal $x(t) = A \\sin(2 \\pi f_c t + \\varphi)$, with amplitude $A=1.0$ Volt, carrier frequency $f_c=1.0$ Hz, and initial phase $\\varphi = 5$ degrees, to be converted into radians.\n", - "- Make a plot of the signal against time. Note that this is strictly a *sampled signal* $x_n$ rather than $x(t)$, but since we use a rather high sampling rate, the signal shown is close to continuous in time. Connecting the sample points of $x_n$ in the graph by lines, as done in the graph below, corroborates the suggestion of a continuous-time signal. Be aware!\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "0491cc69" - }, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\"> <p>We will give you the answers in this code cell for free!</p></div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "T_meas = 5\n", - "f_s = 100 #sampling rate [Hz]\n", - "\n", - "t_vec = np.arange(0, T_meas, 1 / f_s) # ends at 4.99, length 500 according to the sample-and-hold convention\n", - "\n", - "A = 1 \n", - "f_c = 1 \n", - "phi = 5 * np.pi / 180\n", - "x = A * np.sin(2 * np.pi * f_c * t_vec + phi)\n", - "\n", - "plt.plot(t_vec, x, color='b', label='signal')\n", - "plt.xlabel(r'$t \\: [s]$')\n", - "plt.ylabel(r'$x(t) \\: [V]$')\n", - "plt.legend(loc='upper right')\n", - "plt.title(fr'Sinusoidal signal with $A$={A} V, $f_c$={f_c} Hz and initial phase $\\phi$={phi:.3f} °')\n", - "plt.grid()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**In addition to the code output above, write your answer in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### The Discrete Fourier Transform (chapter 5)\n", - "\n", - "To discover which frequencies are contained in the signal $x(t)$, we can transform it from the time domain to the frequency domain using the Fourier transform:\n", - "\n", - "$$\n", - "X(f) = \\int_{-\\infty}^{\\infty} x(t) e^{-j 2\\pi f t} dt\n", - "$$\n", - "\n", - "Which can then be expressed in terms of magnitude and phase:\n", - "\n", - "$$\n", - "X(f) = |X(f)|e^{j\\theta(f)}\n", - "$$\n", - "\n", - "Where $|X(f)|$ plotted against frequency $f$ is called the *magnitude spectrum* (and practically often referred to as amplitude spectrum).\n", - "\n", - "The set and number of sinusoids required to approximate or re-create a given signal $x(t)$ depends on the shape of that signal. Of course, when the signal is a pure sinusoid, we only need one term. For an example, consider a 2 Hz sinusoidal signal and its magnitude spectrum below (the magnitude spectrum is expressed in [Vs], which equals [V/Hz], hence a magnitude or amplitude density).\n", - "\n", - "<img src=\"https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/SignalSpectrumExample.png\" style=\"margin:auto\" width=800/>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can see a sharp spike in the magnitude plot (which has two logarithmic axes, and we only plot the spectrum for positive frequencies $f>0$). A continuous time sinusoid with amplitude $A$ will produce a magnitude of $\\frac{A T_{meas}}{2}$ in the amplitude spectrum (with $T_{meas}$ the *measurement time* or duration), rather than $\\frac{A}{2}$ which you would expect (in a double-sided spectrum). This is because of the limited time duration of the input signal, which actually implies multiplication of $x(t)$ by a *rectangular time window* $w(t)=\\Pi(\\frac{t}{T_{meas}})$. Since the sinusoid has an amplitude of $A=1$ V, and was measured for $T_{meas}=5$ seconds, the magnitude becomes 2.5. The magnitude at all other frequencies is very small, approximately $10^{-15}$, or approximately zero.\n", - "\n", - "The Fourier transform is a continuous-time operation, mapping the continuous time-domain to the continuous frequency domain. Usually, we don't have continuous-time signals, but discrete time signals $x_n$ sampled at a certain sampling rate. The discrete Fourier Transform (DFT) is the discrete-time equivalent of the continuous time-Fourier transform:\n", - "\n", - "$$\n", - "X_k = \\sum_{n=0}^{N-1}x_ne^{-j2\\pi kn/N}, k=0,1,...,N-1\n", - "$$\n", - "\n", - "Where $X_k$ is the sequence of frequency domain samples. NumPy contains a function to perform the DFT using a fast numerical algorithm, the Fast Fourier Transform:\n", - "\n", - "<code>X_discr = np.fft.fft(x)</code>\n", - "\n", - "For more information on the function see [here](https://numpy.org/doc/stable/reference/generated/numpy.fft.fft.html).\n", - "\n", - "The discrete-time signal $x_n$ and the frequency domain samples $X_k$ returned by Python are of equal length ($N$ samples in, $N$ samples out). When you compare the equations of the DFT with the continuous Fourier Transform, you will see that in the continuous equation we integrate over time $t$, while in the DFT *no information* about the time or sample rate is required (there is no $\\Delta t$ in the above equation for $X_k$, as noted at the end of Chapter 5). This results in a *scale factor* in the spectrum when the DFT of signals with different sample rates are compared. To solve this, we have to multiply the DFT as calculated by NumPy by the sample time interval $\\Delta t = 1/f_s$ to restore the time dimension and obtain a *discrete approximation of the continuous Fourier Transform*. To account for the measurement duration as described above, we have to divide by $T_{meas} = N \\Delta t$. So, in total, multiply by $\\Delta t$ and divide by $T_{meas}$, hence, we have to divide the NumPy result by the number of samples $N$:\n", - "\n", - "<code>X_cont = np.fft.fft(x) / N</code>\n", - "\n", - "The DFT only contains information (the complex value of $X_k$) at discrete frequencies, known as the *analysis frequencies*, which are integer multiples of the frequency resolution $f_0$. If we have a sampled signal $x_n$ consisting of $N$ samples, sampled at $f_s$ Hz with $f_s=1/ \\Delta t$, the frequency resolution is:\n", - "\n", - "$$\n", - "f_0 = \\frac{1}{T_{meas}} = \\frac{1}{N \\Delta t} = \\frac{f_s}{N}\n", - "$$\n", - "\n", - "The first value of the complex vector $X_n$ returned by NumPy is the mean of the time-domain signal corresponding to $f=0$ Hz. So, the frequency vector corresponding to the discrete Fourier transform starts at zero and has $N$ elements, the analysis frequencies:\n", - "\n", - "<code>f_vec = np.arange(0, f_s, f_0)</code>\n", - "\n", - "With task 2 you visualize the entire output as you get it from the `np.fft.fft`, hence for frequencies $[0,f_s)$. From Chapter 4 you know that the spectrum of a sampled signal repeats every integer multiple of $f_s$ (copies of the spectrum)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 2:</b> \n", - "\n", - "- Calculate the Fast Fourier Transform of the signal you generated in Task 1. Remember: the signal has 500 samples and thus does *not* end at exactly 5 second.\n", - "- Create the frequency vector $f$ with the analysis frequencies.\n", - "- Plot the modulus of the Fourier Transform against the frequency $f$ using a log scale on both axes. Use plot markers to see at which frequencies the Fourier transform was calculated.\n", - "\n", - "On top of that, answer to the following questions:\n", - "<ol>\n", - " <li>Describe the amplitude spectrum.</li>\n", - " <li>What is the magnitude of $X(f)$ at $f$ = 1 Hz?</li>\n", - " <li>Do you notice anything peculiar about the amplitude spectrum?</li>\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE\n", - "\n", - "# Write your own code or use the template below to create your figure(s)\n", - "\n", - "# f, axes = plt.subplots(1,1,figsize=(10,5))\n", - "\n", - "# axes[0].plot(YOUR_CODE_HERE, YOUR_CODE_HERE, 'x', color='b', label='Fourier transform')\n", - "# axes[0].loglog()\n", - "# axes[0].set_xlabel('$f \\: \\: [Hz]$')\n", - "# axes[0].set_ylabel('$|X(f)| \\: [V]$')\n", - "# axes[0].grid()\n", - "# axes[0].set_title('Log/Log')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**In addition to the code output above, write your answer in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Symmetry\n", - "\n", - "\n", - "Due to symmetry properties of the DFT, the following holds for a real signal $x(t)$:\n", - "\n", - "$$\n", - "|X_k| = |X_{-k}|\n", - "$$\n", - "\n", - "Which means that the modulus of the Fourier coefficients is symmetric about $f=0$. The NumPy <code>fft</code> command appends the Fourier coefficients for $k<0$ to the right side of the Fourier coefficients for $k \\ge 0$. This is called the *two-sided* spectrum.\n", - "\n", - "Since we are working with real signals, the symmetry property is valid, and we can just ignore the coefficients for $k<0$. This means that we consider the following range in the frequency domain:\n", - "\n", - "$[0, \\frac{f_s}{2}]$ for even values of $N$\n", - "\n", - "$[0, \\frac{f_s}{2})$ for odd values of $N$\n", - "\n", - "In other words, we are only considering frequencies up to half of $f_s$. This is easily implemented in Python using the floor division operator <code>//</code>:\n", - "\n", - "<code>X_cont = X_cont[:N//2]</code>\n", - "\\\n", - "<code>f_vec = f_vec[:N//2]</code>\n", - "\n", - "If you're unfamiliar with this, consider that <code>A//B</code> returns the number of times <code>B</code> 'fits into' <code>A</code>. In principle, this will always return an integer, so it can be easily used for indexing an array. In this specifc example, <code>N//2</code> will return $\\frac{N}{2}$ for even $N$ and $\\frac{N-1}{2}$ for odd N, which is exactly what we want. See the example below." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "N = 100\n", - "print(f'{N} floor divided by 2: {N//2}')\n", - "print(f'{N+1} floor divided by 2: {(N+1)//2}')\n", - "print(f'{N-1} floor divided by 2: {(N-1)//2}')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "\n", - "<p>\n", - "<b>Task 3:</b> \n", - "\n", - "- Repeat Task 2 with different measurement times $T_{meas}$ for the signal. Use measurement times such that the $f_c$ = 1 Hz oscillation fits *exactly* 1 time, 5 times and 20 times.\n", - "- Plot the amplitude spectrum for all three measurement times, **only for positive frequencies**, in separate graphs (log-log scale) with the same domains and answer to the following questions:\n", - "\n", - "- What is the effect of changing $T_{meas}$ on the frequency range in the amplitude spectrum? Does the highest analysis frequency change?\n", - "- Does the frequency resolution change?\n", - "- Does the magnitude of at the peaks change?\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE\n", - "\n", - "# Write your own code or use the template below to create your figure(s)\n", - "\n", - "plt.figure(figsize=(12,4))\n", - "for i, T_meas in enumerate(YOUR_CODE_HERE):\n", - " YOUR_CODE_HERE\n", - "\n", - " plt.subplot(1, 3, i+1)\n", - " \n", - " YOUR_CODE_HERE\n", - " \n", - " plt.grid()\n", - " plt.tight_layout()\n", - "plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**In addition to the code output above, write your answer in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Aliasing (chapter 4)\n", - "\n", - "So far we have been analyzing a signal with a fairly low frequency, just $1$ or $2$ Hz. Now suppose, due to some unexpected source, our signal contains a second sinusoid with a much higher frequency. This is often caused by the line frequency ($50$ Hz) due to power plant generators providing the $220$ V current in regular buildings, or by electrical interference. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "\n", - "<p>\n", - "<b>Task 4: with this task we'll make you run into an aliasing problem . . .</b> \n", - "\n", - "- Create a time-array starting $t=0$, with a sampling rate of 100 Hz, and ending such that a sinusoid with a frequency of 1 Hz fits exactly 5 times in the measurement time.\n", - "\n", - "- Re-create the signal $x(t) = A \\sin(2 \\pi f_c t + \\varphi)$ from the first Task, with amplitude $A=1.0$ V, carrier frequency $f_c=1.0$ Hz, and initial phase $\\varphi = 5$ degrees, to be converted into radians.\n", - "\n", - "- Add to this signal a second sinusoid with a frequency of $80$ Hz and amplitude of $0.1$ V (and zero initial phase).\n", - "\n", - "- Create a plot of the signal against time, and of the amplitude spectrum as in the previous Tasks. \n", - "\n", - "Then answer to the following questions:\n", - "<ol>\n", - " <li>What do you see in the frequency plot? Are there peaks? How many? Where?</li>\n", - " <li>Does this match what you see in the time plot?</li>\n", - " <li>Does changing the measurement time (duration) help?</li>\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE\n", - "\n", - "# Write your own code or use the template below to create your figure(s)\n", - "\n", - "# plt.figure(figsize=(12,6))\n", - "# plt.subplot(211)\n", - "# YOUR_CODE_HERE\n", - "# plt.grid()\n", - "# plt.title('Time signal')\n", - "# plt.legend()\n", - "\n", - "# plt.subplot(212)\n", - "# YOUR_CODE_HERE\n", - "# plt.loglog()\n", - "# YOUR_CODE_HERE\n", - "# plt.grid()\n", - "# plt.tight_layout()\n", - "# plt.title('Amplitude spectrum')\n", - "# plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**In addition to the code output above, write your answer in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The effect seen in Task 4 is called *aliasing*, and the cause is that if your sample rate is too low for the signals you're measuring, you will not capture their oscillation period sufficiently - with at least two samples per cycle. Instead, the signal will appear at a much lower frequency, as you can see in the figure below. Here $f_c = 5$ Hz, and the signal was sampled with $f_c = 7$ Hz, and based on the discrete time samples we incorrectly conclude that there is a frequency component at $2$ Hz (at the end of Chapter 4).\n", - "\n", - "<img src=\"https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/NewSlide38.png\" style=\"margin:auto\" width=800/>\n", - "<img src=\"https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/NewSlide51.png\" style=\"margin:auto\" width=800/>\n", - "\n", - "So, how fast do we need to sample to capture an $80$ Hz signal?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 5:</b> \n", - "\n", - "Repeat Task 4 with different sample rates: $110, 150, 160,$ and $200$ Hz. Plot the signal and amplitude spectrum for each one (you might want to use a loop). \n", - "\n", - "Then answer the following questions:\n", - "<ol>\n", - " <li>At what frequency does the (aliased) 80 Hz signal appear in the spectrum, for the above values of $f_s$ (provide numerical answers)?</li>\n", - " <li>Can you figure out the relationship (a simple equation) between the sample rate and the frequency of the original signal, and the frequency at which the alias appears?</li>\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE\n", - "\n", - "# Write your own code or use the template below to create your figure(s)\n", - "\n", - "# for YOUR_CODE_HERE:\n", - " \n", - "# YOUR_CODE_HERE\n", - " \n", - "# plt.figure(figsize=(12,6))\n", - "# plt.suptitle(f'$f_s = {YOUR_CODE_HERE}$ Hz')\n", - "# plt.subplot(211)\n", - "# YOUR_CODE_HERE\n", - "# plt.grid()\n", - "# plt.legend()\n", - " \n", - "# plt.subplot(212)\n", - "# YOUR_CODE_HERE\n", - "# plt.loglog()\n", - "# plt.grid()\n", - "# plt.tight_layout()\n", - "# plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**In addition to the code output above, write your answer in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As you probably figured out, the sample rate needs to be faster than twice the largest frequency in the signal. In other words, you can measure signals with a frequency up to half the sample rate without aliasing becoming a problem. The frequency above which aliasing occurs (half the sampling rate) is called the *Nyquist frequency* (Chapter 4)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Damped vibrations\n", - "\n", - "We now know how to create an amplitude/magnitude spectrum. We've seen that we get aliasing if our signal has components at frequencies higher than the *Nyquist frequency* (and leakage if the measurement time is too short). Now, let's consider the damped vibration aceleration signal that an accelerometer would measure (see *Appendix A*). In this case the damping ratio is not equal to zero, unlike in Tasks 1 to 5." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 6:</b> \n", - "\n", - "- Create a time-array starting at $t=0$ s, ending at $t = 50$ s, with a sampling rate of $100$ Hz.\n", - "- Create a damped harmonic acceleration signal $x(t) = \\frac{x(0)}{\\sqrt{1-\\zeta^2}} e^{-\\zeta \\omega_0 t} \\sin(\\omega_d t)$ with $\\zeta = 0.05$, $\\omega_0 = 10 \\pi$ rad/s (corresponding to $5$ Hz), $\\omega_d = \\omega_0 \\sqrt{1-\\zeta^2} = 9.987 \\pi$ rad/s, and initial displacement $x(0)=1$ (for convenience the initial phase of the signal is kept to zero).\n", - "- Create a plot of the signal against time, and of the amplitude spectrum as in the previous Tasks.\n", - "\n", - "Then answer the following questions:\n", - "<ol>\n", - " <li>Do you see any changes in the time plot, compared to the earlier plot? Describe them!</li>\n", - " <li>What is the dominant frequency of the signal now?</li>\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE\n", - "\n", - "# # Write your own code or use the template below to create your figure(s)\n", - "\n", - "# plt.figure(figsize=(12,6))\n", - "# plt.subplot(211)\n", - "# YOUR_CODE_HERE\n", - "# plt.grid()\n", - "# plt.legend()\n", - "\n", - "# plt.subplot(212)\n", - "# YOUR_CODE_HERE\n", - "# plt.loglog()\n", - "# YOUR_CODE_HERE\n", - "# plt.grid()\n", - "# plt.tight_layout()\n", - "# plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**In addition to the code output above, write your answer in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Cantilever-beam acceleration measurements\n", - "\n", - "Now you're ready to start analyzing the cantilever-beam acceleration measurements.\n", - "\n", - "Read in the data-file: *cantileverbeam_acc50Hz.csv*.\n", - "\n", - "This dataset contains 5 minutes of measurements with a sampling rate of $50$ Hz (a total of $N=15001$ samples). The first column in the file contains the UTC time of day (in seconds), the second column contains the measured acceleration (in m/s<sup>2</sup>)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Detrending\n", - "\n", - "In this project the signal of interest is the damped, harmonic motion of the cantilever-beam. In addition the measurements may contain (unwanted) effects of the sensor (think of an offset, due to imperfect manufacturing and/or prior calibration, or a drift over time, for instance due to temperature changes in the electronics during the experiment). By detrending we mean to remove such effects, prior to our spectral analysis, so that we can start with a nice, zero mean signal. A-priori detrending is good practice and generally yields a cleaner spectrum. Next week (week 2.4 on Time Series Analysis) we cover the subject of removing unwanted effects from the signal in more detail, as to obtain a so-called **stationary** signal, meaning that the properties or characteristics of the signal (such as the mean) do not change over time, and, we provide practical means to “stationarize†a given or measured signal.\n", - "\n", - "There are built-in functions in Python to remove such an offset and/or trend (and you're free to use them). But, earlier in the MUDE, in week 1.3, you learned about least-squares parameter estimation, and that's what you can apply to do the detrending (and actually built-in functions just apply the very same principle). Next week, on Time Series Analysis, you will actually be covering (again) the estimation of a trend in a time series of measurements.\n", - "As a re-cap for week 1.3: when a series of observations $y_1, …, y_m$ (in our case with $m=N$) is supposed or expected to exhibit a functional linear trend (a straight line in terms of a graph), this can be modelled as\n", - "\n", - "$$\n", - "\\mathbb{E} = \\begin{pmatrix} \\begin{bmatrix} Y_{1} \\\\ Y_{2} \\\\ \\vdots \\\\ Y_{m} \\end{bmatrix} \\end{pmatrix} \n", - " = \n", - " \\begin{bmatrix} 1 & t_1 - t_1 \\\\ 1 & t_2 - t_1 \\\\ \\vdots & \\vdots \\\\ 1 & t_m - t_1 \\end{bmatrix} \n", - " \\begin{pmatrix} x_{1} \\\\ x_{2} \\end{pmatrix}\n", - "$$\n", - "\n", - "with $x_1$ the offset at time $t_1$ (rather than $t=0$), and $x_2$ the slope of the line. The two unknown parameters in this vector $x$ can be estimated through (unweighted) least-squares, $\\hat{x}=(A^T A)^{-1} A^T y$, and next the residuals are obtained as $\\hat{\\epsilon}=y-\\hat{y}=y-A\\hat{x}$. The residuals are the 'left-over part' of the observations, once the (estimated) trend has been taken out; these residuals are of interest for further spectral analysis!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 7:</b> \n", - "\n", - "- For the cantilever-beam acceleration measurements, perform a least-squares estimation according to the above model, and report the estimated offset and slope of the trend.\n", - "- The detrended acceleration measurements, hence the elements of vector $\\hat{\\epsilon}$ are the input to your spectral analysis, so from here on, we denote them by $x(t)$ (in continuous time), and by $x_n$ (in discrete time) with $n=0,…,N-1$.\n", - "- Make a plot of the input signal as a function of time, hence of the detrended accelerations.\n", - "\n", - "Report the estimated offset and slope of the trend (i.e. numerical values).\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df = pd.read_csv('cantileverbeam_acc50Hz.csv', header=0)\n", - "\n", - "t = np.array(df['time']) #\n", - "dat = np.array(df['acceleration']) #\n", - "\n", - "N = len(t)\n", - "\n", - "plt.figure()\n", - "plt.plot(t, dat, color='b', label='acceleration signal')\n", - "plt.xlabel('time [s]')\n", - "plt.ylabel('acceleration [m/s2]')\n", - "plt.title('Vertical cantilever beam acceleration')\n", - "plt.legend()\n", - "\n", - "# observation record length (as N*dt, according to sample-and-hold convention)\n", - "T = (t[N-1] - t[0])*N/(N - 1)\n", - "dt = T/N\n", - "\n", - "YOUR_CODE_HERE" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**In addition to the code output above, write your answer in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 8:</b> \n", - "\n", - "Previously, in Task 3, you computed and plotted the magnitude spectrum $|X_k|$ of a signal for positive frequencies $f>0$ (putting a lot of attention to correctly labelling the horizontal frequency axis of the plot!), and now, with the material of Chapter 6 on spectral estimation, you will estimate the power spectral density $S$ of the signal through the periodogram, which is just: $S(k\\Delta f)=\\frac{|X_k|^2}{T}$ (in [W/Hz] when $x_n$ is a voltage signal; and $|X_k|$ being the result straight from the <code>np.fft</code>, multiplied by sampling interval $\\Delta t$), for frequency $k\\Delta f$, with frequency resolution $\\Delta f=\\frac{1}{T}$, and $k=0,…,N-1$ (hence, pretty much the same procedure as with the magnitude spectrum, though just taking the square of the modulus, and dividing by $T$).\n", - "\n", - "Compute and plot the periodogram for the detrended accelerometer measurements of Task 7 (if you prefer, feel free to use a linear scaling of the axes here, rather a log-log, and, use $T$ as defined already in the code of Task 7). Please, pay attention to correctly labelling the axes, and stating dimensions of the quantities along the axes!\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 9:</b> \n", - "\n", - "Answer the following questions:\n", - "<ol>\n", - " <li>Report the damped natural frequency (in Hertz) of this one-degree-of-freedom (1DOF) mechanical system. Does it match the motion of the beam shown in the cantilever-beam video?</li>\n", - " <li>The acceleration was measured at quite a high sample rate of $50$ Hz. What is the minimum sampling frequency to correctly identify the damped natural frequency in the periodogram?</li>\n", - "</ol>\n", - "<p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Write your answer(s) in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Task 10: Global Mean Sea-Level (GMSL) data (optional)\n", - "\n", - "Repeat the steps with Tasks 7-9, but now with the Global Mean Sea Level data set. Data is from the Australia's National Science Agency (CSIRO): [GMSL data](https://www.cmar.csiro.au/sealevel/sl_hist_last_decades.html). \n", - "\n", - "These data result from nearly 3 decades of satellite altimetry (with satellite missions such as TOPEX/Poseidon and the Jason-series). The first column contains the time tag or epoch (in decimal years), the second column is the global mean sea level (in mm). There is one measurement per month (monthly average, so that for instance tide-effects are averaged out, and the measurement typically refers to the middle of the month, hence 1993.042 is mid January in 1993). The single monthly measurement is the global mean sea level, so, the average of the entire world.\n", - "\n", - "The sampling frequency $f_s = 12$ per year ($\\Delta t = 1/12 \\sim 0.083$ year), and there are $N=331$ measurements in total." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "data = pd.read_csv('CSIRO_Alt_seas_inc.txt', names=['month', 'sl'])\n", - "data.head()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# create time-array, time relative to t0 [yr] (epoch-time of the first observation;\n", - "# t0=1993.042 refers to mid January 1993)\n", - "t = data.iloc[:, 0] - data.iloc[0, 0]\n", - "\n", - "# number of observations\n", - "N = len(t)\n", - "\n", - "# observation record length (as N * dt, according to sample-and-hold convention)\n", - "T = (t[N - 1] - t[0]) * N / (N - 1)\n", - "\n", - "# Delta t [yr]; dt = T/N = (N*dt)/N\n", - "dt = T / N\n", - "\n", - "# observed sea-level height\n", - "y = data.iloc[:,1]\n", - "\n", - "# plot observed time-series, as it is, versus epoch-time in [year]\n", - "plt.plot(data.iloc[:,0],y, color='b', label='sea level')\n", - "plt.xlabel('time [yr]')\n", - "plt.ylabel('sea-level height [mm]')\n", - "plt.title('Global Mean Sea-Level (GMSL) rise')\n", - "plt.legend();" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 10 (Optional!):</b> \n", - "\n", - "Detrend the data. \n", - "\n", - "Estimate and plot power spectral density (PSD), hence the periodogram, for the (detrended) global mean sea-level data. \n", - "\n", - "Identify the largest peak in the spectrum, what is the frequency, and can you come up with a physical explanation of this behaviour?\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Write your answer(s) in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>End of task.</b>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#C8FFFF; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Appendix A: Cantilever-beam dynamics:</b> \n", - "\n", - "The dynamics of the smartphone suspended on a cantilever beam can be considered as the mass-spring-damper system shown below:\n", - "\n", - "<img src=\"https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/mass_spring_damper.png\" style=\"margin:auto\" width=200/>\n", - "\n", - "The equation of motion of the deflection $x$ of this mass-spring-damper system (a damped harmonic oscillator) can be described by the following second order differential equation:\n", - "\n", - "$$\n", - "\\ddot{x}(t) + \\frac{c}{m} \\dot{x}(t) + \\frac{k}{m} x(t) =0\n", - "$$\n", - "\n", - "Where $\\ddot{x}(t)$, $\\dot{x}(t)$ and $x(t)$ are the acceleration, velocity and displacement as a function of time of the oscillating mass $m$ [kg] respectively. (with a unit transfer function, $x(t)$ describes the motion of the proof mass inside the smartphone accelerometer). For simplicity, we consider here the homogeneous equation, corresponding to free motion. The other parameters are the damping coefficient $c$ [kg/s] and spring constant $k$ [N/m]. The damping ratio can be obtained from the system parameters: $\\zeta = \\frac{c}{2 \\sqrt{mk}}$, which is dimensionless. The undamped natural frequency is $\\omega_0 = \\sqrt{\\frac{k}{m}}$ [rad/s]. The differential equation becomes:\n", - "\n", - "$$\n", - "\\ddot{x}(t) + 2 \\zeta \\omega_0 \\dot{x}(t) + \\omega_0^2 x(t) =0\n", - "$$\n", - "\n", - "For the under-damped case ($0 \\le \\zeta \\le 1)$ of our smartphone and assuming an initial zero tip velocity $\\dot{x}(t=0)=0$ (release from stand-still), the solution for the position as a function of time is given by:\n", - "\n", - "$$\n", - "x(t)=e^{-\\zeta \\omega_0 t} \\frac{x(0)}{\\sqrt{1-\\zeta^2}}\\sin(\\omega_d t + \\varphi)\n", - "$$\n", - "\n", - "Where $x(0)$ is the initial position $x(t=0)$, $\\omega_d$ is the damped natural frequency $\\omega_d = \\omega_0 \\sqrt{1-\\zeta^2}$, and the phase shift $\\varphi = \\arctan \\left( \\frac{\\sqrt{1-\\zeta^2}}{\\zeta} \\right)$. The sinusoid term represents the harmonic motion, and the exponential term represents the damping of that motion over time. Next, the velocity of the smartphone's oscillation can be derived as:\n", - "\n", - "$\\dot{x}(t) = e^{-\\zeta \\omega_0 t} \\frac{x(0)}{\\sqrt{1-\\zeta^2}}\\sin(\\omega_d t)$.\n", - "\n", - "The acceleration of the smartphone (which is what is being measured) is found as:\n", - "\n", - "$\\ddot{x}(t) = e^{-\\zeta \\omega_0 t} \\frac{x(0)}{\\sqrt{1-\\zeta^2}} \\sin (\\omega_d t - \\phi)$.\n", - "\n", - "Note that $\\omega_0$ and $\\omega_d$ are the angular frequencies expressed in radians per second. $\\ddot{x}(t)$ is a damped harmonic signal where the rate of damping is determined by the damping ratio $\\zeta$.\n", - "\n", - "In order to get a pure harmonic signal (as used in Tasks 1 to 5), set the damping ratio $\\zeta=0$, and optionally set the phase-shift $\\phi$ to zero as well, then the tip acceleration is given by the following simple sinusoidal expression:\n", - "\n", - "$$\n", - "\\ddot{x}(t)=x(0) \\sin(\\omega_0 t).\n", - "$$\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" />\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" />\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2024 <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">MUDE</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">CC BY 4.0 License</a>." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "mude-base", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.4" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/synced_files/students/GA_2_3/Analysis.md b/synced_files/students/GA_2_3/Analysis.md deleted file mode 100644 index c22c963231b1fdea5d6e2fbecbd10e0cbef75a91..0000000000000000000000000000000000000000 --- a/synced_files/students/GA_2_3/Analysis.md +++ /dev/null @@ -1,649 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: mude-base - language: python - name: python3 ---- - -# GA 2.3: Beam Beats - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px"\> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px"\> -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): week 2.3. Due: Friday, November 29, 2024.* - - -## Analyzing cantilever-beam accelerations and global Mean Sea-Level measurements - -This project covers the week on Signal Processing (week 2.3). - -As a warming up you will create and analyze some elementary signals yourself, and next, you will carry out frequency domain analyses on two given data-sets, namely acceleration measurements of a Cantilever-Beam experiment, and (in optional Task 10) Global Mean Sea-Level measurements. - -Most of the Tasks in this notebook consist of both coding, producing a plot, and answering (open) questions. Typically, as you work your way through the Tasks, you can often re-use code, or part of it, from earlier Tasks and assignments. That will save you a lot of work!! - -<!-- #region id="0491cc69" --> -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>In many of the code blocks below, template code to create figures is provided. Note that there is a lot of code missing, and one line of <code>YOUR_CODE_HERE</code> does not imply that only one line of code is missing!</p></div> -<!-- #endregion --> - -<!-- #region --> -### Data Acquisition System - -A data acquisition (DAQ) system usually consists of four components: - -<img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/DAQ.png" style="margin:auto"/> - - -- A sensor transforms a physical signal into a small voltage. The transformation is often frequency dependent or nonlinear, and can show drift or bias. -- Signal conditioning electronics (often included in the sensor housing) filter unwanted frequencies, such as the 50 Hz line frequency caused by power plant generators, using low-pass or notch filters. In addition the sensor voltage may be amplified. -- An analog-to-digital (A/D) converter samples the analog voltage with a certain rate, such as 100 Hz. The A/D converter can measure analog voltages within a certain range, the measurement range. The measured voltage is quantized with a certain resolution, such as 14-bit, which means that the full measurement range is divided into $2^{14}=16,384$ discrete intervals. Together, the resolution and measurement range determine the precision. Usually the sample rate, the measurement range, and the sample resolution are configurable. Sampling and quantizing together turns an analog signal into a digital signal. -- A digital computer reads the sampled data from the A/D converter at specific times, and allows for further processing, analysis and storage of the (digital) signal. - -The result is that an analog, physical signal, is turned into a series of numbers (samples of the signal, in the time domain), ready for processing and analysis in a digital computer. - - - -One of the data sets that you will analyze during this MUDE Q2 project was acquired by an accelerometer in a smartphone, on top of a vertical cantilever-beam. The accelerometer measures the side-ward accelerations, expressed in m/s<sup>2</sup>, and sampled at 50 Hz. Detailed information about the experiment and the sensor can be found in "Experimental evaluation of smartphone accelerometer and low-cost dual frequency GNSS sensors for deformation monitoring", by Alexandru Lapadat, Christian Tiberius and Peter Teunissen, Sensors 2021, 21, 7946, https://doi.org/10.3390/s21237946. - -A quick impression of the test setup can be gained by watching the short video [Cantilever Beam Experiment](https://youtu.be/o4moRwvlBLU?si=aKelBMWm3HB2Of26) (1 minute). - -A theoretical description of the motion of the smartphone accelerometer fixed to the cantilever beam is presented in Appendix A. Pulling the beam at the tip and releasing it, results in a (nearly) horizontal side-ward motion of the smartphone, and the (horizontal) position can be described by a *damped harmonic* as a function of time. Consequently, also the first and second derivative with respect to time, the velocity and acceleration as a function of time as the smartphone will measure it, are harmonics. - -### Basic sinusoid signal - -You will start with first creating (and analyzing) a few simple signals yourself. In the first few Tasks of this project, we will take the damping ratio zero and use a fairly short measurement time (duration), and hence the acceleration measured by the smartphone is a plain (undamped) sinusoid as shown in Appendix A (a stationary signal). In the following Tasks we also add a phase offset $\varphi$ to the plain sinusoid: - -$$ -x(t) = A \sin(2 \pi f_c t + \varphi) -$$ - -The result is taken from the last equation in Appendix A. We consider here acceleration, though for convenience, we omit the dots on top of the $x(t)$. -<!-- #endregion --> - -```python -import numpy as np -import pandas as pd -import matplotlib.pyplot as plt - -%matplotlib inline -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 1:</b> - -- Create a time-array starting at $t=0$ s, ending at $t=5.0$ s, with a sampling rate of 100 Hz. Hint: what is the number of samples $N$? And what should then be the last value in the time-array? Note that, for example, with $N=10$ samples at a sampling rate of $f_s = 100$ Hz, we have signal samples at times $t=0.00, 0.01, 0.02, ... , 0.08, 0.09$ seconds, hence $T_{meas}= N \Delta t =0.1$ seconds (the sample-and-hold convention). -- Create a sinusoidal signal $x(t) = A \sin(2 \pi f_c t + \varphi)$, with amplitude $A=1.0$ Volt, carrier frequency $f_c=1.0$ Hz, and initial phase $\varphi = 5$ degrees, to be converted into radians. -- Make a plot of the signal against time. Note that this is strictly a *sampled signal* $x_n$ rather than $x(t)$, but since we use a rather high sampling rate, the signal shown is close to continuous in time. Connecting the sample points of $x_n$ in the graph by lines, as done in the graph below, corroborates the suggestion of a continuous-time signal. Be aware! -</p> -</div> - -<!-- #region id="0491cc69" --> -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>We will give you the answers in this code cell for free!</p></div> -<!-- #endregion --> - -```python -T_meas = 5 -f_s = 100 #sampling rate [Hz] - -t_vec = np.arange(0, T_meas, 1 / f_s) # ends at 4.99, length 500 according to the sample-and-hold convention - -A = 1 -f_c = 1 -phi = 5 * np.pi / 180 -x = A * np.sin(2 * np.pi * f_c * t_vec + phi) - -plt.plot(t_vec, x, color='b', label='signal') -plt.xlabel(r'$t \: [s]$') -plt.ylabel(r'$x(t) \: [V]$') -plt.legend(loc='upper right') -plt.title(fr'Sinusoidal signal with $A$={A} V, $f_c$={f_c} Hz and initial phase $\phi$={phi:.3f} °') -plt.grid() -``` - -**In addition to the code output above, write your answer in this Markdown cell.** - - -### The Discrete Fourier Transform (chapter 5) - -To discover which frequencies are contained in the signal $x(t)$, we can transform it from the time domain to the frequency domain using the Fourier transform: - -$$ -X(f) = \int_{-\infty}^{\infty} x(t) e^{-j 2\pi f t} dt -$$ - -Which can then be expressed in terms of magnitude and phase: - -$$ -X(f) = |X(f)|e^{j\theta(f)} -$$ - -Where $|X(f)|$ plotted against frequency $f$ is called the *magnitude spectrum* (and practically often referred to as amplitude spectrum). - -The set and number of sinusoids required to approximate or re-create a given signal $x(t)$ depends on the shape of that signal. Of course, when the signal is a pure sinusoid, we only need one term. For an example, consider a 2 Hz sinusoidal signal and its magnitude spectrum below (the magnitude spectrum is expressed in [Vs], which equals [V/Hz], hence a magnitude or amplitude density). - -<img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/SignalSpectrumExample.png" style="margin:auto" width=800/> - - -You can see a sharp spike in the magnitude plot (which has two logarithmic axes, and we only plot the spectrum for positive frequencies $f>0$). A continuous time sinusoid with amplitude $A$ will produce a magnitude of $\frac{A T_{meas}}{2}$ in the amplitude spectrum (with $T_{meas}$ the *measurement time* or duration), rather than $\frac{A}{2}$ which you would expect (in a double-sided spectrum). This is because of the limited time duration of the input signal, which actually implies multiplication of $x(t)$ by a *rectangular time window* $w(t)=\Pi(\frac{t}{T_{meas}})$. Since the sinusoid has an amplitude of $A=1$ V, and was measured for $T_{meas}=5$ seconds, the magnitude becomes 2.5. The magnitude at all other frequencies is very small, approximately $10^{-15}$, or approximately zero. - -The Fourier transform is a continuous-time operation, mapping the continuous time-domain to the continuous frequency domain. Usually, we don't have continuous-time signals, but discrete time signals $x_n$ sampled at a certain sampling rate. The discrete Fourier Transform (DFT) is the discrete-time equivalent of the continuous time-Fourier transform: - -$$ -X_k = \sum_{n=0}^{N-1}x_ne^{-j2\pi kn/N}, k=0,1,...,N-1 -$$ - -Where $X_k$ is the sequence of frequency domain samples. NumPy contains a function to perform the DFT using a fast numerical algorithm, the Fast Fourier Transform: - -<code>X_discr = np.fft.fft(x)</code> - -For more information on the function see [here](https://numpy.org/doc/stable/reference/generated/numpy.fft.fft.html). - -The discrete-time signal $x_n$ and the frequency domain samples $X_k$ returned by Python are of equal length ($N$ samples in, $N$ samples out). When you compare the equations of the DFT with the continuous Fourier Transform, you will see that in the continuous equation we integrate over time $t$, while in the DFT *no information* about the time or sample rate is required (there is no $\Delta t$ in the above equation for $X_k$, as noted at the end of Chapter 5). This results in a *scale factor* in the spectrum when the DFT of signals with different sample rates are compared. To solve this, we have to multiply the DFT as calculated by NumPy by the sample time interval $\Delta t = 1/f_s$ to restore the time dimension and obtain a *discrete approximation of the continuous Fourier Transform*. To account for the measurement duration as described above, we have to divide by $T_{meas} = N \Delta t$. So, in total, multiply by $\Delta t$ and divide by $T_{meas}$, hence, we have to divide the NumPy result by the number of samples $N$: - -<code>X_cont = np.fft.fft(x) / N</code> - -The DFT only contains information (the complex value of $X_k$) at discrete frequencies, known as the *analysis frequencies*, which are integer multiples of the frequency resolution $f_0$. If we have a sampled signal $x_n$ consisting of $N$ samples, sampled at $f_s$ Hz with $f_s=1/ \Delta t$, the frequency resolution is: - -$$ -f_0 = \frac{1}{T_{meas}} = \frac{1}{N \Delta t} = \frac{f_s}{N} -$$ - -The first value of the complex vector $X_n$ returned by NumPy is the mean of the time-domain signal corresponding to $f=0$ Hz. So, the frequency vector corresponding to the discrete Fourier transform starts at zero and has $N$ elements, the analysis frequencies: - -<code>f_vec = np.arange(0, f_s, f_0)</code> - -With task 2 you visualize the entire output as you get it from the `np.fft.fft`, hence for frequencies $[0,f_s)$. From Chapter 4 you know that the spectrum of a sampled signal repeats every integer multiple of $f_s$ (copies of the spectrum). - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 2:</b> - -- Calculate the Fast Fourier Transform of the signal you generated in Task 1. Remember: the signal has 500 samples and thus does *not* end at exactly 5 second. -- Create the frequency vector $f$ with the analysis frequencies. -- Plot the modulus of the Fourier Transform against the frequency $f$ using a log scale on both axes. Use plot markers to see at which frequencies the Fourier transform was calculated. - -On top of that, answer to the following questions: -<ol> - <li>Describe the amplitude spectrum.</li> - <li>What is the magnitude of $X(f)$ at $f$ = 1 Hz?</li> - <li>Do you notice anything peculiar about the amplitude spectrum?</li> -</ol> -</p> -</div> - -```python -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -# f, axes = plt.subplots(1,1,figsize=(10,5)) - -# axes[0].plot(YOUR_CODE_HERE, YOUR_CODE_HERE, 'x', color='b', label='Fourier transform') -# axes[0].loglog() -# axes[0].set_xlabel('$f \: \: [Hz]$') -# axes[0].set_ylabel('$|X(f)| \: [V]$') -# axes[0].grid() -# axes[0].set_title('Log/Log') -``` - -**In addition to the code output above, write your answer in this Markdown cell.** - -<!-- #region --> -### Symmetry - - -Due to symmetry properties of the DFT, the following holds for a real signal $x(t)$: - -$$ -|X_k| = |X_{-k}| -$$ - -Which means that the modulus of the Fourier coefficients is symmetric about $f=0$. The NumPy <code>fft</code> command appends the Fourier coefficients for $k<0$ to the right side of the Fourier coefficients for $k \ge 0$. This is called the *two-sided* spectrum. - -Since we are working with real signals, the symmetry property is valid, and we can just ignore the coefficients for $k<0$. This means that we consider the following range in the frequency domain: - -$[0, \frac{f_s}{2}]$ for even values of $N$ - -$[0, \frac{f_s}{2})$ for odd values of $N$ - -In other words, we are only considering frequencies up to half of $f_s$. This is easily implemented in Python using the floor division operator <code>//</code>: - -<code>X_cont = X_cont[:N//2]</code> -\ -<code>f_vec = f_vec[:N//2]</code> - -If you're unfamiliar with this, consider that <code>A//B</code> returns the number of times <code>B</code> 'fits into' <code>A</code>. In principle, this will always return an integer, so it can be easily used for indexing an array. In this specifc example, <code>N//2</code> will return $\frac{N}{2}$ for even $N$ and $\frac{N-1}{2}$ for odd N, which is exactly what we want. See the example below. -<!-- #endregion --> - -```python -N = 100 -print(f'{N} floor divided by 2: {N//2}') -print(f'{N+1} floor divided by 2: {(N+1)//2}') -print(f'{N-1} floor divided by 2: {(N-1)//2}') -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> - -<p> -<b>Task 3:</b> - -- Repeat Task 2 with different measurement times $T_{meas}$ for the signal. Use measurement times such that the $f_c$ = 1 Hz oscillation fits *exactly* 1 time, 5 times and 20 times. -- Plot the amplitude spectrum for all three measurement times, **only for positive frequencies**, in separate graphs (log-log scale) with the same domains and answer to the following questions: - -- What is the effect of changing $T_{meas}$ on the frequency range in the amplitude spectrum? Does the highest analysis frequency change? -- Does the frequency resolution change? -- Does the magnitude of at the peaks change? - -</p> -</div> - -```python -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -plt.figure(figsize=(12,4)) -for i, T_meas in enumerate(YOUR_CODE_HERE): - YOUR_CODE_HERE - - plt.subplot(1, 3, i+1) - - YOUR_CODE_HERE - - plt.grid() - plt.tight_layout() -plt.legend() -``` - -**In addition to the code output above, write your answer in this Markdown cell.** - - -### Aliasing (chapter 4) - -So far we have been analyzing a signal with a fairly low frequency, just $1$ or $2$ Hz. Now suppose, due to some unexpected source, our signal contains a second sinusoid with a much higher frequency. This is often caused by the line frequency ($50$ Hz) due to power plant generators providing the $220$ V current in regular buildings, or by electrical interference. - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> - -<p> -<b>Task 4: with this task we'll make you run into an aliasing problem . . .</b> - -- Create a time-array starting $t=0$, with a sampling rate of 100 Hz, and ending such that a sinusoid with a frequency of 1 Hz fits exactly 5 times in the measurement time. - -- Re-create the signal $x(t) = A \sin(2 \pi f_c t + \varphi)$ from the first Task, with amplitude $A=1.0$ V, carrier frequency $f_c=1.0$ Hz, and initial phase $\varphi = 5$ degrees, to be converted into radians. - -- Add to this signal a second sinusoid with a frequency of $80$ Hz and amplitude of $0.1$ V (and zero initial phase). - -- Create a plot of the signal against time, and of the amplitude spectrum as in the previous Tasks. - -Then answer to the following questions: -<ol> - <li>What do you see in the frequency plot? Are there peaks? How many? Where?</li> - <li>Does this match what you see in the time plot?</li> - <li>Does changing the measurement time (duration) help?</li> -</ol> -</p> -</div> - -```python -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -# plt.figure(figsize=(12,6)) -# plt.subplot(211) -# YOUR_CODE_HERE -# plt.grid() -# plt.title('Time signal') -# plt.legend() - -# plt.subplot(212) -# YOUR_CODE_HERE -# plt.loglog() -# YOUR_CODE_HERE -# plt.grid() -# plt.tight_layout() -# plt.title('Amplitude spectrum') -# plt.legend() -``` - -**In addition to the code output above, write your answer in this Markdown cell.** - - -The effect seen in Task 4 is called *aliasing*, and the cause is that if your sample rate is too low for the signals you're measuring, you will not capture their oscillation period sufficiently - with at least two samples per cycle. Instead, the signal will appear at a much lower frequency, as you can see in the figure below. Here $f_c = 5$ Hz, and the signal was sampled with $f_c = 7$ Hz, and based on the discrete time samples we incorrectly conclude that there is a frequency component at $2$ Hz (at the end of Chapter 4). - -<img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/NewSlide38.png" style="margin:auto" width=800/> -<img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/NewSlide51.png" style="margin:auto" width=800/> - -So, how fast do we need to sample to capture an $80$ Hz signal? - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 5:</b> - -Repeat Task 4 with different sample rates: $110, 150, 160,$ and $200$ Hz. Plot the signal and amplitude spectrum for each one (you might want to use a loop). - -Then answer the following questions: -<ol> - <li>At what frequency does the (aliased) 80 Hz signal appear in the spectrum, for the above values of $f_s$ (provide numerical answers)?</li> - <li>Can you figure out the relationship (a simple equation) between the sample rate and the frequency of the original signal, and the frequency at which the alias appears?</li> -</ol> -</p> -</div> - -```python -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -# for YOUR_CODE_HERE: - -# YOUR_CODE_HERE - -# plt.figure(figsize=(12,6)) -# plt.suptitle(f'$f_s = {YOUR_CODE_HERE}$ Hz') -# plt.subplot(211) -# YOUR_CODE_HERE -# plt.grid() -# plt.legend() - -# plt.subplot(212) -# YOUR_CODE_HERE -# plt.loglog() -# plt.grid() -# plt.tight_layout() -# plt.legend() -``` - -**In addition to the code output above, write your answer in this Markdown cell.** - - -As you probably figured out, the sample rate needs to be faster than twice the largest frequency in the signal. In other words, you can measure signals with a frequency up to half the sample rate without aliasing becoming a problem. The frequency above which aliasing occurs (half the sampling rate) is called the *Nyquist frequency* (Chapter 4). - - -### Damped vibrations - -We now know how to create an amplitude/magnitude spectrum. We've seen that we get aliasing if our signal has components at frequencies higher than the *Nyquist frequency* (and leakage if the measurement time is too short). Now, let's consider the damped vibration aceleration signal that an accelerometer would measure (see *Appendix A*). In this case the damping ratio is not equal to zero, unlike in Tasks 1 to 5. - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 6:</b> - -- Create a time-array starting at $t=0$ s, ending at $t = 50$ s, with a sampling rate of $100$ Hz. -- Create a damped harmonic acceleration signal $x(t) = \frac{x(0)}{\sqrt{1-\zeta^2}} e^{-\zeta \omega_0 t} \sin(\omega_d t)$ with $\zeta = 0.05$, $\omega_0 = 10 \pi$ rad/s (corresponding to $5$ Hz), $\omega_d = \omega_0 \sqrt{1-\zeta^2} = 9.987 \pi$ rad/s, and initial displacement $x(0)=1$ (for convenience the initial phase of the signal is kept to zero). -- Create a plot of the signal against time, and of the amplitude spectrum as in the previous Tasks. - -Then answer the following questions: -<ol> - <li>Do you see any changes in the time plot, compared to the earlier plot? Describe them!</li> - <li>What is the dominant frequency of the signal now?</li> -</ol> -</p> -</div> - -```python -YOUR_CODE_HERE - -# # Write your own code or use the template below to create your figure(s) - -# plt.figure(figsize=(12,6)) -# plt.subplot(211) -# YOUR_CODE_HERE -# plt.grid() -# plt.legend() - -# plt.subplot(212) -# YOUR_CODE_HERE -# plt.loglog() -# YOUR_CODE_HERE -# plt.grid() -# plt.tight_layout() -# plt.legend() -``` - -**In addition to the code output above, write your answer in this Markdown cell.** - - -### Cantilever-beam acceleration measurements - -Now you're ready to start analyzing the cantilever-beam acceleration measurements. - -Read in the data-file: *cantileverbeam_acc50Hz.csv*. - -This dataset contains 5 minutes of measurements with a sampling rate of $50$ Hz (a total of $N=15001$ samples). The first column in the file contains the UTC time of day (in seconds), the second column contains the measured acceleration (in m/s<sup>2</sup>). - - -### Detrending - -In this project the signal of interest is the damped, harmonic motion of the cantilever-beam. In addition the measurements may contain (unwanted) effects of the sensor (think of an offset, due to imperfect manufacturing and/or prior calibration, or a drift over time, for instance due to temperature changes in the electronics during the experiment). By detrending we mean to remove such effects, prior to our spectral analysis, so that we can start with a nice, zero mean signal. A-priori detrending is good practice and generally yields a cleaner spectrum. Next week (week 2.4 on Time Series Analysis) we cover the subject of removing unwanted effects from the signal in more detail, as to obtain a so-called **stationary** signal, meaning that the properties or characteristics of the signal (such as the mean) do not change over time, and, we provide practical means to “stationarize†a given or measured signal. - -There are built-in functions in Python to remove such an offset and/or trend (and you're free to use them). But, earlier in the MUDE, in week 1.3, you learned about least-squares parameter estimation, and that's what you can apply to do the detrending (and actually built-in functions just apply the very same principle). Next week, on Time Series Analysis, you will actually be covering (again) the estimation of a trend in a time series of measurements. -As a re-cap for week 1.3: when a series of observations $y_1, …, y_m$ (in our case with $m=N$) is supposed or expected to exhibit a functional linear trend (a straight line in terms of a graph), this can be modelled as - -$$ -\mathbb{E} = \begin{pmatrix} \begin{bmatrix} Y_{1} \\ Y_{2} \\ \vdots \\ Y_{m} \end{bmatrix} \end{pmatrix} - = - \begin{bmatrix} 1 & t_1 - t_1 \\ 1 & t_2 - t_1 \\ \vdots & \vdots \\ 1 & t_m - t_1 \end{bmatrix} - \begin{pmatrix} x_{1} \\ x_{2} \end{pmatrix} -$$ - -with $x_1$ the offset at time $t_1$ (rather than $t=0$), and $x_2$ the slope of the line. The two unknown parameters in this vector $x$ can be estimated through (unweighted) least-squares, $\hat{x}=(A^T A)^{-1} A^T y$, and next the residuals are obtained as $\hat{\epsilon}=y-\hat{y}=y-A\hat{x}$. The residuals are the 'left-over part' of the observations, once the (estimated) trend has been taken out; these residuals are of interest for further spectral analysis! - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 7:</b> - -- For the cantilever-beam acceleration measurements, perform a least-squares estimation according to the above model, and report the estimated offset and slope of the trend. -- The detrended acceleration measurements, hence the elements of vector $\hat{\epsilon}$ are the input to your spectral analysis, so from here on, we denote them by $x(t)$ (in continuous time), and by $x_n$ (in discrete time) with $n=0,…,N-1$. -- Make a plot of the input signal as a function of time, hence of the detrended accelerations. - -Report the estimated offset and slope of the trend (i.e. numerical values). -</ol> -</p> -</div> - -```python -df = pd.read_csv('cantileverbeam_acc50Hz.csv', header=0) - -t = np.array(df['time']) # -dat = np.array(df['acceleration']) # - -N = len(t) - -plt.figure() -plt.plot(t, dat, color='b', label='acceleration signal') -plt.xlabel('time [s]') -plt.ylabel('acceleration [m/s2]') -plt.title('Vertical cantilever beam acceleration') -plt.legend() - -# observation record length (as N*dt, according to sample-and-hold convention) -T = (t[N-1] - t[0])*N/(N - 1) -dt = T/N - -YOUR_CODE_HERE -``` - -**In addition to the code output above, write your answer in this Markdown cell.** - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 8:</b> - -Previously, in Task 3, you computed and plotted the magnitude spectrum $|X_k|$ of a signal for positive frequencies $f>0$ (putting a lot of attention to correctly labelling the horizontal frequency axis of the plot!), and now, with the material of Chapter 6 on spectral estimation, you will estimate the power spectral density $S$ of the signal through the periodogram, which is just: $S(k\Delta f)=\frac{|X_k|^2}{T}$ (in [W/Hz] when $x_n$ is a voltage signal; and $|X_k|$ being the result straight from the <code>np.fft</code>, multiplied by sampling interval $\Delta t$), for frequency $k\Delta f$, with frequency resolution $\Delta f=\frac{1}{T}$, and $k=0,…,N-1$ (hence, pretty much the same procedure as with the magnitude spectrum, though just taking the square of the modulus, and dividing by $T$). - -Compute and plot the periodogram for the detrended accelerometer measurements of Task 7 (if you prefer, feel free to use a linear scaling of the axes here, rather a log-log, and, use $T$ as defined already in the code of Task 7). Please, pay attention to correctly labelling the axes, and stating dimensions of the quantities along the axes! -</p> -</div> - -```python -YOUR_CODE_HERE -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 9:</b> - -Answer the following questions: -<ol> - <li>Report the damped natural frequency (in Hertz) of this one-degree-of-freedom (1DOF) mechanical system. Does it match the motion of the beam shown in the cantilever-beam video?</li> - <li>The acceleration was measured at quite a high sample rate of $50$ Hz. What is the minimum sampling frequency to correctly identify the damped natural frequency in the periodogram?</li> -</ol> -<p> -</div> - - -**Write your answer(s) in this Markdown cell.** - - -## Task 10: Global Mean Sea-Level (GMSL) data (optional) - -Repeat the steps with Tasks 7-9, but now with the Global Mean Sea Level data set. Data is from the Australia's National Science Agency (CSIRO): [GMSL data](https://www.cmar.csiro.au/sealevel/sl_hist_last_decades.html). - -These data result from nearly 3 decades of satellite altimetry (with satellite missions such as TOPEX/Poseidon and the Jason-series). The first column contains the time tag or epoch (in decimal years), the second column is the global mean sea level (in mm). There is one measurement per month (monthly average, so that for instance tide-effects are averaged out, and the measurement typically refers to the middle of the month, hence 1993.042 is mid January in 1993). The single monthly measurement is the global mean sea level, so, the average of the entire world. - -The sampling frequency $f_s = 12$ per year ($\Delta t = 1/12 \sim 0.083$ year), and there are $N=331$ measurements in total. - -```python -data = pd.read_csv('CSIRO_Alt_seas_inc.txt', names=['month', 'sl']) -data.head() -``` - -```python -# create time-array, time relative to t0 [yr] (epoch-time of the first observation; -# t0=1993.042 refers to mid January 1993) -t = data.iloc[:, 0] - data.iloc[0, 0] - -# number of observations -N = len(t) - -# observation record length (as N * dt, according to sample-and-hold convention) -T = (t[N - 1] - t[0]) * N / (N - 1) - -# Delta t [yr]; dt = T/N = (N*dt)/N -dt = T / N - -# observed sea-level height -y = data.iloc[:,1] - -# plot observed time-series, as it is, versus epoch-time in [year] -plt.plot(data.iloc[:,0],y, color='b', label='sea level') -plt.xlabel('time [yr]') -plt.ylabel('sea-level height [mm]') -plt.title('Global Mean Sea-Level (GMSL) rise') -plt.legend(); -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 10 (Optional!):</b> - -Detrend the data. - -Estimate and plot power spectral density (PSD), hence the periodogram, for the (detrended) global mean sea-level data. - -Identify the largest peak in the spectrum, what is the frequency, and can you come up with a physical explanation of this behaviour? -</ol> -</p> -</div> - -```python -YOUR_CODE_HERE -``` - -**Write your answer(s) in this Markdown cell.** - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>End of task.</b> -</p> -</div> - - -<div style="background-color:#C8FFFF; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Appendix A: Cantilever-beam dynamics:</b> - -The dynamics of the smartphone suspended on a cantilever beam can be considered as the mass-spring-damper system shown below: - -<img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/mass_spring_damper.png" style="margin:auto" width=200/> - -The equation of motion of the deflection $x$ of this mass-spring-damper system (a damped harmonic oscillator) can be described by the following second order differential equation: - -$$ -\ddot{x}(t) + \frac{c}{m} \dot{x}(t) + \frac{k}{m} x(t) =0 -$$ - -Where $\ddot{x}(t)$, $\dot{x}(t)$ and $x(t)$ are the acceleration, velocity and displacement as a function of time of the oscillating mass $m$ [kg] respectively. (with a unit transfer function, $x(t)$ describes the motion of the proof mass inside the smartphone accelerometer). For simplicity, we consider here the homogeneous equation, corresponding to free motion. The other parameters are the damping coefficient $c$ [kg/s] and spring constant $k$ [N/m]. The damping ratio can be obtained from the system parameters: $\zeta = \frac{c}{2 \sqrt{mk}}$, which is dimensionless. The undamped natural frequency is $\omega_0 = \sqrt{\frac{k}{m}}$ [rad/s]. The differential equation becomes: - -$$ -\ddot{x}(t) + 2 \zeta \omega_0 \dot{x}(t) + \omega_0^2 x(t) =0 -$$ - -For the under-damped case ($0 \le \zeta \le 1)$ of our smartphone and assuming an initial zero tip velocity $\dot{x}(t=0)=0$ (release from stand-still), the solution for the position as a function of time is given by: - -$$ -x(t)=e^{-\zeta \omega_0 t} \frac{x(0)}{\sqrt{1-\zeta^2}}\sin(\omega_d t + \varphi) -$$ - -Where $x(0)$ is the initial position $x(t=0)$, $\omega_d$ is the damped natural frequency $\omega_d = \omega_0 \sqrt{1-\zeta^2}$, and the phase shift $\varphi = \arctan \left( \frac{\sqrt{1-\zeta^2}}{\zeta} \right)$. The sinusoid term represents the harmonic motion, and the exponential term represents the damping of that motion over time. Next, the velocity of the smartphone's oscillation can be derived as: - -$\dot{x}(t) = e^{-\zeta \omega_0 t} \frac{x(0)}{\sqrt{1-\zeta^2}}\sin(\omega_d t)$. - -The acceleration of the smartphone (which is what is being measured) is found as: - -$\ddot{x}(t) = e^{-\zeta \omega_0 t} \frac{x(0)}{\sqrt{1-\zeta^2}} \sin (\omega_d t - \phi)$. - -Note that $\omega_0$ and $\omega_d$ are the angular frequencies expressed in radians per second. $\ddot{x}(t)$ is a damped harmonic signal where the rate of damping is determined by the damping ratio $\zeta$. - -In order to get a pure harmonic signal (as used in Tasks 1 to 5), set the damping ratio $\zeta=0$, and optionally set the phase-shift $\phi$ to zero as well, then the tip acceleration is given by the following simple sinusoidal expression: - -$$ -\ddot{x}(t)=x(0) \sin(\omega_0 t). -$$ -</p> -</div> - - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/GA_2_3/Analysis.py b/synced_files/students/GA_2_3/Analysis.py deleted file mode 100644 index 64e85d4c0312a4052b34ab428ab8ee90cc4df31e..0000000000000000000000000000000000000000 --- a/synced_files/students/GA_2_3/Analysis.py +++ /dev/null @@ -1,645 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: mude-base -# language: python -# name: python3 -# --- - -# %% [markdown] -# # GA 2.3: Beam Beats -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px"\> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px"\> -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): week 2.3. Due: Friday, November 29, 2024.* - -# %% [markdown] -# ## Analyzing cantilever-beam accelerations and global Mean Sea-Level measurements -# -# This project covers the week on Signal Processing (week 2.3). -# -# As a warming up you will create and analyze some elementary signals yourself, and next, you will carry out frequency domain analyses on two given data-sets, namely acceleration measurements of a Cantilever-Beam experiment, and (in optional Task 10) Global Mean Sea-Level measurements. -# -# Most of the Tasks in this notebook consist of both coding, producing a plot, and answering (open) questions. Typically, as you work your way through the Tasks, you can often re-use code, or part of it, from earlier Tasks and assignments. That will save you a lot of work!! - -# %% [markdown] id="0491cc69" -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>In many of the code blocks below, template code to create figures is provided. Note that there is a lot of code missing, and one line of <code>YOUR_CODE_HERE</code> does not imply that only one line of code is missing!</p></div> - -# %% [markdown] -# ### Data Acquisition System -# -# A data acquisition (DAQ) system usually consists of four components: -# -# <img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/DAQ.png" style="margin:auto"/> -# -# -# - A sensor transforms a physical signal into a small voltage. The transformation is often frequency dependent or nonlinear, and can show drift or bias. -# - Signal conditioning electronics (often included in the sensor housing) filter unwanted frequencies, such as the 50 Hz line frequency caused by power plant generators, using low-pass or notch filters. In addition the sensor voltage may be amplified. -# - An analog-to-digital (A/D) converter samples the analog voltage with a certain rate, such as 100 Hz. The A/D converter can measure analog voltages within a certain range, the measurement range. The measured voltage is quantized with a certain resolution, such as 14-bit, which means that the full measurement range is divided into $2^{14}=16,384$ discrete intervals. Together, the resolution and measurement range determine the precision. Usually the sample rate, the measurement range, and the sample resolution are configurable. Sampling and quantizing together turns an analog signal into a digital signal. -# - A digital computer reads the sampled data from the A/D converter at specific times, and allows for further processing, analysis and storage of the (digital) signal. -# -# The result is that an analog, physical signal, is turned into a series of numbers (samples of the signal, in the time domain), ready for processing and analysis in a digital computer. -# -#  -# -# One of the data sets that you will analyze during this MUDE Q2 project was acquired by an accelerometer in a smartphone, on top of a vertical cantilever-beam. The accelerometer measures the side-ward accelerations, expressed in m/s<sup>2</sup>, and sampled at 50 Hz. Detailed information about the experiment and the sensor can be found in "Experimental evaluation of smartphone accelerometer and low-cost dual frequency GNSS sensors for deformation monitoring", by Alexandru Lapadat, Christian Tiberius and Peter Teunissen, Sensors 2021, 21, 7946, https://doi.org/10.3390/s21237946. -# -# A quick impression of the test setup can be gained by watching the short video [Cantilever Beam Experiment](https://youtu.be/o4moRwvlBLU?si=aKelBMWm3HB2Of26) (1 minute). -# -# A theoretical description of the motion of the smartphone accelerometer fixed to the cantilever beam is presented in Appendix A. Pulling the beam at the tip and releasing it, results in a (nearly) horizontal side-ward motion of the smartphone, and the (horizontal) position can be described by a *damped harmonic* as a function of time. Consequently, also the first and second derivative with respect to time, the velocity and acceleration as a function of time as the smartphone will measure it, are harmonics. -# -# ### Basic sinusoid signal -# -# You will start with first creating (and analyzing) a few simple signals yourself. In the first few Tasks of this project, we will take the damping ratio zero and use a fairly short measurement time (duration), and hence the acceleration measured by the smartphone is a plain (undamped) sinusoid as shown in Appendix A (a stationary signal). In the following Tasks we also add a phase offset $\varphi$ to the plain sinusoid: -# -# $$ -# x(t) = A \sin(2 \pi f_c t + \varphi) -# $$ -# -# The result is taken from the last equation in Appendix A. We consider here acceleration, though for convenience, we omit the dots on top of the $x(t)$. - -# %% -import numpy as np -import pandas as pd -import matplotlib.pyplot as plt - -# %matplotlib inline - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 1:</b> -# -# - Create a time-array starting at $t=0$ s, ending at $t=5.0$ s, with a sampling rate of 100 Hz. Hint: what is the number of samples $N$? And what should then be the last value in the time-array? Note that, for example, with $N=10$ samples at a sampling rate of $f_s = 100$ Hz, we have signal samples at times $t=0.00, 0.01, 0.02, ... , 0.08, 0.09$ seconds, hence $T_{meas}= N \Delta t =0.1$ seconds (the sample-and-hold convention). -# - Create a sinusoidal signal $x(t) = A \sin(2 \pi f_c t + \varphi)$, with amplitude $A=1.0$ Volt, carrier frequency $f_c=1.0$ Hz, and initial phase $\varphi = 5$ degrees, to be converted into radians. -# - Make a plot of the signal against time. Note that this is strictly a *sampled signal* $x_n$ rather than $x(t)$, but since we use a rather high sampling rate, the signal shown is close to continuous in time. Connecting the sample points of $x_n$ in the graph by lines, as done in the graph below, corroborates the suggestion of a continuous-time signal. Be aware! -# </p> -# </div> - -# %% [markdown] id="0491cc69" -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>We will give you the answers in this code cell for free!</p></div> - -# %% -T_meas = 5 -f_s = 100 #sampling rate [Hz] - -t_vec = np.arange(0, T_meas, 1 / f_s) # ends at 4.99, length 500 according to the sample-and-hold convention - -A = 1 -f_c = 1 -phi = 5 * np.pi / 180 -x = A * np.sin(2 * np.pi * f_c * t_vec + phi) - -plt.plot(t_vec, x, color='b', label='signal') -plt.xlabel(r'$t \: [s]$') -plt.ylabel(r'$x(t) \: [V]$') -plt.legend(loc='upper right') -plt.title(fr'Sinusoidal signal with $A$={A} V, $f_c$={f_c} Hz and initial phase $\phi$={phi:.3f} °') -plt.grid() - -# %% [markdown] -# **In addition to the code output above, write your answer in this Markdown cell.** - -# %% [markdown] -# ### The Discrete Fourier Transform (chapter 5) -# -# To discover which frequencies are contained in the signal $x(t)$, we can transform it from the time domain to the frequency domain using the Fourier transform: -# -# $$ -# X(f) = \int_{-\infty}^{\infty} x(t) e^{-j 2\pi f t} dt -# $$ -# -# Which can then be expressed in terms of magnitude and phase: -# -# $$ -# X(f) = |X(f)|e^{j\theta(f)} -# $$ -# -# Where $|X(f)|$ plotted against frequency $f$ is called the *magnitude spectrum* (and practically often referred to as amplitude spectrum). -# -# The set and number of sinusoids required to approximate or re-create a given signal $x(t)$ depends on the shape of that signal. Of course, when the signal is a pure sinusoid, we only need one term. For an example, consider a 2 Hz sinusoidal signal and its magnitude spectrum below (the magnitude spectrum is expressed in [Vs], which equals [V/Hz], hence a magnitude or amplitude density). -# -# <img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/SignalSpectrumExample.png" style="margin:auto" width=800/> - -# %% [markdown] -# You can see a sharp spike in the magnitude plot (which has two logarithmic axes, and we only plot the spectrum for positive frequencies $f>0$). A continuous time sinusoid with amplitude $A$ will produce a magnitude of $\frac{A T_{meas}}{2}$ in the amplitude spectrum (with $T_{meas}$ the *measurement time* or duration), rather than $\frac{A}{2}$ which you would expect (in a double-sided spectrum). This is because of the limited time duration of the input signal, which actually implies multiplication of $x(t)$ by a *rectangular time window* $w(t)=\Pi(\frac{t}{T_{meas}})$. Since the sinusoid has an amplitude of $A=1$ V, and was measured for $T_{meas}=5$ seconds, the magnitude becomes 2.5. The magnitude at all other frequencies is very small, approximately $10^{-15}$, or approximately zero. -# -# The Fourier transform is a continuous-time operation, mapping the continuous time-domain to the continuous frequency domain. Usually, we don't have continuous-time signals, but discrete time signals $x_n$ sampled at a certain sampling rate. The discrete Fourier Transform (DFT) is the discrete-time equivalent of the continuous time-Fourier transform: -# -# $$ -# X_k = \sum_{n=0}^{N-1}x_ne^{-j2\pi kn/N}, k=0,1,...,N-1 -# $$ -# -# Where $X_k$ is the sequence of frequency domain samples. NumPy contains a function to perform the DFT using a fast numerical algorithm, the Fast Fourier Transform: -# -# <code>X_discr = np.fft.fft(x)</code> -# -# For more information on the function see [here](https://numpy.org/doc/stable/reference/generated/numpy.fft.fft.html). -# -# The discrete-time signal $x_n$ and the frequency domain samples $X_k$ returned by Python are of equal length ($N$ samples in, $N$ samples out). When you compare the equations of the DFT with the continuous Fourier Transform, you will see that in the continuous equation we integrate over time $t$, while in the DFT *no information* about the time or sample rate is required (there is no $\Delta t$ in the above equation for $X_k$, as noted at the end of Chapter 5). This results in a *scale factor* in the spectrum when the DFT of signals with different sample rates are compared. To solve this, we have to multiply the DFT as calculated by NumPy by the sample time interval $\Delta t = 1/f_s$ to restore the time dimension and obtain a *discrete approximation of the continuous Fourier Transform*. To account for the measurement duration as described above, we have to divide by $T_{meas} = N \Delta t$. So, in total, multiply by $\Delta t$ and divide by $T_{meas}$, hence, we have to divide the NumPy result by the number of samples $N$: -# -# <code>X_cont = np.fft.fft(x) / N</code> -# -# The DFT only contains information (the complex value of $X_k$) at discrete frequencies, known as the *analysis frequencies*, which are integer multiples of the frequency resolution $f_0$. If we have a sampled signal $x_n$ consisting of $N$ samples, sampled at $f_s$ Hz with $f_s=1/ \Delta t$, the frequency resolution is: -# -# $$ -# f_0 = \frac{1}{T_{meas}} = \frac{1}{N \Delta t} = \frac{f_s}{N} -# $$ -# -# The first value of the complex vector $X_n$ returned by NumPy is the mean of the time-domain signal corresponding to $f=0$ Hz. So, the frequency vector corresponding to the discrete Fourier transform starts at zero and has $N$ elements, the analysis frequencies: -# -# <code>f_vec = np.arange(0, f_s, f_0)</code> -# -# With task 2 you visualize the entire output as you get it from the `np.fft.fft`, hence for frequencies $[0,f_s)$. From Chapter 4 you know that the spectrum of a sampled signal repeats every integer multiple of $f_s$ (copies of the spectrum). - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 2:</b> -# -# - Calculate the Fast Fourier Transform of the signal you generated in Task 1. Remember: the signal has 500 samples and thus does *not* end at exactly 5 second. -# - Create the frequency vector $f$ with the analysis frequencies. -# - Plot the modulus of the Fourier Transform against the frequency $f$ using a log scale on both axes. Use plot markers to see at which frequencies the Fourier transform was calculated. -# -# On top of that, answer to the following questions: -# <ol> -# <li>Describe the amplitude spectrum.</li> -# <li>What is the magnitude of $X(f)$ at $f$ = 1 Hz?</li> -# <li>Do you notice anything peculiar about the amplitude spectrum?</li> -# </ol> -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -# f, axes = plt.subplots(1,1,figsize=(10,5)) - -# axes[0].plot(YOUR_CODE_HERE, YOUR_CODE_HERE, 'x', color='b', label='Fourier transform') -# axes[0].loglog() -# axes[0].set_xlabel('$f \: \: [Hz]$') -# axes[0].set_ylabel('$|X(f)| \: [V]$') -# axes[0].grid() -# axes[0].set_title('Log/Log') - -# %% [markdown] -# **In addition to the code output above, write your answer in this Markdown cell.** - -# %% [markdown] -# ### Symmetry -# -# -# Due to symmetry properties of the DFT, the following holds for a real signal $x(t)$: -# -# $$ -# |X_k| = |X_{-k}| -# $$ -# -# Which means that the modulus of the Fourier coefficients is symmetric about $f=0$. The NumPy <code>fft</code> command appends the Fourier coefficients for $k<0$ to the right side of the Fourier coefficients for $k \ge 0$. This is called the *two-sided* spectrum. -# -# Since we are working with real signals, the symmetry property is valid, and we can just ignore the coefficients for $k<0$. This means that we consider the following range in the frequency domain: -# -# $[0, \frac{f_s}{2}]$ for even values of $N$ -# -# $[0, \frac{f_s}{2})$ for odd values of $N$ -# -# In other words, we are only considering frequencies up to half of $f_s$. This is easily implemented in Python using the floor division operator <code>//</code>: -# -# <code>X_cont = X_cont[:N//2]</code> -# \ -# <code>f_vec = f_vec[:N//2]</code> -# -# If you're unfamiliar with this, consider that <code>A//B</code> returns the number of times <code>B</code> 'fits into' <code>A</code>. In principle, this will always return an integer, so it can be easily used for indexing an array. In this specifc example, <code>N//2</code> will return $\frac{N}{2}$ for even $N$ and $\frac{N-1}{2}$ for odd N, which is exactly what we want. See the example below. - -# %% -N = 100 -print(f'{N} floor divided by 2: {N//2}') -print(f'{N+1} floor divided by 2: {(N+1)//2}') -print(f'{N-1} floor divided by 2: {(N-1)//2}') - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# -# <p> -# <b>Task 3:</b> -# -# - Repeat Task 2 with different measurement times $T_{meas}$ for the signal. Use measurement times such that the $f_c$ = 1 Hz oscillation fits *exactly* 1 time, 5 times and 20 times. -# - Plot the amplitude spectrum for all three measurement times, **only for positive frequencies**, in separate graphs (log-log scale) with the same domains and answer to the following questions: -# -# - What is the effect of changing $T_{meas}$ on the frequency range in the amplitude spectrum? Does the highest analysis frequency change? -# - Does the frequency resolution change? -# - Does the magnitude of at the peaks change? -# -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -plt.figure(figsize=(12,4)) -for i, T_meas in enumerate(YOUR_CODE_HERE): - YOUR_CODE_HERE - - plt.subplot(1, 3, i+1) - - YOUR_CODE_HERE - - plt.grid() - plt.tight_layout() -plt.legend() - -# %% [markdown] -# **In addition to the code output above, write your answer in this Markdown cell.** - -# %% [markdown] -# ### Aliasing (chapter 4) -# -# So far we have been analyzing a signal with a fairly low frequency, just $1$ or $2$ Hz. Now suppose, due to some unexpected source, our signal contains a second sinusoid with a much higher frequency. This is often caused by the line frequency ($50$ Hz) due to power plant generators providing the $220$ V current in regular buildings, or by electrical interference. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# -# <p> -# <b>Task 4: with this task we'll make you run into an aliasing problem . . .</b> -# -# - Create a time-array starting $t=0$, with a sampling rate of 100 Hz, and ending such that a sinusoid with a frequency of 1 Hz fits exactly 5 times in the measurement time. -# -# - Re-create the signal $x(t) = A \sin(2 \pi f_c t + \varphi)$ from the first Task, with amplitude $A=1.0$ V, carrier frequency $f_c=1.0$ Hz, and initial phase $\varphi = 5$ degrees, to be converted into radians. -# -# - Add to this signal a second sinusoid with a frequency of $80$ Hz and amplitude of $0.1$ V (and zero initial phase). -# -# - Create a plot of the signal against time, and of the amplitude spectrum as in the previous Tasks. -# -# Then answer to the following questions: -# <ol> -# <li>What do you see in the frequency plot? Are there peaks? How many? Where?</li> -# <li>Does this match what you see in the time plot?</li> -# <li>Does changing the measurement time (duration) help?</li> -# </ol> -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -# plt.figure(figsize=(12,6)) -# plt.subplot(211) -# YOUR_CODE_HERE -# plt.grid() -# plt.title('Time signal') -# plt.legend() - -# plt.subplot(212) -# YOUR_CODE_HERE -# plt.loglog() -# YOUR_CODE_HERE -# plt.grid() -# plt.tight_layout() -# plt.title('Amplitude spectrum') -# plt.legend() - -# %% [markdown] -# **In addition to the code output above, write your answer in this Markdown cell.** - -# %% [markdown] -# The effect seen in Task 4 is called *aliasing*, and the cause is that if your sample rate is too low for the signals you're measuring, you will not capture their oscillation period sufficiently - with at least two samples per cycle. Instead, the signal will appear at a much lower frequency, as you can see in the figure below. Here $f_c = 5$ Hz, and the signal was sampled with $f_c = 7$ Hz, and based on the discrete time samples we incorrectly conclude that there is a frequency component at $2$ Hz (at the end of Chapter 4). -# -# <img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/NewSlide38.png" style="margin:auto" width=800/> -# <img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/NewSlide51.png" style="margin:auto" width=800/> -# -# So, how fast do we need to sample to capture an $80$ Hz signal? - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 5:</b> -# -# Repeat Task 4 with different sample rates: $110, 150, 160,$ and $200$ Hz. Plot the signal and amplitude spectrum for each one (you might want to use a loop). -# -# Then answer the following questions: -# <ol> -# <li>At what frequency does the (aliased) 80 Hz signal appear in the spectrum, for the above values of $f_s$ (provide numerical answers)?</li> -# <li>Can you figure out the relationship (a simple equation) between the sample rate and the frequency of the original signal, and the frequency at which the alias appears?</li> -# </ol> -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -# for YOUR_CODE_HERE: - -# YOUR_CODE_HERE - -# plt.figure(figsize=(12,6)) -# plt.suptitle(f'$f_s = {YOUR_CODE_HERE}$ Hz') -# plt.subplot(211) -# YOUR_CODE_HERE -# plt.grid() -# plt.legend() - -# plt.subplot(212) -# YOUR_CODE_HERE -# plt.loglog() -# plt.grid() -# plt.tight_layout() -# plt.legend() - -# %% [markdown] -# **In addition to the code output above, write your answer in this Markdown cell.** - -# %% [markdown] -# As you probably figured out, the sample rate needs to be faster than twice the largest frequency in the signal. In other words, you can measure signals with a frequency up to half the sample rate without aliasing becoming a problem. The frequency above which aliasing occurs (half the sampling rate) is called the *Nyquist frequency* (Chapter 4). - -# %% [markdown] -# ### Damped vibrations -# -# We now know how to create an amplitude/magnitude spectrum. We've seen that we get aliasing if our signal has components at frequencies higher than the *Nyquist frequency* (and leakage if the measurement time is too short). Now, let's consider the damped vibration aceleration signal that an accelerometer would measure (see *Appendix A*). In this case the damping ratio is not equal to zero, unlike in Tasks 1 to 5. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 6:</b> -# -# - Create a time-array starting at $t=0$ s, ending at $t = 50$ s, with a sampling rate of $100$ Hz. -# - Create a damped harmonic acceleration signal $x(t) = \frac{x(0)}{\sqrt{1-\zeta^2}} e^{-\zeta \omega_0 t} \sin(\omega_d t)$ with $\zeta = 0.05$, $\omega_0 = 10 \pi$ rad/s (corresponding to $5$ Hz), $\omega_d = \omega_0 \sqrt{1-\zeta^2} = 9.987 \pi$ rad/s, and initial displacement $x(0)=1$ (for convenience the initial phase of the signal is kept to zero). -# - Create a plot of the signal against time, and of the amplitude spectrum as in the previous Tasks. -# -# Then answer the following questions: -# <ol> -# <li>Do you see any changes in the time plot, compared to the earlier plot? Describe them!</li> -# <li>What is the dominant frequency of the signal now?</li> -# </ol> -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# # Write your own code or use the template below to create your figure(s) - -# plt.figure(figsize=(12,6)) -# plt.subplot(211) -# YOUR_CODE_HERE -# plt.grid() -# plt.legend() - -# plt.subplot(212) -# YOUR_CODE_HERE -# plt.loglog() -# YOUR_CODE_HERE -# plt.grid() -# plt.tight_layout() -# plt.legend() - -# %% [markdown] -# **In addition to the code output above, write your answer in this Markdown cell.** - -# %% [markdown] -# ### Cantilever-beam acceleration measurements -# -# Now you're ready to start analyzing the cantilever-beam acceleration measurements. -# -# Read in the data-file: *cantileverbeam_acc50Hz.csv*. -# -# This dataset contains 5 minutes of measurements with a sampling rate of $50$ Hz (a total of $N=15001$ samples). The first column in the file contains the UTC time of day (in seconds), the second column contains the measured acceleration (in m/s<sup>2</sup>). - -# %% [markdown] -# ### Detrending -# -# In this project the signal of interest is the damped, harmonic motion of the cantilever-beam. In addition the measurements may contain (unwanted) effects of the sensor (think of an offset, due to imperfect manufacturing and/or prior calibration, or a drift over time, for instance due to temperature changes in the electronics during the experiment). By detrending we mean to remove such effects, prior to our spectral analysis, so that we can start with a nice, zero mean signal. A-priori detrending is good practice and generally yields a cleaner spectrum. Next week (week 2.4 on Time Series Analysis) we cover the subject of removing unwanted effects from the signal in more detail, as to obtain a so-called **stationary** signal, meaning that the properties or characteristics of the signal (such as the mean) do not change over time, and, we provide practical means to “stationarize†a given or measured signal. -# -# There are built-in functions in Python to remove such an offset and/or trend (and you're free to use them). But, earlier in the MUDE, in week 1.3, you learned about least-squares parameter estimation, and that's what you can apply to do the detrending (and actually built-in functions just apply the very same principle). Next week, on Time Series Analysis, you will actually be covering (again) the estimation of a trend in a time series of measurements. -# As a re-cap for week 1.3: when a series of observations $y_1, …, y_m$ (in our case with $m=N$) is supposed or expected to exhibit a functional linear trend (a straight line in terms of a graph), this can be modelled as -# -# $$ -# \mathbb{E} = \begin{pmatrix} \begin{bmatrix} Y_{1} \\ Y_{2} \\ \vdots \\ Y_{m} \end{bmatrix} \end{pmatrix} -# = -# \begin{bmatrix} 1 & t_1 - t_1 \\ 1 & t_2 - t_1 \\ \vdots & \vdots \\ 1 & t_m - t_1 \end{bmatrix} -# \begin{pmatrix} x_{1} \\ x_{2} \end{pmatrix} -# $$ -# -# with $x_1$ the offset at time $t_1$ (rather than $t=0$), and $x_2$ the slope of the line. The two unknown parameters in this vector $x$ can be estimated through (unweighted) least-squares, $\hat{x}=(A^T A)^{-1} A^T y$, and next the residuals are obtained as $\hat{\epsilon}=y-\hat{y}=y-A\hat{x}$. The residuals are the 'left-over part' of the observations, once the (estimated) trend has been taken out; these residuals are of interest for further spectral analysis! - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 7:</b> -# -# - For the cantilever-beam acceleration measurements, perform a least-squares estimation according to the above model, and report the estimated offset and slope of the trend. -# - The detrended acceleration measurements, hence the elements of vector $\hat{\epsilon}$ are the input to your spectral analysis, so from here on, we denote them by $x(t)$ (in continuous time), and by $x_n$ (in discrete time) with $n=0,…,N-1$. -# - Make a plot of the input signal as a function of time, hence of the detrended accelerations. -# -# Report the estimated offset and slope of the trend (i.e. numerical values). -# </ol> -# </p> -# </div> - -# %% -df = pd.read_csv('cantileverbeam_acc50Hz.csv', header=0) - -t = np.array(df['time']) # -dat = np.array(df['acceleration']) # - -N = len(t) - -plt.figure() -plt.plot(t, dat, color='b', label='acceleration signal') -plt.xlabel('time [s]') -plt.ylabel('acceleration [m/s2]') -plt.title('Vertical cantilever beam acceleration') -plt.legend() - -# observation record length (as N*dt, according to sample-and-hold convention) -T = (t[N-1] - t[0])*N/(N - 1) -dt = T/N - -YOUR_CODE_HERE - -# %% [markdown] -# **In addition to the code output above, write your answer in this Markdown cell.** - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 8:</b> -# -# Previously, in Task 3, you computed and plotted the magnitude spectrum $|X_k|$ of a signal for positive frequencies $f>0$ (putting a lot of attention to correctly labelling the horizontal frequency axis of the plot!), and now, with the material of Chapter 6 on spectral estimation, you will estimate the power spectral density $S$ of the signal through the periodogram, which is just: $S(k\Delta f)=\frac{|X_k|^2}{T}$ (in [W/Hz] when $x_n$ is a voltage signal; and $|X_k|$ being the result straight from the <code>np.fft</code>, multiplied by sampling interval $\Delta t$), for frequency $k\Delta f$, with frequency resolution $\Delta f=\frac{1}{T}$, and $k=0,…,N-1$ (hence, pretty much the same procedure as with the magnitude spectrum, though just taking the square of the modulus, and dividing by $T$). -# -# Compute and plot the periodogram for the detrended accelerometer measurements of Task 7 (if you prefer, feel free to use a linear scaling of the axes here, rather a log-log, and, use $T$ as defined already in the code of Task 7). Please, pay attention to correctly labelling the axes, and stating dimensions of the quantities along the axes! -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 9:</b> -# -# Answer the following questions: -# <ol> -# <li>Report the damped natural frequency (in Hertz) of this one-degree-of-freedom (1DOF) mechanical system. Does it match the motion of the beam shown in the cantilever-beam video?</li> -# <li>The acceleration was measured at quite a high sample rate of $50$ Hz. What is the minimum sampling frequency to correctly identify the damped natural frequency in the periodogram?</li> -# </ol> -# <p> -# </div> - -# %% [markdown] -# **Write your answer(s) in this Markdown cell.** - -# %% [markdown] -# ## Task 10: Global Mean Sea-Level (GMSL) data (optional) -# -# Repeat the steps with Tasks 7-9, but now with the Global Mean Sea Level data set. Data is from the Australia's National Science Agency (CSIRO): [GMSL data](https://www.cmar.csiro.au/sealevel/sl_hist_last_decades.html). -# -# These data result from nearly 3 decades of satellite altimetry (with satellite missions such as TOPEX/Poseidon and the Jason-series). The first column contains the time tag or epoch (in decimal years), the second column is the global mean sea level (in mm). There is one measurement per month (monthly average, so that for instance tide-effects are averaged out, and the measurement typically refers to the middle of the month, hence 1993.042 is mid January in 1993). The single monthly measurement is the global mean sea level, so, the average of the entire world. -# -# The sampling frequency $f_s = 12$ per year ($\Delta t = 1/12 \sim 0.083$ year), and there are $N=331$ measurements in total. - -# %% -data = pd.read_csv('CSIRO_Alt_seas_inc.txt', names=['month', 'sl']) -data.head() - -# %% -# create time-array, time relative to t0 [yr] (epoch-time of the first observation; -# t0=1993.042 refers to mid January 1993) -t = data.iloc[:, 0] - data.iloc[0, 0] - -# number of observations -N = len(t) - -# observation record length (as N * dt, according to sample-and-hold convention) -T = (t[N - 1] - t[0]) * N / (N - 1) - -# Delta t [yr]; dt = T/N = (N*dt)/N -dt = T / N - -# observed sea-level height -y = data.iloc[:,1] - -# plot observed time-series, as it is, versus epoch-time in [year] -plt.plot(data.iloc[:,0],y, color='b', label='sea level') -plt.xlabel('time [yr]') -plt.ylabel('sea-level height [mm]') -plt.title('Global Mean Sea-Level (GMSL) rise') -plt.legend(); - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 10 (Optional!):</b> -# -# Detrend the data. -# -# Estimate and plot power spectral density (PSD), hence the periodogram, for the (detrended) global mean sea-level data. -# -# Identify the largest peak in the spectrum, what is the frequency, and can you come up with a physical explanation of this behaviour? -# </ol> -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# %% [markdown] -# **Write your answer(s) in this Markdown cell.** - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>End of task.</b> -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#C8FFFF; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Appendix A: Cantilever-beam dynamics:</b> -# -# The dynamics of the smartphone suspended on a cantilever beam can be considered as the mass-spring-damper system shown below: -# -# <img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/mass_spring_damper.png" style="margin:auto" width=200/> -# -# The equation of motion of the deflection $x$ of this mass-spring-damper system (a damped harmonic oscillator) can be described by the following second order differential equation: -# -# $$ -# \ddot{x}(t) + \frac{c}{m} \dot{x}(t) + \frac{k}{m} x(t) =0 -# $$ -# -# Where $\ddot{x}(t)$, $\dot{x}(t)$ and $x(t)$ are the acceleration, velocity and displacement as a function of time of the oscillating mass $m$ [kg] respectively. (with a unit transfer function, $x(t)$ describes the motion of the proof mass inside the smartphone accelerometer). For simplicity, we consider here the homogeneous equation, corresponding to free motion. The other parameters are the damping coefficient $c$ [kg/s] and spring constant $k$ [N/m]. The damping ratio can be obtained from the system parameters: $\zeta = \frac{c}{2 \sqrt{mk}}$, which is dimensionless. The undamped natural frequency is $\omega_0 = \sqrt{\frac{k}{m}}$ [rad/s]. The differential equation becomes: -# -# $$ -# \ddot{x}(t) + 2 \zeta \omega_0 \dot{x}(t) + \omega_0^2 x(t) =0 -# $$ -# -# For the under-damped case ($0 \le \zeta \le 1)$ of our smartphone and assuming an initial zero tip velocity $\dot{x}(t=0)=0$ (release from stand-still), the solution for the position as a function of time is given by: -# -# $$ -# x(t)=e^{-\zeta \omega_0 t} \frac{x(0)}{\sqrt{1-\zeta^2}}\sin(\omega_d t + \varphi) -# $$ -# -# Where $x(0)$ is the initial position $x(t=0)$, $\omega_d$ is the damped natural frequency $\omega_d = \omega_0 \sqrt{1-\zeta^2}$, and the phase shift $\varphi = \arctan \left( \frac{\sqrt{1-\zeta^2}}{\zeta} \right)$. The sinusoid term represents the harmonic motion, and the exponential term represents the damping of that motion over time. Next, the velocity of the smartphone's oscillation can be derived as: -# -# $\dot{x}(t) = e^{-\zeta \omega_0 t} \frac{x(0)}{\sqrt{1-\zeta^2}}\sin(\omega_d t)$. -# -# The acceleration of the smartphone (which is what is being measured) is found as: -# -# $\ddot{x}(t) = e^{-\zeta \omega_0 t} \frac{x(0)}{\sqrt{1-\zeta^2}} \sin (\omega_d t - \phi)$. -# -# Note that $\omega_0$ and $\omega_d$ are the angular frequencies expressed in radians per second. $\ddot{x}(t)$ is a damped harmonic signal where the rate of damping is determined by the damping ratio $\zeta$. -# -# In order to get a pure harmonic signal (as used in Tasks 1 to 5), set the damping ratio $\zeta=0$, and optionally set the phase-shift $\phi$ to zero as well, then the tip acceleration is given by the following simple sinusoidal expression: -# -# $$ -# \ddot{x}(t)=x(0) \sin(\omega_0 t). -# $$ -# </p> -# </div> - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/GA_2_3/Analysis_solution.ipynb b/synced_files/students/GA_2_3/Analysis_solution.ipynb deleted file mode 100644 index cc7f631cce4f2c9d36902164d74cc79d2602a569..0000000000000000000000000000000000000000 --- a/synced_files/students/GA_2_3/Analysis_solution.ipynb +++ /dev/null @@ -1,1418 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# GA 2.3: Beam Beats\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px\"\\>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px\"\\>\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): week 2.3. Due: Friday, November 29, 2024.*" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Analyzing cantilever-beam accelerations and global Mean Sea-Level measurements\n", - "\n", - "This project covers the week on Signal Processing (week 2.3).\n", - "\n", - "As a warming up you will create and analyze some elementary signals yourself, and next, you will carry out frequency domain analyses on two given data-sets, namely acceleration measurements of a Cantilever-Beam experiment, and (in optional Task 10) Global Mean Sea-Level measurements.\n", - "\n", - "Most of the Tasks in this notebook consist of both coding, producing a plot, and answering (open) questions. Typically, as you work your way through the Tasks, you can often re-use code, or part of it, from earlier Tasks and assignments. That will save you a lot of work!!" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "0491cc69" - }, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\"> <p>In many of the code blocks below, template code to create figures is provided. Note that there is a lot of code missing, and one line of <code>YOUR_CODE_HERE</code> does not imply that only one line of code is missing!</p></div>" - ] - }, - { - "attachments": { - "verticalcantileverbeam.png": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAcsAAAKNCAMAAAB4NbCZAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAbUExURQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///5TvxDIAAAAHdFJOUwA8QHaAuL+mjBuqAAAACXBIWXMAADLAAAAywAEoZFrbAAAWlElEQVR4Xu3bi3baCLZF0fgRu///i1taWgJssAMSAja157ijQ52DhNEKj1Tq/qmqqqqqqqqqqqqqqqqqqqqqqqqqqqqq/5jPz09vVbq2fB5t+TzaMsjb5+eLN09pyyBDyzdvntKWQdryebTl3b0MDT4///7ls264MUzGfyYLu2mDt79/xzu/zZPx7uN9/k4nmQzL4Z/G/x3vvMs73J5P6ATcaX9Gf4Jx+OVuPPDBT1InjOHApRuvFxd38LLbeVV3d919yRnvzj+/Hbfc3Xt3388/+1Pr9CmP7jYPDkZ1ZLyYby8vb2/TC3G4kuOAFwsvhenmdAWHW3//vk3Zpsl09+F/3v5wx3E7nme4y/B/832569hyuMd0vvndlpSnTvn1bkxeXmjsqI6NV92bo/EC8k7my22cDVdwemG+ze9xw2Q6iDs5PDwVbTiI3yvMGHHf3Wi8NZ16zDTdOnG34Ry+M+weuE4YrvrcYrS7uLwWps2Ygxs7w2TfZ3f4t5bOx5vcGH711MNourULOD3IXPDE3eYHmU9WJ+wu2GR/rQ4WRxdw90KZA2A44qDl7vUz3+fgLPPNw8PnQ07ebfcjHmSt78bXw0HM/ZU8yPH1Ak6fW7uW/IpFLfl1NBzCOY/vNp5seFC05W/GmP4JZLC/kidbTt9IRue3HA7h9sF9vbl7eY/Gn2P89fhuw8kO7U5cR/wTwHSJhhv8erKl98T9WrKqn9Do2zvciZbDr/4rhG1afvsJ5puHJ6t/G3/vj7/ur+Rxy2Hipb+0Jb8TjiPNL0XMZz++2/5x6yy+evZX8iDHvqWTi1rO9zmONP5K5tGvL9/dqM7g1d9ftt9aDrf+2XKuNBx8dN/55m53EOzE3YZfd8nrZ/Pl93rtr+TJltNyvO4nWh68fsa7ToePw+k8B/edb+6XJ0853zz4nfFn/y/h67vxGk7/PpRLub+Sxy2578vL9OeSH1r+HbbDfWk5nID7+tIbbk03Dm5yquHhz7zbeD/vVse4TKPvcU60HGNhuKYnWs4Fp5a7vzmZL/5w01tfH0W/3m33U7blb6a/kpzfuobb041TLf3bx+FqvnlJ93cHr8xxw8HTveeTHN53mHtrutP8t6ej3+/G38LULdGynkJbPo+2fB5t+Tza8nm0ZT2p8c9TW/D0dUNe+qvz9Hvvr96orXjpr87T77x/fjbmxrz0V+fpZx+fn+/erK146a/O009eh0FflZs7vvCrHZ1yeH/98GZt6OjCr/f9lEPKvr/ewvcLfwXfTtmPylv5duGv4csph4/Kj35U3saXC38dh6fsR+UNHV74Kzk4ZT8qb+ngwl/L7pSv/ai8qd2Fv575lP2ovLH5wl+Rp+xH5a154a9pOmU/Km9uuvBXxSmHj8q+v94YF97bV8Ip+1F5e1x3b18Jp+xH5e1x4b19JRucss6xwYXf4JR1jg0u/AanrHNscOE3OGWdY4MLv8Ep6xwbXPgNTlnn2ODCb3DKOscGF36DU9Y5NrjwG5yyzrHBhd/glHWODS78Bqesc2xw4Tc4ZZ1jgwu/wSnrHBtc+A1OWefY4MJvcMo6xwYXfoNT1jm48Bvw9HVDXvqr8/R1Q176q/P0dUNe+qvz9HVDXvqr8/T1UEjzvwMMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWFNKZEQxcVhTSmREMXFYU0pkRDFxWjNfX13fSmREM3t9fX71TPbQh4cfHB9EmZoSj0cdHmz6wsaKlxlYfP74uD1sPST28HsM+45BweHudpgzMCAbTbnj9vu+SDi/RaVqbOesKv+4zfnvTZGpGMHA5Gd+SmfYFurEPf/3R6+tU4igjWJkRDFwe2L1Eh9e0o7qy999b+oIcOjr4jj5mBAOX380v0ObcxOcvLecX5G9XnnuYEQxcnvI+fV3617tta1/s/ceWU8h/viMSxoxg4PIH/qn015x96V7qdajlzS+mz8hfX5CiihnBwOXPfLf9uebHPz/H66vhBXLimk0hzym5uOWInD+9OD9+6VwnjO9131v63nruW9x454Uth8fnzfZktOGn8FadZbySX1ue/d46G0+xuOVgqnmcc/g5+sK8ANfxsOXFJde3/OnFOf4k3qwzjNfwoCUlL30xcA4zgoHLc52oueRn+Q/jCu5aLip5pZYnao4/zedF7xD/ZcOfR0ZTy7HkZW+u4hxmBAOXl/hWk5ZfP8vrR9PLkuu1uOQVW04/0O5bEC37wjyPKYeWK0peteWXmpymL8zzTBdruFxcQIeX4xxmBAOXl9v9MJymL8yzzC/L0fKSV2+5q8lp+sI8i9dqtOr3PmcwIxi4XGao+eEXs74wz3D4svz9Lyz+gROYEQxcLnT4w/WF+S9fUo4W1+RoM4KBy8Wmb7HoC/MfjloONZddNI41Ixi4XIh/bTHrC/N3J1IOFr3VcqQZwcDlEl9CjtZ8M/sP8Codu/y6cZgZwcDl5Y5KDlzVKadflqPL/zafw8wIBi4vdCrkoC/MX3iN9sb/AH33Xy9fhuPNCAYuL7H7j2iP9evPj/YvyxUNZ5zHjGDg8hLvB/+N+zf9+vOTIeUVGs642GYEA5eXO/z/WtjrC/MmuNZmBAOXSw1FvyTtC/MmuNZmBAOXK+1fpH1h3gKX2oxg4PIqxhdpv8reAunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYuKwrpzAgGLisK6cwIBi4rCunMCAYu68871yOIGeEoz7tX/7riWj6Ftnwebfk82vJ5tOXzaMvnsU3LRebfAIt+pFUH3+/odQ/8sOan9eo/X2TVwfc7et0DP6yP6Vl9+I+XWXXw/Y5e98CP6tWntei9ZtXB9zt63QM/rNfpWS1Muebg+x297oEf1vyxsehprTr4fkeve+CHNT+tfuuJ58fGx6Knterg+x297oEf1fwNYNGXuVUH3+/odQ/8sPqt52nMHxuLntaqg+939LoHfljz01r0sbHq4Psdve6BH9b8sbHoaa06uN96rqvfep5Gv/U8jfljY9HTWnXw/Y5e98APa35aiz42Vh18v6PXPfDDmj82Fj2tVQf3W8+VzU/Lf7zMqoPvd/S6B35U/dbzNOaPjUVPa9XB9zt63QM/rKZ8GvPTWvQNYNXB9zt63QM/rH7reRb91vM0mvJpzB8bi57WqoPvd/S6B35Y89Pqt5548zeARU9r1cH3O3rdAz+q/mXl0+i3nqcxf2wselqrDr7f0ese+GHNT2vRx8aqg+939LoHfljzx8aip7Xq4H7rua5+63ka/dbzNOaPjUVPa9XB9zt63QM/rPlpLfrYWHXw/Y5e98APa/7YWPS0Vh3cbz3X1W89T6Pfep7G/LGx6GmtOvh+R6974Ic1P61FHxurDr7f0ese+GH5tJZ9A1h18P2OXvfAD2vVN4B1Xx/udnS/9Rzpt56H4u/QZU9r1cH3O3rdAz+u6ffowqe16uD7Hb3ugR/Y+MQWfwNYdfD9jl73wA/sfc03gFUH3+/odQ9ctaU/f/4PDvMXtjrnOloAAAAASUVORK5CYII=" - } - }, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Data Acquisition System\n", - "\n", - "A data acquisition (DAQ) system usually consists of four components:\n", - "\n", - "<img src=\"https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/DAQ.png\" style=\"margin:auto\"/>\n", - "\n", - "\n", - "- A sensor transforms a physical signal into a small voltage. The transformation is often frequency dependent or nonlinear, and can show drift or bias.\n", - "- Signal conditioning electronics (often included in the sensor housing) filter unwanted frequencies, such as the 50 Hz line frequency caused by power plant generators, using low-pass or notch filters. In addition the sensor voltage may be amplified.\n", - "- An analog-to-digital (A/D) converter samples the analog voltage with a certain rate, such as 100 Hz. The A/D converter can measure analog voltages within a certain range, the measurement range. The measured voltage is quantized with a certain resolution, such as 14-bit, which means that the full measurement range is divided into $2^{14}=16,384$ discrete intervals. Together, the resolution and measurement range determine the precision. Usually the sample rate, the measurement range, and the sample resolution are configurable. Sampling and quantizing together turns an analog signal into a digital signal.\n", - "- A digital computer reads the sampled data from the A/D converter at specific times, and allows for further processing, analysis and storage of the (digital) signal.\n", - "\n", - "The result is that an analog, physical signal, is turned into a series of numbers (samples of the signal, in the time domain), ready for processing and analysis in a digital computer.\n", - "\n", - "\n", - "\n", - "One of the data sets that you will analyze during this MUDE Q2 project was acquired by an accelerometer in a smartphone, on top of a vertical cantilever-beam. The accelerometer measures the side-ward accelerations, expressed in m/s<sup>2</sup>, and sampled at 50 Hz. Detailed information about the experiment and the sensor can be found in \"Experimental evaluation of smartphone accelerometer and low-cost dual frequency GNSS sensors for deformation monitoring\", by Alexandru Lapadat, Christian Tiberius and Peter Teunissen, Sensors 2021, 21, 7946, https://doi.org/10.3390/s21237946.\n", - "\n", - "A quick impression of the test setup can be gained by watching the short video [Cantilever Beam Experiment](https://youtu.be/o4moRwvlBLU?si=aKelBMWm3HB2Of26) (1 minute).\n", - "\n", - "A theoretical description of the motion of the smartphone accelerometer fixed to the cantilever beam is presented in Appendix A. Pulling the beam at the tip and releasing it, results in a (nearly) horizontal side-ward motion of the smartphone, and the (horizontal) position can be described by a *damped harmonic* as a function of time. Consequently, also the first and second derivative with respect to time, the velocity and acceleration as a function of time as the smartphone will measure it, are harmonics.\n", - "\n", - "### Basic sinusoid signal\n", - "\n", - "You will start with first creating (and analyzing) a few simple signals yourself. In the first few Tasks of this project, we will take the damping ratio zero and use a fairly short measurement time (duration), and hence the acceleration measured by the smartphone is a plain (undamped) sinusoid as shown in Appendix A (a stationary signal). In the following Tasks we also add a phase offset $\\varphi$ to the plain sinusoid:\n", - "\n", - "$$\n", - "x(t) = A \\sin(2 \\pi f_c t + \\varphi)\n", - "$$\n", - "\n", - "The result is taken from the last equation in Appendix A. We consider here acceleration, though for convenience, we omit the dots on top of the $x(t)$." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import matplotlib.pyplot as plt\n", - "\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 1:</b>\n", - "\n", - "- Create a time-array starting at $t=0$ s, ending at $t=5.0$ s, with a sampling rate of 100 Hz. Hint: what is the number of samples $N$? And what should then be the last value in the time-array? Note that, for example, with $N=10$ samples at a sampling rate of $f_s = 100$ Hz, we have signal samples at times $t=0.00, 0.01, 0.02, ... , 0.08, 0.09$ seconds, hence $T_{meas}= N \\Delta t =0.1$ seconds (the sample-and-hold convention).\n", - "- Create a sinusoidal signal $x(t) = A \\sin(2 \\pi f_c t + \\varphi)$, with amplitude $A=1.0$ Volt, carrier frequency $f_c=1.0$ Hz, and initial phase $\\varphi = 5$ degrees, to be converted into radians.\n", - "- Make a plot of the signal against time. Note that this is strictly a *sampled signal* $x_n$ rather than $x(t)$, but since we use a rather high sampling rate, the signal shown is close to continuous in time. Connecting the sample points of $x_n$ in the graph by lines, as done in the graph below, corroborates the suggestion of a continuous-time signal. Be aware!\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "0491cc69" - }, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\"> <p>We will give you the answers in this code cell for free!</p></div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "T_meas = 5\n", - "f_s = 100 #sampling rate [Hz]\n", - "\n", - "t_vec = np.arange(0, T_meas, 1 / f_s) # ends at 4.99, length 500 according to the sample-and-hold convention\n", - "\n", - "A = 1 \n", - "f_c = 1 \n", - "phi = 5 * np.pi / 180\n", - "x = A * np.sin(2 * np.pi * f_c * t_vec + phi)\n", - "\n", - "plt.plot(t_vec, x, color='b', label='signal')\n", - "plt.xlabel(r'$t \\: [s]$')\n", - "plt.ylabel(r'$x(t) \\: [V]$')\n", - "plt.legend(loc='upper right')\n", - "plt.title(fr'Sinusoidal signal with $A$={A} V, $f_c$={f_c} Hz and initial phase $\\phi$={phi:.3f} °')\n", - "plt.grid()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**In addition to the code output above, write your answer in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Solution:</b>\n", - " \n", - "The number of samples is $N=\\frac{T_{meas}}{\\Delta t}=T_{meas}\\cdot f_s=5\\cdot 100=500$.\n", - "The last value should be $4.99$ because we use a $\\Delta t=\\frac{1}{f_s}=0.01$ s.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### The Discrete Fourier Transform (chapter 5)\n", - "\n", - "To discover which frequencies are contained in the signal $x(t)$, we can transform it from the time domain to the frequency domain using the Fourier transform:\n", - "\n", - "$$\n", - "X(f) = \\int_{-\\infty}^{\\infty} x(t) e^{-j 2\\pi f t} dt\n", - "$$\n", - "\n", - "Which can then be expressed in terms of magnitude and phase:\n", - "\n", - "$$\n", - "X(f) = |X(f)|e^{j\\theta(f)}\n", - "$$\n", - "\n", - "Where $|X(f)|$ plotted against frequency $f$ is called the *magnitude spectrum* (and practically often referred to as amplitude spectrum).\n", - "\n", - "The set and number of sinusoids required to approximate or re-create a given signal $x(t)$ depends on the shape of that signal. Of course, when the signal is a pure sinusoid, we only need one term. For an example, consider a 2 Hz sinusoidal signal and its magnitude spectrum below (the magnitude spectrum is expressed in [Vs], which equals [V/Hz], hence a magnitude or amplitude density).\n", - "\n", - "<img src=\"https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/SignalSpectrumExample.png\" style=\"margin:auto\" width=800/>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can see a sharp spike in the magnitude plot (which has two logarithmic axes, and we only plot the spectrum for positive frequencies $f>0$). A continuous time sinusoid with amplitude $A$ will produce a magnitude of $\\frac{A T_{meas}}{2}$ in the amplitude spectrum (with $T_{meas}$ the *measurement time* or duration), rather than $\\frac{A}{2}$ which you would expect (in a double-sided spectrum). This is because of the limited time duration of the input signal, which actually implies multiplication of $x(t)$ by a *rectangular time window* $w(t)=\\Pi(\\frac{t}{T_{meas}})$. Since the sinusoid has an amplitude of $A=1$ V, and was measured for $T_{meas}=5$ seconds, the magnitude becomes 2.5. The magnitude at all other frequencies is very small, approximately $10^{-15}$, or approximately zero.\n", - "\n", - "The Fourier transform is a continuous-time operation, mapping the continuous time-domain to the continuous frequency domain. Usually, we don't have continuous-time signals, but discrete time signals $x_n$ sampled at a certain sampling rate. The discrete Fourier Transform (DFT) is the discrete-time equivalent of the continuous time-Fourier transform:\n", - "\n", - "$$\n", - "X_k = \\sum_{n=0}^{N-1}x_ne^{-j2\\pi kn/N}, k=0,1,...,N-1\n", - "$$\n", - "\n", - "Where $X_k$ is the sequence of frequency domain samples. NumPy contains a function to perform the DFT using a fast numerical algorithm, the Fast Fourier Transform:\n", - "\n", - "<code>X_discr = np.fft.fft(x)</code>\n", - "\n", - "For more information on the function see [here](https://numpy.org/doc/stable/reference/generated/numpy.fft.fft.html).\n", - "\n", - "The discrete-time signal $x_n$ and the frequency domain samples $X_k$ returned by Python are of equal length ($N$ samples in, $N$ samples out). When you compare the equations of the DFT with the continuous Fourier Transform, you will see that in the continuous equation we integrate over time $t$, while in the DFT *no information* about the time or sample rate is required (there is no $\\Delta t$ in the above equation for $X_k$, as noted at the end of Chapter 5). This results in a *scale factor* in the spectrum when the DFT of signals with different sample rates are compared. To solve this, we have to multiply the DFT as calculated by NumPy by the sample time interval $\\Delta t = 1/f_s$ to restore the time dimension and obtain a *discrete approximation of the continuous Fourier Transform*. To account for the measurement duration as described above, we have to divide by $T_{meas} = N \\Delta t$. So, in total, multiply by $\\Delta t$ and divide by $T_{meas}$, hence, we have to divide the NumPy result by the number of samples $N$:\n", - "\n", - "<code>X_cont = np.fft.fft(x) / N</code>\n", - "\n", - "The DFT only contains information (the complex value of $X_k$) at discrete frequencies, known as the *analysis frequencies*, which are integer multiples of the frequency resolution $f_0$. If we have a sampled signal $x_n$ consisting of $N$ samples, sampled at $f_s$ Hz with $f_s=1/ \\Delta t$, the frequency resolution is:\n", - "\n", - "$$\n", - "f_0 = \\frac{1}{T_{meas}} = \\frac{1}{N \\Delta t} = \\frac{f_s}{N}\n", - "$$\n", - "\n", - "The first value of the complex vector $X_n$ returned by NumPy is the mean of the time-domain signal corresponding to $f=0$ Hz. So, the frequency vector corresponding to the discrete Fourier transform starts at zero and has $N$ elements, the analysis frequencies:\n", - "\n", - "<code>f_vec = np.arange(0, f_s, f_0)</code>\n", - "\n", - "With task 2 you visualize the entire output as you get it from the `np.fft.fft`, hence for frequencies $[0,f_s)$. From Chapter 4 you know that the spectrum of a sampled signal repeats every integer multiple of $f_s$ (copies of the spectrum)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 2:</b> \n", - "\n", - "- Calculate the Fast Fourier Transform of the signal you generated in Task 1. Remember: the signal has 500 samples and thus does *not* end at exactly 5 second.\n", - "- Create the frequency vector $f$ with the analysis frequencies.\n", - "- Plot the modulus of the Fourier Transform against the frequency $f$ using a log scale on both axes. Use plot markers to see at which frequencies the Fourier transform was calculated.\n", - "\n", - "On top of that, answer to the following questions:\n", - "<ol>\n", - " <li>Describe the amplitude spectrum.</li>\n", - " <li>What is the magnitude of $X(f)$ at $f$ = 1 Hz?</li>\n", - " <li>Do you notice anything peculiar about the amplitude spectrum?</li>\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE\n", - "\n", - "# Write your own code or use the template below to create your figure(s)\n", - "\n", - "# f, axes = plt.subplots(1,1,figsize=(10,5))\n", - "\n", - "# axes[0].plot(YOUR_CODE_HERE, YOUR_CODE_HERE, 'x', color='b', label='Fourier transform')\n", - "# axes[0].loglog()\n", - "# axes[0].set_xlabel('$f \\: \\: [Hz]$')\n", - "# axes[0].set_ylabel('$|X(f)| \\: [V]$')\n", - "# axes[0].grid()\n", - "# axes[0].set_title('Log/Log')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "## SOLUTION\n", - "\n", - "T_meas = 5\n", - "f_s = 100\n", - "\n", - "t_vec = np.arange(0, T_meas, 1/f_s) # ends at 4.99, length 500 according to the sample-and-hold convention\n", - "\n", - "A = 1\n", - "f_c = 1\n", - "phi = 5 * np.pi / 180\n", - "x = A * np.sin(2 * np.pi * f_c * t_vec + phi)\n", - "\n", - "N = len(x)\n", - "X_cont = np.fft.fft(x) / N\n", - "\n", - "f_0 = f_s / N\n", - "f_vec = np.arange(0, f_s, f_0)\n", - "\n", - "f, axes = plt.subplots(1,2,figsize=(10,5))\n", - "\n", - "axes[0].plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transform')\n", - "axes[0].loglog()\n", - "axes[0].set_xlabel(r'$f \\: \\: [Hz]$')\n", - "axes[0].set_ylabel(r'$|X(f)| \\: [V]$')\n", - "axes[0].grid()\n", - "axes[0].set_title('Log/Log')\n", - "\n", - "axes[1].plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transform')\n", - "axes[1].set_xlabel(r'$f \\: \\: [Hz]$')\n", - "axes[1].set_ylabel(r'$|X(f)| \\: [V]$')\n", - "axes[1].grid()\n", - "axes[1].set_title('Linear')\n", - "plt.legend()\n", - "\n", - "print(f_vec[np.abs(X_cont)>0.1])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**In addition to the code output above, write your answer in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Solution:</b> \n", - "<ol>\n", - " <li>A peak of 0.5 should be found (from theory) at a frequency of 1 Hz and one around 100 Hz (exactly at 99 Hz), the rest all close to zero.</li>\n", - " <li>0.5 (as we divide the fft-result by N to get the equivalent of the continuous-time Fourier transform).</li>\n", - " <li>The peak at 100 Hz (or 99 Hz to be precise) should not be there. We did not input a signal with such a frequency.</li>\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Symmetry\n", - "\n", - "\n", - "Due to symmetry properties of the DFT, the following holds for a real signal $x(t)$:\n", - "\n", - "$$\n", - "|X_k| = |X_{-k}|\n", - "$$\n", - "\n", - "Which means that the modulus of the Fourier coefficients is symmetric about $f=0$. The NumPy <code>fft</code> command appends the Fourier coefficients for $k<0$ to the right side of the Fourier coefficients for $k \\ge 0$. This is called the *two-sided* spectrum.\n", - "\n", - "Since we are working with real signals, the symmetry property is valid, and we can just ignore the coefficients for $k<0$. This means that we consider the following range in the frequency domain:\n", - "\n", - "$[0, \\frac{f_s}{2}]$ for even values of $N$\n", - "\n", - "$[0, \\frac{f_s}{2})$ for odd values of $N$\n", - "\n", - "In other words, we are only considering frequencies up to half of $f_s$. This is easily implemented in Python using the floor division operator <code>//</code>:\n", - "\n", - "<code>X_cont = X_cont[:N//2]</code>\n", - "\\\n", - "<code>f_vec = f_vec[:N//2]</code>\n", - "\n", - "If you're unfamiliar with this, consider that <code>A//B</code> returns the number of times <code>B</code> 'fits into' <code>A</code>. In principle, this will always return an integer, so it can be easily used for indexing an array. In this specifc example, <code>N//2</code> will return $\\frac{N}{2}$ for even $N$ and $\\frac{N-1}{2}$ for odd N, which is exactly what we want. See the example below." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "N = 100\n", - "print(f'{N} floor divided by 2: {N//2}')\n", - "print(f'{N+1} floor divided by 2: {(N+1)//2}')\n", - "print(f'{N-1} floor divided by 2: {(N-1)//2}')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "\n", - "<p>\n", - "<b>Task 3:</b> \n", - "\n", - "- Repeat Task 2 with different measurement times $T_{meas}$ for the signal. Use measurement times such that the $f_c$ = 1 Hz oscillation fits *exactly* 1 time, 5 times and 20 times.\n", - "- Plot the amplitude spectrum for all three measurement times, **only for positive frequencies**, in separate graphs (log-log scale) with the same domains and answer to the following questions:\n", - "\n", - "- What is the effect of changing $T_{meas}$ on the frequency range in the amplitude spectrum? Does the highest analysis frequency change?\n", - "- Does the frequency resolution change?\n", - "- Does the magnitude of at the peaks change?\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE\n", - "\n", - "# Write your own code or use the template below to create your figure(s)\n", - "\n", - "plt.figure(figsize=(12,4))\n", - "for i, T_meas in enumerate(YOUR_CODE_HERE):\n", - " YOUR_CODE_HERE\n", - "\n", - " plt.subplot(1, 3, i+1)\n", - " \n", - " YOUR_CODE_HERE\n", - " \n", - " plt.grid()\n", - " plt.tight_layout()\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "### SOLUTION\n", - "T_lst = [1, 5, 20]\n", - "f_s = 100\n", - "\n", - "plt.figure(figsize=(12,4))\n", - "for i, T_meas in enumerate(T_lst):\n", - " t_vec = np.arange(0, T_meas, 1/f_s)\n", - " A = 1\n", - " f_c = 1\n", - " phi = 5 * np.pi / 180\n", - " x = A * np.sin(2 * np.pi * f_c * t_vec + phi)\n", - " \n", - " N = len(x)\n", - " X_cont = np.fft.fft(x) / N\n", - " \n", - " f_0 = f_s / N\n", - " f_vec = np.arange(0, f_s, f_0)\n", - " \n", - " X_cont = X_cont[:N//2]\n", - " f_vec = f_vec[:N//2]\n", - "\n", - " plt.subplot(1, 3, i+1)\n", - " plt.plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transform')\n", - " plt.loglog()\n", - " plt.xlim(0.04, 100)\n", - " plt.ylim(10**(-19), 10)\n", - " plt.xlabel(r'$f \\: \\: [Hz]$')\n", - " plt.ylabel(r'$|X(f)| \\: [V]$')\n", - " plt.grid()\n", - " plt.tight_layout()\n", - "plt.legend();" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**In addition to the code output above, write your answer in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Solution:</b> \n", - "<ol>\n", - " <li>No, the highest analysis frequency stays the same (as it is related to the sampling frequency, which we did not change).</li>\n", - " <li>Yes, the frequency resolution becomes better/finer (gets smaller).</li>\n", - " <li>No, because we already divide by (we already account for the measurement duration).</li>\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Aliasing (chapter 4)\n", - "\n", - "So far we have been analyzing a signal with a fairly low frequency, just $1$ or $2$ Hz. Now suppose, due to some unexpected source, our signal contains a second sinusoid with a much higher frequency. This is often caused by the line frequency ($50$ Hz) due to power plant generators providing the $220$ V current in regular buildings, or by electrical interference. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "\n", - "<p>\n", - "<b>Task 4: with this task we'll make you run into an aliasing problem . . .</b> \n", - "\n", - "- Create a time-array starting $t=0$, with a sampling rate of 100 Hz, and ending such that a sinusoid with a frequency of 1 Hz fits exactly 5 times in the measurement time.\n", - "\n", - "- Re-create the signal $x(t) = A \\sin(2 \\pi f_c t + \\varphi)$ from the first Task, with amplitude $A=1.0$ V, carrier frequency $f_c=1.0$ Hz, and initial phase $\\varphi = 5$ degrees, to be converted into radians.\n", - "\n", - "- Add to this signal a second sinusoid with a frequency of $80$ Hz and amplitude of $0.1$ V (and zero initial phase).\n", - "\n", - "- Create a plot of the signal against time, and of the amplitude spectrum as in the previous Tasks. \n", - "\n", - "Then answer to the following questions:\n", - "<ol>\n", - " <li>What do you see in the frequency plot? Are there peaks? How many? Where?</li>\n", - " <li>Does this match what you see in the time plot?</li>\n", - " <li>Does changing the measurement time (duration) help?</li>\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE\n", - "\n", - "# Write your own code or use the template below to create your figure(s)\n", - "\n", - "# plt.figure(figsize=(12,6))\n", - "# plt.subplot(211)\n", - "# YOUR_CODE_HERE\n", - "# plt.grid()\n", - "# plt.title('Time signal')\n", - "# plt.legend()\n", - "\n", - "# plt.subplot(212)\n", - "# YOUR_CODE_HERE\n", - "# plt.loglog()\n", - "# YOUR_CODE_HERE\n", - "# plt.grid()\n", - "# plt.tight_layout()\n", - "# plt.title('Amplitude spectrum')\n", - "# plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "### SOLUTION\n", - "T_meas = 5\n", - "f_s = 100\n", - "\n", - "t_vec = np.arange(0, T_meas, 1/f_s) # ends at 4.99, length 500\n", - "\n", - "A = 1\n", - "f_c = 1\n", - "phi = 5 * np.pi / 180\n", - "x = A * np.sin(2 * np.pi * f_c * t_vec + phi)\n", - "\n", - "A_i = 0.1\n", - "f_i = 80\n", - "x += A_i * np.sin(2 * np.pi * f_i * t_vec)\n", - "\n", - "N = len(x)\n", - "X_cont = np.fft.fft(x) / N\n", - "\n", - "f_0 = f_s / N\n", - "f_vec = np.arange(0, f_s, f_0)\n", - "\n", - "X_cont = X_cont[:N//2]\n", - "f_vec = f_vec[:N//2]\n", - "\n", - "plt.figure(figsize=(12,6))\n", - "plt.subplot(211)\n", - "plt.plot(t_vec, x, color='b', label='signal')\n", - "plt.xlabel(r\"$t \\: [s]$\")\n", - "plt.ylabel(r\"$x(t) \\: [V]$\")\n", - "plt.grid()\n", - "plt.title('Time signal')\n", - "plt.legend()\n", - "\n", - "plt.subplot(212)\n", - "plt.plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transform')\n", - "plt.loglog()\n", - "plt.xlim(0.04, 100)\n", - "plt.ylim(10**(-19), 10)\n", - "plt.xlabel(r\"$f \\: \\: [Hz]$\")\n", - "plt.ylabel(r\"$|X(f)| \\: [V]$\")\n", - "plt.grid()\n", - "plt.tight_layout()\n", - "plt.title('Amplitude spectrum')\n", - "plt.legend();" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**In addition to the code output above, write your answer in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Solution:</b> \n", - "<ol>\n", - " <li>There are two peaks, one of $0.5$ at $1$ Hz and one of $0.05$ at $20$ Hz, which should be at $80$ Hz (again exact values are hard to read but should be derived from theory).</li>\n", - " <li>Yes, there is a large amplitude sinusoid with a frequency of $1$ Hz, and a small amplitude sinusoid with a frequency of $20$ Hz on top if it (count the number of wiggles - there are $20$ wavies within 1 second). However, it does not match the input signal we created (with $1$ Hz and $80$ Hz).</li>\n", - " <li>No, the frequency resolution would change, but not the largest frequency of the amplitude spectrum, as that one is determined by the sampling frequency $f_s$.</li>\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The effect seen in Task 4 is called *aliasing*, and the cause is that if your sample rate is too low for the signals you're measuring, you will not capture their oscillation period sufficiently - with at least two samples per cycle. Instead, the signal will appear at a much lower frequency, as you can see in the figure below. Here $f_c = 5$ Hz, and the signal was sampled with $f_c = 7$ Hz, and based on the discrete time samples we incorrectly conclude that there is a frequency component at $2$ Hz (at the end of Chapter 4).\n", - "\n", - "<img src=\"https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/NewSlide38.png\" style=\"margin:auto\" width=800/>\n", - "<img src=\"https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/NewSlide51.png\" style=\"margin:auto\" width=800/>\n", - "\n", - "So, how fast do we need to sample to capture an $80$ Hz signal?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 5:</b> \n", - "\n", - "Repeat Task 4 with different sample rates: $110, 150, 160,$ and $200$ Hz. Plot the signal and amplitude spectrum for each one (you might want to use a loop). \n", - "\n", - "Then answer the following questions:\n", - "<ol>\n", - " <li>At what frequency does the (aliased) 80 Hz signal appear in the spectrum, for the above values of $f_s$ (provide numerical answers)?</li>\n", - " <li>Can you figure out the relationship (a simple equation) between the sample rate and the frequency of the original signal, and the frequency at which the alias appears?</li>\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE\n", - "\n", - "# Write your own code or use the template below to create your figure(s)\n", - "\n", - "# for YOUR_CODE_HERE:\n", - " \n", - "# YOUR_CODE_HERE\n", - " \n", - "# plt.figure(figsize=(12,6))\n", - "# plt.suptitle(f'$f_s = {YOUR_CODE_HERE}$ Hz')\n", - "# plt.subplot(211)\n", - "# YOUR_CODE_HERE\n", - "# plt.grid()\n", - "# plt.legend()\n", - " \n", - "# plt.subplot(212)\n", - "# YOUR_CODE_HERE\n", - "# plt.loglog()\n", - "# plt.grid()\n", - "# plt.tight_layout()\n", - "# plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "### SOLUTION\n", - "\n", - "f_s_lst = [110, 150, 160, 200]\n", - "\n", - "for f_s in f_s_lst:\n", - " T_meas = 5\n", - " # f_s = 100\n", - " \n", - " t_vec = np.arange(0, T_meas, 1/f_s)\n", - " \n", - " A = 1\n", - " f_c = 1\n", - " phi = 5 * np.pi / 180\n", - " x = A * np.sin(2 * np.pi * f_c * t_vec + phi)\n", - " \n", - " A_i = 0.1\n", - " f_i = 80\n", - " x += A_i * np.sin(2 * np.pi * f_i * t_vec)\n", - " \n", - " N = len(x)\n", - " X_cont = np.fft.fft(x) / N\n", - " \n", - " f_0 = f_s / N\n", - " f_vec = np.arange(0, f_s, f_0)\n", - " \n", - " X_cont = X_cont[:N//2]\n", - " f_vec = f_vec[:N//2]\n", - " \n", - " plt.figure(figsize=(12,6))\n", - " plt.suptitle(f'$f_s = {f_s}$ Hz')\n", - " plt.subplot(211)\n", - " plt.plot(t_vec, x, color='b', label='signal')\n", - " plt.xlabel(r'$t \\: [s]$')\n", - " plt.ylabel(r'$x(t) \\: [V] $')\n", - " plt.grid()\n", - " plt.legend()\n", - " plt.subplot(212)\n", - " plt.plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transform')\n", - " plt.loglog()\n", - " plt.xlim(0.04, 100)\n", - " plt.ylim(10**(- 19), 10)\n", - " plt.xlabel(r'$f \\: \\: [Hz]$')\n", - " plt.ylabel(r'$|X(f)| \\: [V]$')\n", - " plt.grid()\n", - " plt.tight_layout()\n", - " plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**In addition to the code output above, write your answer in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Solution:</b> \n", - "<ul>\n", - " <li> Different frequencies:\n", - " <ul>\n", - " <li>$f_s=110$ Hz: peak at $30$ Hz.\n", - " <li>$f_s=150$ Hz: peak at $70$ Hz.\n", - " <li>$f_s=160$ Hz: no peak (the $80$ Hz signal is sampled exactly twice per cycle, exactly at the 'zero-passes'; we now don't see it at all).\n", - " <li>$f_s=200$ Hz: peak at $80$ Hz.\n", - " </ul>\n", - "</li>\n", - " <li>The sample rate needs to be more than twice the (highest) frequency of the signal, which is the *Nyquist* rate. As long as we do not meet this requirement the alias appears mirrored about the Nyquist frequency (which is half the sampling frequency), e.g. with $f_s=110$ Hz, the alias of $f_i=80$ Hz appears at $110-80=30$ Hz.</li>\n", - "</ol> \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As you probably figured out, the sample rate needs to be faster than twice the largest frequency in the signal. In other words, you can measure signals with a frequency up to half the sample rate without aliasing becoming a problem. The frequency above which aliasing occurs (half the sampling rate) is called the *Nyquist frequency* (Chapter 4)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Damped vibrations\n", - "\n", - "We now know how to create an amplitude/magnitude spectrum. We've seen that we get aliasing if our signal has components at frequencies higher than the *Nyquist frequency* (and leakage if the measurement time is too short). Now, let's consider the damped vibration aceleration signal that an accelerometer would measure (see *Appendix A*). In this case the damping ratio is not equal to zero, unlike in Tasks 1 to 5." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 6:</b> \n", - "\n", - "- Create a time-array starting at $t=0$ s, ending at $t = 50$ s, with a sampling rate of $100$ Hz.\n", - "- Create a damped harmonic acceleration signal $x(t) = \\frac{x(0)}{\\sqrt{1-\\zeta^2}} e^{-\\zeta \\omega_0 t} \\sin(\\omega_d t)$ with $\\zeta = 0.05$, $\\omega_0 = 10 \\pi$ rad/s (corresponding to $5$ Hz), $\\omega_d = \\omega_0 \\sqrt{1-\\zeta^2} = 9.987 \\pi$ rad/s, and initial displacement $x(0)=1$ (for convenience the initial phase of the signal is kept to zero).\n", - "- Create a plot of the signal against time, and of the amplitude spectrum as in the previous Tasks.\n", - "\n", - "Then answer the following questions:\n", - "<ol>\n", - " <li>Do you see any changes in the time plot, compared to the earlier plot? Describe them!</li>\n", - " <li>What is the dominant frequency of the signal now?</li>\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE\n", - "\n", - "# # Write your own code or use the template below to create your figure(s)\n", - "\n", - "# plt.figure(figsize=(12,6))\n", - "# plt.subplot(211)\n", - "# YOUR_CODE_HERE\n", - "# plt.grid()\n", - "# plt.legend()\n", - "\n", - "# plt.subplot(212)\n", - "# YOUR_CODE_HERE\n", - "# plt.loglog()\n", - "# YOUR_CODE_HERE\n", - "# plt.grid()\n", - "# plt.tight_layout()\n", - "# plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "### SOLUTION\n", - "T_meas = 50\n", - "f_s = 100\n", - "\n", - "t_vec = np.arange(0, T_meas, 1/f_s)\n", - "\n", - "x_0 = 1\n", - "zeta = 0.05\n", - "omega_0 = 10 * np.pi\n", - "omega_d = omega_0 * np.sqrt(1 - zeta**2)\n", - "x = x_0 / (np.sqrt(1 - zeta**2)) * np.exp(-zeta * omega_0 * t_vec) * np.sin(omega_d * t_vec)\n", - "\n", - "N = len(x)\n", - "X_cont = np.fft.fft(x) / N\n", - "\n", - "f_0 = f_s / N\n", - "f_vec = np.arange(0, f_s, f_0)\n", - "\n", - "X_cont = X_cont[:N//2]\n", - "f_vec = f_vec[:N//2]\n", - "\n", - "plt.figure(figsize=(12,6))\n", - "plt.subplot(211)\n", - "plt.plot(t_vec, x, color='b', label='signal')\n", - "plt.xlabel(r\"$t \\: [s]$\")\n", - "plt.ylabel(r\"$x(t) \\: [V] $\")\n", - "plt.title('Time signal')\n", - "plt.grid()\n", - "plt.legend()\n", - "\n", - "plt.subplot(212)\n", - "plt.plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transfrom')\n", - "plt.loglog()\n", - "plt.xlim(0.04, 100)\n", - "plt.ylim(10**(-7), 10)\n", - "plt.xlabel(r\"$f \\: \\: [Hz]$\")\n", - "plt.ylabel(r\"$|X(f)| \\: [V]$\")\n", - "plt.title('Amplitude spectrum')\n", - "plt.grid()\n", - "plt.tight_layout()\n", - "plt.legend()\n", - "\n", - "print(f_vec[np.argmax(np.abs(X_cont))])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**In addition to the code output above, write your answer in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Solution:</b> \n", - "<ol>\n", - " <li>The signal is now clearly a sinusoid with an exponentially decaying amplitude, a.k.a. a damped vibration!</li>\n", - " <li>Around $5$ Hz (max value of $|X_{cont}|$ at $4.98$ Hz).</li>\n", - "</ol>\n", - "Instead of a 'crisp' spectrum, with a very clear, distinct and ultimately narrow peak, you now get a kind of smoothed or faded peak. This is simply the result of dealing with a damped harmonic, rather than a perfect harmonic. The signal somehow still looks pretty periodic, but strictly spoken, the signal is not periodic anymore, as the amplitude slightly changes (decreases) with time.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Cantilever-beam acceleration measurements\n", - "\n", - "Now you're ready to start analyzing the cantilever-beam acceleration measurements.\n", - "\n", - "Read in the data-file: *cantileverbeam_acc50Hz.csv*.\n", - "\n", - "This dataset contains 5 minutes of measurements with a sampling rate of $50$ Hz (a total of $N=15001$ samples). The first column in the file contains the UTC time of day (in seconds), the second column contains the measured acceleration (in m/s<sup>2</sup>)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Detrending\n", - "\n", - "In this project the signal of interest is the damped, harmonic motion of the cantilever-beam. In addition the measurements may contain (unwanted) effects of the sensor (think of an offset, due to imperfect manufacturing and/or prior calibration, or a drift over time, for instance due to temperature changes in the electronics during the experiment). By detrending we mean to remove such effects, prior to our spectral analysis, so that we can start with a nice, zero mean signal. A-priori detrending is good practice and generally yields a cleaner spectrum. Next week (week 2.4 on Time Series Analysis) we cover the subject of removing unwanted effects from the signal in more detail, as to obtain a so-called **stationary** signal, meaning that the properties or characteristics of the signal (such as the mean) do not change over time, and, we provide practical means to “stationarize†a given or measured signal.\n", - "\n", - "There are built-in functions in Python to remove such an offset and/or trend (and you're free to use them). But, earlier in the MUDE, in week 1.3, you learned about least-squares parameter estimation, and that's what you can apply to do the detrending (and actually built-in functions just apply the very same principle). Next week, on Time Series Analysis, you will actually be covering (again) the estimation of a trend in a time series of measurements.\n", - "As a re-cap for week 1.3: when a series of observations $y_1, …, y_m$ (in our case with $m=N$) is supposed or expected to exhibit a functional linear trend (a straight line in terms of a graph), this can be modelled as\n", - "\n", - "$$\n", - "\\mathbb{E} = \\begin{pmatrix} \\begin{bmatrix} Y_{1} \\\\ Y_{2} \\\\ \\vdots \\\\ Y_{m} \\end{bmatrix} \\end{pmatrix} \n", - " = \n", - " \\begin{bmatrix} 1 & t_1 - t_1 \\\\ 1 & t_2 - t_1 \\\\ \\vdots & \\vdots \\\\ 1 & t_m - t_1 \\end{bmatrix} \n", - " \\begin{pmatrix} x_{1} \\\\ x_{2} \\end{pmatrix}\n", - "$$\n", - "\n", - "with $x_1$ the offset at time $t_1$ (rather than $t=0$), and $x_2$ the slope of the line. The two unknown parameters in this vector $x$ can be estimated through (unweighted) least-squares, $\\hat{x}=(A^T A)^{-1} A^T y$, and next the residuals are obtained as $\\hat{\\epsilon}=y-\\hat{y}=y-A\\hat{x}$. The residuals are the 'left-over part' of the observations, once the (estimated) trend has been taken out; these residuals are of interest for further spectral analysis!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 7:</b> \n", - "\n", - "- For the cantilever-beam acceleration measurements, perform a least-squares estimation according to the above model, and report the estimated offset and slope of the trend.\n", - "- The detrended acceleration measurements, hence the elements of vector $\\hat{\\epsilon}$ are the input to your spectral analysis, so from here on, we denote them by $x(t)$ (in continuous time), and by $x_n$ (in discrete time) with $n=0,…,N-1$.\n", - "- Make a plot of the input signal as a function of time, hence of the detrended accelerations.\n", - "\n", - "Report the estimated offset and slope of the trend (i.e. numerical values).\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df = pd.read_csv('cantileverbeam_acc50Hz.csv', header=0)\n", - "\n", - "t = np.array(df['time']) #\n", - "dat = np.array(df['acceleration']) #\n", - "\n", - "N = len(t)\n", - "\n", - "plt.figure()\n", - "plt.plot(t, dat, color='b', label='acceleration signal')\n", - "plt.xlabel('time [s]')\n", - "plt.ylabel('acceleration [m/s2]')\n", - "plt.title('Vertical cantilever beam acceleration')\n", - "plt.legend()\n", - "\n", - "# observation record length (as N*dt, according to sample-and-hold convention)\n", - "T = (t[N-1] - t[0])*N/(N - 1)\n", - "dt = T/N\n", - "\n", - "YOUR_CODE_HERE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# LOAD DATA\n", - "\n", - "df = pd.read_csv('cantileverbeam_acc50Hz.csv', header=0)\n", - "\n", - "t = np.array(df['time']) #\n", - "dat = np.array(df['acceleration']) #\n", - "\n", - "N = len(t)\n", - "\n", - "# observation record length (as N * dt, according to sample-and-hold convention)\n", - "T = (t[N-1] - t[0]) * N / (N - 1)\n", - "dt = T / N\n", - "plt.figure()\n", - "plt.plot(t, dat, color='b', label='acceleration signal')\n", - "plt.xlabel('time [s]')\n", - "plt.ylabel('acceleration [m/s2]')\n", - "plt.title('Vertical cantilever beam acceleration')\n", - "plt.legend()\n", - "\n", - "### SOLUTION\n", - "\n", - "#detrend data\n", - "A = np.column_stack((np.ones(N), t - t[0]))\n", - "\n", - "#xhat = np.linalg.lstsq(A, dat, rcond=None)[0]\n", - "xhat = np.linalg.inv((A.T)@A)@A.T@dat\n", - "yhat = A@xhat\n", - "ehat = dat - yhat\n", - "\n", - "plt.figure()\n", - "plt.plot(t, ehat, color='b', label='detrended signal')\n", - "plt.xlabel('time [s]')\n", - "plt.ylabel('detrended accelerations [m/s2]')\n", - "plt.title('Detrended vertical cantilever beam acceleration')\n", - "plt.legend();" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**In addition to the code output above, write your answer in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Solution:</b> \n", - "\n", - "The mean is $-0.43$ m/s<sup>2</sup>, so that's considerable, and the slope is $-1.3e^{-4}$ m/s<sup>2</sup>, which is pretty much negligible over the duration of this experiment; mean/offset when one forgets to subtract $t[0]$ from the time column in the A-matrix, hence reporting the offset for 00:00h UTC, this is $8.08$ m/s<sup>2</sup>.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 8:</b> \n", - "\n", - "Previously, in Task 3, you computed and plotted the magnitude spectrum $|X_k|$ of a signal for positive frequencies $f>0$ (putting a lot of attention to correctly labelling the horizontal frequency axis of the plot!), and now, with the material of Chapter 6 on spectral estimation, you will estimate the power spectral density $S$ of the signal through the periodogram, which is just: $S(k\\Delta f)=\\frac{|X_k|^2}{T}$ (in [W/Hz] when $x_n$ is a voltage signal; and $|X_k|$ being the result straight from the <code>np.fft</code>, multiplied by sampling interval $\\Delta t$), for frequency $k\\Delta f$, with frequency resolution $\\Delta f=\\frac{1}{T}$, and $k=0,…,N-1$ (hence, pretty much the same procedure as with the magnitude spectrum, though just taking the square of the modulus, and dividing by $T$).\n", - "\n", - "Compute and plot the periodogram for the detrended accelerometer measurements of Task 7 (if you prefer, feel free to use a linear scaling of the axes here, rather a log-log, and, use $T$ as defined already in the code of Task 7). Please, pay attention to correctly labelling the axes, and stating dimensions of the quantities along the axes!\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "### SOLUTION\n", - "\n", - "#estimate and plot power spectral density (PSD)\n", - "# in this solution code we use np.fft (rather than scipy.fft), and we actually compute and plot a (symmetric) \n", - "#two-sided PSD-estimate (using also the fftshift), as we like to (optionally) compare it with the Python \n", - "#built-in periodogram\n", - "\n", - "Fs = 1 / dt\n", - "f0 = 1 / T\n", - "print(Fs)\n", - "print(f0)\n", - "\n", - "f = np.concatenate((np.arange(-Fs / 2 + f0 / 2, 0, f0), np.arange(0, Fs / 2, f0)))\n", - "print(f)\n", - "\n", - "Z = np.fft.fft(ehat) * dt\n", - "psd = (np.abs(Z))**2/T \n", - "plt.figure()\n", - "plt.plot(f,np.fft.fftshift(psd), color='b', label='psd')\n", - "print(Z)\n", - "plt.xlabel('frequency [Hz]')\n", - "plt.ylabel('PSD [m2/s4/Hz]')\n", - "plt.title('Power Spectral Density (PSD)')\n", - "plt.legend();" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 9:</b> \n", - "\n", - "Answer the following questions:\n", - "<ol>\n", - " <li>Report the damped natural frequency (in Hertz) of this one-degree-of-freedom (1DOF) mechanical system. Does it match the motion of the beam shown in the cantilever-beam video?</li>\n", - " <li>The acceleration was measured at quite a high sample rate of $50$ Hz. What is the minimum sampling frequency to correctly identify the damped natural frequency in the periodogram?</li>\n", - "</ol>\n", - "<p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Write your answer(s) in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Solution:</b> \n", - "<ol>\n", - " <li>Around $1.36$ Hz, and yes, this matches the motion in the video.</li>\n", - " <li>Nyquist rate is twice the (highest) frequency in the signal, hence $2 \\times 1.36 = 2.72$ Hz, so, any value larger than $2.72$ Hz.</li>\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Task 10: Global Mean Sea-Level (GMSL) data (optional)\n", - "\n", - "Repeat the steps with Tasks 7-9, but now with the Global Mean Sea Level data set. Data is from the Australia's National Science Agency (CSIRO): [GMSL data](https://www.cmar.csiro.au/sealevel/sl_hist_last_decades.html). \n", - "\n", - "These data result from nearly 3 decades of satellite altimetry (with satellite missions such as TOPEX/Poseidon and the Jason-series). The first column contains the time tag or epoch (in decimal years), the second column is the global mean sea level (in mm). There is one measurement per month (monthly average, so that for instance tide-effects are averaged out, and the measurement typically refers to the middle of the month, hence 1993.042 is mid January in 1993). The single monthly measurement is the global mean sea level, so, the average of the entire world.\n", - "\n", - "The sampling frequency $f_s = 12$ per year ($\\Delta t = 1/12 \\sim 0.083$ year), and there are $N=331$ measurements in total." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "data = pd.read_csv('CSIRO_Alt_seas_inc.txt', names=['month', 'sl'])\n", - "data.head()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# create time-array, time relative to t0 [yr] (epoch-time of the first observation;\n", - "# t0=1993.042 refers to mid January 1993)\n", - "t = data.iloc[:, 0] - data.iloc[0, 0]\n", - "\n", - "# number of observations\n", - "N = len(t)\n", - "\n", - "# observation record length (as N * dt, according to sample-and-hold convention)\n", - "T = (t[N - 1] - t[0]) * N / (N - 1)\n", - "\n", - "# Delta t [yr]; dt = T/N = (N*dt)/N\n", - "dt = T / N\n", - "\n", - "# observed sea-level height\n", - "y = data.iloc[:,1]\n", - "\n", - "# plot observed time-series, as it is, versus epoch-time in [year]\n", - "plt.plot(data.iloc[:,0],y, color='b', label='sea level')\n", - "plt.xlabel('time [yr]')\n", - "plt.ylabel('sea-level height [mm]')\n", - "plt.title('Global Mean Sea-Level (GMSL) rise')\n", - "plt.legend();" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>Task 10 (Optional!):</b> \n", - "\n", - "Detrend the data. \n", - "\n", - "Estimate and plot power spectral density (PSD), hence the periodogram, for the (detrended) global mean sea-level data. \n", - "\n", - "Identify the largest peak in the spectrum, what is the frequency, and can you come up with a physical explanation of this behaviour?\n", - "</ol>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "### SOLUTION\n", - "\n", - "# prepare for detrending the data, we'll estimate an offset and a slope (two unknown parameters)\n", - "A = np.ones((N, 2))\n", - "A[:,1] = t\n", - "\n", - "# (unweighted) least-squares estimation of two parameters\n", - "xhat = (np.linalg.inv(A.T @ A) @ A.T) @ y\n", - "\n", - "# estimated observations (fitted by a straight line with offset and slope)\n", - "yhat = A @ xhat\n", - "\n", - "# difference of observed value and estimated observation (least-squares residuals)\n", - "ehat = y - yhat\n", - "\n", - "# hence observed time-series but detrended, this will act as our signal x(t), or x_0,...,x_{N-1}\n", - "plt.plot(data.iloc[:,0], ehat, color='b', label='detrended signal')\n", - "plt.xlabel('time [yr]')\n", - "plt.ylabel('detrended sea-level height [mm]')\n", - "plt.title('Detrened Global Mean Sea-Level')\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "### SOLUTION\n", - "\n", - "# sampling frequency [Hz]\n", - "Fs = 1 / dt\n", - "\n", - "# observed signal to length NFFT ( record length is NFFT*dt)\n", - "NFFT = N\n", - "\n", - "# Discrete Fourier Transform (DFT) by fft, to NFFT samples\n", - "# and multiply by Delta t (as to maintain analogy with continuous-time Fourier transform)\n", - "X = dt * np.fft.fft(ehat, NFFT)\n", - "\n", - "# frequency resolution\n", - "f0 = 1 / (NFFT * dt)\n", - "\n", - "# frequency array (centered at f=0, and conform fftshift) for NFFT even, covers interval [-Fs/2,Fs/2)\n", - "#f = np.concatenate((np.arange(- Fs / 2, 0, f0), np.arange(0, Fs / 2 , f0))); #+ f0/4\n", - "f = np.concatenate((np.arange(-Fs / 2 + f0 / 2, 0, f0), np.arange(0, Fs / 2 , f0))) #- f0 / 4 \n", - "\n", - "\n", - "# for NFFT odd, use instead: f=np.concatenate((np.arange(-Fs/2 + f0/2, 0, f0), np.arange(0, Fs/2, f0))); covers interval (-Fs/2,Fs/2)\n", - "#|Xk|^2 / T periodogram (centered, with f=0 in the center), division by T, which is actual data record length\n", - "plt.plot(f, np.fft.fftshift((abs(X))**2 / T), color='b', label='psd')\n", - "plt.xlabel(r'frequency [$yr^{-1}$]')\n", - "plt.ylabel(r'PSD [$mm^2$ yr]')\n", - "plt.title('Power Spectral Density of GMSL data')\n", - "plt.legend();" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Write your answer(s) in this Markdown cell.** " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Solution:</b> \n", - "\n", - "The largest peak is $f = 0.996$/ year, hence the annual cycle, related to summer and winter, there is also a peak at $f = 1.992$/year, hence the double frequency (related to a half year cycle), and this one typically shows up if the once per year periodic cycle is not a perfect harmonic (sine or cosine), but instead a bit distorted/skewed, finally, there is also a large peak at $f = \\frac{1}{T} = 0.0362$/year, a long term effect, which implies a cycle with the duration of the entire data set, which here seems just coincidence, that a full cycle occurs in $T=27.58$ years.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;\">\n", - "<p>\n", - "<b>End of task.</b>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#C8FFFF; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Appendix A: Cantilever-beam dynamics:</b> \n", - "\n", - "The dynamics of the smartphone suspended on a cantilever beam can be considered as the mass-spring-damper system shown below:\n", - "\n", - "<img src=\"https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/mass_spring_damper.png\" style=\"margin:auto\" width=200/>\n", - "\n", - "The equation of motion of the deflection $x$ of this mass-spring-damper system (a damped harmonic oscillator) can be described by the following second order differential equation:\n", - "\n", - "$$\n", - "\\ddot{x}(t) + \\frac{c}{m} \\dot{x}(t) + \\frac{k}{m} x(t) =0\n", - "$$\n", - "\n", - "Where $\\ddot{x}(t)$, $\\dot{x}(t)$ and $x(t)$ are the acceleration, velocity and displacement as a function of time of the oscillating mass $m$ [kg] respectively. (with a unit transfer function, $x(t)$ describes the motion of the proof mass inside the smartphone accelerometer). For simplicity, we consider here the homogeneous equation, corresponding to free motion. The other parameters are the damping coefficient $c$ [kg/s] and spring constant $k$ [N/m]. The damping ratio can be obtained from the system parameters: $\\zeta = \\frac{c}{2 \\sqrt{mk}}$, which is dimensionless. The undamped natural frequency is $\\omega_0 = \\sqrt{\\frac{k}{m}}$ [rad/s]. The differential equation becomes:\n", - "\n", - "$$\n", - "\\ddot{x}(t) + 2 \\zeta \\omega_0 \\dot{x}(t) + \\omega_0^2 x(t) =0\n", - "$$\n", - "\n", - "For the under-damped case ($0 \\le \\zeta \\le 1)$ of our smartphone and assuming an initial zero tip velocity $\\dot{x}(t=0)=0$ (release from stand-still), the solution for the position as a function of time is given by:\n", - "\n", - "$$\n", - "x(t)=e^{-\\zeta \\omega_0 t} \\frac{x(0)}{\\sqrt{1-\\zeta^2}}\\sin(\\omega_d t + \\varphi)\n", - "$$\n", - "\n", - "Where $x(0)$ is the initial position $x(t=0)$, $\\omega_d$ is the damped natural frequency $\\omega_d = \\omega_0 \\sqrt{1-\\zeta^2}$, and the phase shift $\\varphi = \\arctan \\left( \\frac{\\sqrt{1-\\zeta^2}}{\\zeta} \\right)$. The sinusoid term represents the harmonic motion, and the exponential term represents the damping of that motion over time. Next, the velocity of the smartphone's oscillation can be derived as:\n", - "\n", - "$\\dot{x}(t) = e^{-\\zeta \\omega_0 t} \\frac{x(0)}{\\sqrt{1-\\zeta^2}}\\sin(\\omega_d t)$.\n", - "\n", - "The acceleration of the smartphone (which is what is being measured) is found as:\n", - "\n", - "$\\ddot{x}(t) = e^{-\\zeta \\omega_0 t} \\frac{x(0)}{\\sqrt{1-\\zeta^2}} \\sin (\\omega_d t - \\phi)$.\n", - "\n", - "Note that $\\omega_0$ and $\\omega_d$ are the angular frequencies expressed in radians per second. $\\ddot{x}(t)$ is a damped harmonic signal where the rate of damping is determined by the damping ratio $\\zeta$.\n", - "\n", - "In order to get a pure harmonic signal (as used in Tasks 1 to 5), set the damping ratio $\\zeta=0$, and optionally set the phase-shift $\\phi$ to zero as well, then the tip acceleration is given by the following simple sinusoidal expression:\n", - "\n", - "$$\n", - "\\ddot{x}(t)=x(0) \\sin(\\omega_0 t).\n", - "$$\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" />\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" />\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2024 <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">MUDE</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">CC BY 4.0 License</a>." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "mude-base", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.4" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/synced_files/students/GA_2_3/Analysis_solution.md b/synced_files/students/GA_2_3/Analysis_solution.md deleted file mode 100644 index d6dfab2b5b3638509df5442cf67039712869e4b6..0000000000000000000000000000000000000000 --- a/synced_files/students/GA_2_3/Analysis_solution.md +++ /dev/null @@ -1,1087 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: mude-base - language: python - name: python3 ---- - -# GA 2.3: Beam Beats - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px"\> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px"\> -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): week 2.3. Due: Friday, November 29, 2024.* - - -## Analyzing cantilever-beam accelerations and global Mean Sea-Level measurements - -This project covers the week on Signal Processing (week 2.3). - -As a warming up you will create and analyze some elementary signals yourself, and next, you will carry out frequency domain analyses on two given data-sets, namely acceleration measurements of a Cantilever-Beam experiment, and (in optional Task 10) Global Mean Sea-Level measurements. - -Most of the Tasks in this notebook consist of both coding, producing a plot, and answering (open) questions. Typically, as you work your way through the Tasks, you can often re-use code, or part of it, from earlier Tasks and assignments. That will save you a lot of work!! - -<!-- #region id="0491cc69" --> -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>In many of the code blocks below, template code to create figures is provided. Note that there is a lot of code missing, and one line of <code>YOUR_CODE_HERE</code> does not imply that only one line of code is missing!</p></div> -<!-- #endregion --> - -<!-- #region --> -### Data Acquisition System - -A data acquisition (DAQ) system usually consists of four components: - -<img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/DAQ.png" style="margin:auto"/> - - -- A sensor transforms a physical signal into a small voltage. The transformation is often frequency dependent or nonlinear, and can show drift or bias. -- Signal conditioning electronics (often included in the sensor housing) filter unwanted frequencies, such as the 50 Hz line frequency caused by power plant generators, using low-pass or notch filters. In addition the sensor voltage may be amplified. -- An analog-to-digital (A/D) converter samples the analog voltage with a certain rate, such as 100 Hz. The A/D converter can measure analog voltages within a certain range, the measurement range. The measured voltage is quantized with a certain resolution, such as 14-bit, which means that the full measurement range is divided into $2^{14}=16,384$ discrete intervals. Together, the resolution and measurement range determine the precision. Usually the sample rate, the measurement range, and the sample resolution are configurable. Sampling and quantizing together turns an analog signal into a digital signal. -- A digital computer reads the sampled data from the A/D converter at specific times, and allows for further processing, analysis and storage of the (digital) signal. - -The result is that an analog, physical signal, is turned into a series of numbers (samples of the signal, in the time domain), ready for processing and analysis in a digital computer. - - - -One of the data sets that you will analyze during this MUDE Q2 project was acquired by an accelerometer in a smartphone, on top of a vertical cantilever-beam. The accelerometer measures the side-ward accelerations, expressed in m/s<sup>2</sup>, and sampled at 50 Hz. Detailed information about the experiment and the sensor can be found in "Experimental evaluation of smartphone accelerometer and low-cost dual frequency GNSS sensors for deformation monitoring", by Alexandru Lapadat, Christian Tiberius and Peter Teunissen, Sensors 2021, 21, 7946, https://doi.org/10.3390/s21237946. - -A quick impression of the test setup can be gained by watching the short video [Cantilever Beam Experiment](https://youtu.be/o4moRwvlBLU?si=aKelBMWm3HB2Of26) (1 minute). - -A theoretical description of the motion of the smartphone accelerometer fixed to the cantilever beam is presented in Appendix A. Pulling the beam at the tip and releasing it, results in a (nearly) horizontal side-ward motion of the smartphone, and the (horizontal) position can be described by a *damped harmonic* as a function of time. Consequently, also the first and second derivative with respect to time, the velocity and acceleration as a function of time as the smartphone will measure it, are harmonics. - -### Basic sinusoid signal - -You will start with first creating (and analyzing) a few simple signals yourself. In the first few Tasks of this project, we will take the damping ratio zero and use a fairly short measurement time (duration), and hence the acceleration measured by the smartphone is a plain (undamped) sinusoid as shown in Appendix A (a stationary signal). In the following Tasks we also add a phase offset $\varphi$ to the plain sinusoid: - -$$ -x(t) = A \sin(2 \pi f_c t + \varphi) -$$ - -The result is taken from the last equation in Appendix A. We consider here acceleration, though for convenience, we omit the dots on top of the $x(t)$. -<!-- #endregion --> - -```python -import numpy as np -import pandas as pd -import matplotlib.pyplot as plt - -%matplotlib inline -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 1:</b> - -- Create a time-array starting at $t=0$ s, ending at $t=5.0$ s, with a sampling rate of 100 Hz. Hint: what is the number of samples $N$? And what should then be the last value in the time-array? Note that, for example, with $N=10$ samples at a sampling rate of $f_s = 100$ Hz, we have signal samples at times $t=0.00, 0.01, 0.02, ... , 0.08, 0.09$ seconds, hence $T_{meas}= N \Delta t =0.1$ seconds (the sample-and-hold convention). -- Create a sinusoidal signal $x(t) = A \sin(2 \pi f_c t + \varphi)$, with amplitude $A=1.0$ Volt, carrier frequency $f_c=1.0$ Hz, and initial phase $\varphi = 5$ degrees, to be converted into radians. -- Make a plot of the signal against time. Note that this is strictly a *sampled signal* $x_n$ rather than $x(t)$, but since we use a rather high sampling rate, the signal shown is close to continuous in time. Connecting the sample points of $x_n$ in the graph by lines, as done in the graph below, corroborates the suggestion of a continuous-time signal. Be aware! -</p> -</div> - -<!-- #region id="0491cc69" --> -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>We will give you the answers in this code cell for free!</p></div> -<!-- #endregion --> - -```python -T_meas = 5 -f_s = 100 #sampling rate [Hz] - -t_vec = np.arange(0, T_meas, 1 / f_s) # ends at 4.99, length 500 according to the sample-and-hold convention - -A = 1 -f_c = 1 -phi = 5 * np.pi / 180 -x = A * np.sin(2 * np.pi * f_c * t_vec + phi) - -plt.plot(t_vec, x, color='b', label='signal') -plt.xlabel(r'$t \: [s]$') -plt.ylabel(r'$x(t) \: [V]$') -plt.legend(loc='upper right') -plt.title(fr'Sinusoidal signal with $A$={A} V, $f_c$={f_c} Hz and initial phase $\phi$={phi:.3f} °') -plt.grid() -``` - -**In addition to the code output above, write your answer in this Markdown cell.** - - -<div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Solution:</b> - -The number of samples is $N=\frac{T_{meas}}{\Delta t}=T_{meas}\cdot f_s=5\cdot 100=500$. -The last value should be $4.99$ because we use a $\Delta t=\frac{1}{f_s}=0.01$ s. -</p> -</div> - - -### The Discrete Fourier Transform (chapter 5) - -To discover which frequencies are contained in the signal $x(t)$, we can transform it from the time domain to the frequency domain using the Fourier transform: - -$$ -X(f) = \int_{-\infty}^{\infty} x(t) e^{-j 2\pi f t} dt -$$ - -Which can then be expressed in terms of magnitude and phase: - -$$ -X(f) = |X(f)|e^{j\theta(f)} -$$ - -Where $|X(f)|$ plotted against frequency $f$ is called the *magnitude spectrum* (and practically often referred to as amplitude spectrum). - -The set and number of sinusoids required to approximate or re-create a given signal $x(t)$ depends on the shape of that signal. Of course, when the signal is a pure sinusoid, we only need one term. For an example, consider a 2 Hz sinusoidal signal and its magnitude spectrum below (the magnitude spectrum is expressed in [Vs], which equals [V/Hz], hence a magnitude or amplitude density). - -<img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/SignalSpectrumExample.png" style="margin:auto" width=800/> - - -You can see a sharp spike in the magnitude plot (which has two logarithmic axes, and we only plot the spectrum for positive frequencies $f>0$). A continuous time sinusoid with amplitude $A$ will produce a magnitude of $\frac{A T_{meas}}{2}$ in the amplitude spectrum (with $T_{meas}$ the *measurement time* or duration), rather than $\frac{A}{2}$ which you would expect (in a double-sided spectrum). This is because of the limited time duration of the input signal, which actually implies multiplication of $x(t)$ by a *rectangular time window* $w(t)=\Pi(\frac{t}{T_{meas}})$. Since the sinusoid has an amplitude of $A=1$ V, and was measured for $T_{meas}=5$ seconds, the magnitude becomes 2.5. The magnitude at all other frequencies is very small, approximately $10^{-15}$, or approximately zero. - -The Fourier transform is a continuous-time operation, mapping the continuous time-domain to the continuous frequency domain. Usually, we don't have continuous-time signals, but discrete time signals $x_n$ sampled at a certain sampling rate. The discrete Fourier Transform (DFT) is the discrete-time equivalent of the continuous time-Fourier transform: - -$$ -X_k = \sum_{n=0}^{N-1}x_ne^{-j2\pi kn/N}, k=0,1,...,N-1 -$$ - -Where $X_k$ is the sequence of frequency domain samples. NumPy contains a function to perform the DFT using a fast numerical algorithm, the Fast Fourier Transform: - -<code>X_discr = np.fft.fft(x)</code> - -For more information on the function see [here](https://numpy.org/doc/stable/reference/generated/numpy.fft.fft.html). - -The discrete-time signal $x_n$ and the frequency domain samples $X_k$ returned by Python are of equal length ($N$ samples in, $N$ samples out). When you compare the equations of the DFT with the continuous Fourier Transform, you will see that in the continuous equation we integrate over time $t$, while in the DFT *no information* about the time or sample rate is required (there is no $\Delta t$ in the above equation for $X_k$, as noted at the end of Chapter 5). This results in a *scale factor* in the spectrum when the DFT of signals with different sample rates are compared. To solve this, we have to multiply the DFT as calculated by NumPy by the sample time interval $\Delta t = 1/f_s$ to restore the time dimension and obtain a *discrete approximation of the continuous Fourier Transform*. To account for the measurement duration as described above, we have to divide by $T_{meas} = N \Delta t$. So, in total, multiply by $\Delta t$ and divide by $T_{meas}$, hence, we have to divide the NumPy result by the number of samples $N$: - -<code>X_cont = np.fft.fft(x) / N</code> - -The DFT only contains information (the complex value of $X_k$) at discrete frequencies, known as the *analysis frequencies*, which are integer multiples of the frequency resolution $f_0$. If we have a sampled signal $x_n$ consisting of $N$ samples, sampled at $f_s$ Hz with $f_s=1/ \Delta t$, the frequency resolution is: - -$$ -f_0 = \frac{1}{T_{meas}} = \frac{1}{N \Delta t} = \frac{f_s}{N} -$$ - -The first value of the complex vector $X_n$ returned by NumPy is the mean of the time-domain signal corresponding to $f=0$ Hz. So, the frequency vector corresponding to the discrete Fourier transform starts at zero and has $N$ elements, the analysis frequencies: - -<code>f_vec = np.arange(0, f_s, f_0)</code> - -With task 2 you visualize the entire output as you get it from the `np.fft.fft`, hence for frequencies $[0,f_s)$. From Chapter 4 you know that the spectrum of a sampled signal repeats every integer multiple of $f_s$ (copies of the spectrum). - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 2:</b> - -- Calculate the Fast Fourier Transform of the signal you generated in Task 1. Remember: the signal has 500 samples and thus does *not* end at exactly 5 second. -- Create the frequency vector $f$ with the analysis frequencies. -- Plot the modulus of the Fourier Transform against the frequency $f$ using a log scale on both axes. Use plot markers to see at which frequencies the Fourier transform was calculated. - -On top of that, answer to the following questions: -<ol> - <li>Describe the amplitude spectrum.</li> - <li>What is the magnitude of $X(f)$ at $f$ = 1 Hz?</li> - <li>Do you notice anything peculiar about the amplitude spectrum?</li> -</ol> -</p> -</div> - -```python -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -# f, axes = plt.subplots(1,1,figsize=(10,5)) - -# axes[0].plot(YOUR_CODE_HERE, YOUR_CODE_HERE, 'x', color='b', label='Fourier transform') -# axes[0].loglog() -# axes[0].set_xlabel('$f \: \: [Hz]$') -# axes[0].set_ylabel('$|X(f)| \: [V]$') -# axes[0].grid() -# axes[0].set_title('Log/Log') -``` - -```python -## SOLUTION - -T_meas = 5 -f_s = 100 - -t_vec = np.arange(0, T_meas, 1/f_s) # ends at 4.99, length 500 according to the sample-and-hold convention - -A = 1 -f_c = 1 -phi = 5 * np.pi / 180 -x = A * np.sin(2 * np.pi * f_c * t_vec + phi) - -N = len(x) -X_cont = np.fft.fft(x) / N - -f_0 = f_s / N -f_vec = np.arange(0, f_s, f_0) - -f, axes = plt.subplots(1,2,figsize=(10,5)) - -axes[0].plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transform') -axes[0].loglog() -axes[0].set_xlabel(r'$f \: \: [Hz]$') -axes[0].set_ylabel(r'$|X(f)| \: [V]$') -axes[0].grid() -axes[0].set_title('Log/Log') - -axes[1].plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transform') -axes[1].set_xlabel(r'$f \: \: [Hz]$') -axes[1].set_ylabel(r'$|X(f)| \: [V]$') -axes[1].grid() -axes[1].set_title('Linear') -plt.legend() - -print(f_vec[np.abs(X_cont)>0.1]) -``` - -**In addition to the code output above, write your answer in this Markdown cell.** - - -<div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Solution:</b> -<ol> - <li>A peak of 0.5 should be found (from theory) at a frequency of 1 Hz and one around 100 Hz (exactly at 99 Hz), the rest all close to zero.</li> - <li>0.5 (as we divide the fft-result by N to get the equivalent of the continuous-time Fourier transform).</li> - <li>The peak at 100 Hz (or 99 Hz to be precise) should not be there. We did not input a signal with such a frequency.</li> -</ol> -</p> -</div> - -<!-- #region --> -### Symmetry - - -Due to symmetry properties of the DFT, the following holds for a real signal $x(t)$: - -$$ -|X_k| = |X_{-k}| -$$ - -Which means that the modulus of the Fourier coefficients is symmetric about $f=0$. The NumPy <code>fft</code> command appends the Fourier coefficients for $k<0$ to the right side of the Fourier coefficients for $k \ge 0$. This is called the *two-sided* spectrum. - -Since we are working with real signals, the symmetry property is valid, and we can just ignore the coefficients for $k<0$. This means that we consider the following range in the frequency domain: - -$[0, \frac{f_s}{2}]$ for even values of $N$ - -$[0, \frac{f_s}{2})$ for odd values of $N$ - -In other words, we are only considering frequencies up to half of $f_s$. This is easily implemented in Python using the floor division operator <code>//</code>: - -<code>X_cont = X_cont[:N//2]</code> -\ -<code>f_vec = f_vec[:N//2]</code> - -If you're unfamiliar with this, consider that <code>A//B</code> returns the number of times <code>B</code> 'fits into' <code>A</code>. In principle, this will always return an integer, so it can be easily used for indexing an array. In this specifc example, <code>N//2</code> will return $\frac{N}{2}$ for even $N$ and $\frac{N-1}{2}$ for odd N, which is exactly what we want. See the example below. -<!-- #endregion --> - -```python -N = 100 -print(f'{N} floor divided by 2: {N//2}') -print(f'{N+1} floor divided by 2: {(N+1)//2}') -print(f'{N-1} floor divided by 2: {(N-1)//2}') -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> - -<p> -<b>Task 3:</b> - -- Repeat Task 2 with different measurement times $T_{meas}$ for the signal. Use measurement times such that the $f_c$ = 1 Hz oscillation fits *exactly* 1 time, 5 times and 20 times. -- Plot the amplitude spectrum for all three measurement times, **only for positive frequencies**, in separate graphs (log-log scale) with the same domains and answer to the following questions: - -- What is the effect of changing $T_{meas}$ on the frequency range in the amplitude spectrum? Does the highest analysis frequency change? -- Does the frequency resolution change? -- Does the magnitude of at the peaks change? - -</p> -</div> - -```python -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -plt.figure(figsize=(12,4)) -for i, T_meas in enumerate(YOUR_CODE_HERE): - YOUR_CODE_HERE - - plt.subplot(1, 3, i+1) - - YOUR_CODE_HERE - - plt.grid() - plt.tight_layout() -plt.legend() -``` - -```python -### SOLUTION -T_lst = [1, 5, 20] -f_s = 100 - -plt.figure(figsize=(12,4)) -for i, T_meas in enumerate(T_lst): - t_vec = np.arange(0, T_meas, 1/f_s) - A = 1 - f_c = 1 - phi = 5 * np.pi / 180 - x = A * np.sin(2 * np.pi * f_c * t_vec + phi) - - N = len(x) - X_cont = np.fft.fft(x) / N - - f_0 = f_s / N - f_vec = np.arange(0, f_s, f_0) - - X_cont = X_cont[:N//2] - f_vec = f_vec[:N//2] - - plt.subplot(1, 3, i+1) - plt.plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transform') - plt.loglog() - plt.xlim(0.04, 100) - plt.ylim(10**(-19), 10) - plt.xlabel(r'$f \: \: [Hz]$') - plt.ylabel(r'$|X(f)| \: [V]$') - plt.grid() - plt.tight_layout() -plt.legend(); -``` - -**In addition to the code output above, write your answer in this Markdown cell.** - - -<div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Solution:</b> -<ol> - <li>No, the highest analysis frequency stays the same (as it is related to the sampling frequency, which we did not change).</li> - <li>Yes, the frequency resolution becomes better/finer (gets smaller).</li> - <li>No, because we already divide by (we already account for the measurement duration).</li> -</ol> -</p> -</div> - - -### Aliasing (chapter 4) - -So far we have been analyzing a signal with a fairly low frequency, just $1$ or $2$ Hz. Now suppose, due to some unexpected source, our signal contains a second sinusoid with a much higher frequency. This is often caused by the line frequency ($50$ Hz) due to power plant generators providing the $220$ V current in regular buildings, or by electrical interference. - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> - -<p> -<b>Task 4: with this task we'll make you run into an aliasing problem . . .</b> - -- Create a time-array starting $t=0$, with a sampling rate of 100 Hz, and ending such that a sinusoid with a frequency of 1 Hz fits exactly 5 times in the measurement time. - -- Re-create the signal $x(t) = A \sin(2 \pi f_c t + \varphi)$ from the first Task, with amplitude $A=1.0$ V, carrier frequency $f_c=1.0$ Hz, and initial phase $\varphi = 5$ degrees, to be converted into radians. - -- Add to this signal a second sinusoid with a frequency of $80$ Hz and amplitude of $0.1$ V (and zero initial phase). - -- Create a plot of the signal against time, and of the amplitude spectrum as in the previous Tasks. - -Then answer to the following questions: -<ol> - <li>What do you see in the frequency plot? Are there peaks? How many? Where?</li> - <li>Does this match what you see in the time plot?</li> - <li>Does changing the measurement time (duration) help?</li> -</ol> -</p> -</div> - -```python -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -# plt.figure(figsize=(12,6)) -# plt.subplot(211) -# YOUR_CODE_HERE -# plt.grid() -# plt.title('Time signal') -# plt.legend() - -# plt.subplot(212) -# YOUR_CODE_HERE -# plt.loglog() -# YOUR_CODE_HERE -# plt.grid() -# plt.tight_layout() -# plt.title('Amplitude spectrum') -# plt.legend() -``` - -```python -### SOLUTION -T_meas = 5 -f_s = 100 - -t_vec = np.arange(0, T_meas, 1/f_s) # ends at 4.99, length 500 - -A = 1 -f_c = 1 -phi = 5 * np.pi / 180 -x = A * np.sin(2 * np.pi * f_c * t_vec + phi) - -A_i = 0.1 -f_i = 80 -x += A_i * np.sin(2 * np.pi * f_i * t_vec) - -N = len(x) -X_cont = np.fft.fft(x) / N - -f_0 = f_s / N -f_vec = np.arange(0, f_s, f_0) - -X_cont = X_cont[:N//2] -f_vec = f_vec[:N//2] - -plt.figure(figsize=(12,6)) -plt.subplot(211) -plt.plot(t_vec, x, color='b', label='signal') -plt.xlabel(r"$t \: [s]$") -plt.ylabel(r"$x(t) \: [V]$") -plt.grid() -plt.title('Time signal') -plt.legend() - -plt.subplot(212) -plt.plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transform') -plt.loglog() -plt.xlim(0.04, 100) -plt.ylim(10**(-19), 10) -plt.xlabel(r"$f \: \: [Hz]$") -plt.ylabel(r"$|X(f)| \: [V]$") -plt.grid() -plt.tight_layout() -plt.title('Amplitude spectrum') -plt.legend(); -``` - -**In addition to the code output above, write your answer in this Markdown cell.** - - -<div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Solution:</b> -<ol> - <li>There are two peaks, one of $0.5$ at $1$ Hz and one of $0.05$ at $20$ Hz, which should be at $80$ Hz (again exact values are hard to read but should be derived from theory).</li> - <li>Yes, there is a large amplitude sinusoid with a frequency of $1$ Hz, and a small amplitude sinusoid with a frequency of $20$ Hz on top if it (count the number of wiggles - there are $20$ wavies within 1 second). However, it does not match the input signal we created (with $1$ Hz and $80$ Hz).</li> - <li>No, the frequency resolution would change, but not the largest frequency of the amplitude spectrum, as that one is determined by the sampling frequency $f_s$.</li> -</ol> -</p> -</div> - - -The effect seen in Task 4 is called *aliasing*, and the cause is that if your sample rate is too low for the signals you're measuring, you will not capture their oscillation period sufficiently - with at least two samples per cycle. Instead, the signal will appear at a much lower frequency, as you can see in the figure below. Here $f_c = 5$ Hz, and the signal was sampled with $f_c = 7$ Hz, and based on the discrete time samples we incorrectly conclude that there is a frequency component at $2$ Hz (at the end of Chapter 4). - -<img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/NewSlide38.png" style="margin:auto" width=800/> -<img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/NewSlide51.png" style="margin:auto" width=800/> - -So, how fast do we need to sample to capture an $80$ Hz signal? - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 5:</b> - -Repeat Task 4 with different sample rates: $110, 150, 160,$ and $200$ Hz. Plot the signal and amplitude spectrum for each one (you might want to use a loop). - -Then answer the following questions: -<ol> - <li>At what frequency does the (aliased) 80 Hz signal appear in the spectrum, for the above values of $f_s$ (provide numerical answers)?</li> - <li>Can you figure out the relationship (a simple equation) between the sample rate and the frequency of the original signal, and the frequency at which the alias appears?</li> -</ol> -</p> -</div> - -```python -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -# for YOUR_CODE_HERE: - -# YOUR_CODE_HERE - -# plt.figure(figsize=(12,6)) -# plt.suptitle(f'$f_s = {YOUR_CODE_HERE}$ Hz') -# plt.subplot(211) -# YOUR_CODE_HERE -# plt.grid() -# plt.legend() - -# plt.subplot(212) -# YOUR_CODE_HERE -# plt.loglog() -# plt.grid() -# plt.tight_layout() -# plt.legend() -``` - -```python -### SOLUTION - -f_s_lst = [110, 150, 160, 200] - -for f_s in f_s_lst: - T_meas = 5 - # f_s = 100 - - t_vec = np.arange(0, T_meas, 1/f_s) - - A = 1 - f_c = 1 - phi = 5 * np.pi / 180 - x = A * np.sin(2 * np.pi * f_c * t_vec + phi) - - A_i = 0.1 - f_i = 80 - x += A_i * np.sin(2 * np.pi * f_i * t_vec) - - N = len(x) - X_cont = np.fft.fft(x) / N - - f_0 = f_s / N - f_vec = np.arange(0, f_s, f_0) - - X_cont = X_cont[:N//2] - f_vec = f_vec[:N//2] - - plt.figure(figsize=(12,6)) - plt.suptitle(f'$f_s = {f_s}$ Hz') - plt.subplot(211) - plt.plot(t_vec, x, color='b', label='signal') - plt.xlabel(r'$t \: [s]$') - plt.ylabel(r'$x(t) \: [V] $') - plt.grid() - plt.legend() - plt.subplot(212) - plt.plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transform') - plt.loglog() - plt.xlim(0.04, 100) - plt.ylim(10**(- 19), 10) - plt.xlabel(r'$f \: \: [Hz]$') - plt.ylabel(r'$|X(f)| \: [V]$') - plt.grid() - plt.tight_layout() - plt.legend() -``` - -**In addition to the code output above, write your answer in this Markdown cell.** - - -<div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Solution:</b> -<ul> - <li> Different frequencies: - <ul> - <li>$f_s=110$ Hz: peak at $30$ Hz. - <li>$f_s=150$ Hz: peak at $70$ Hz. - <li>$f_s=160$ Hz: no peak (the $80$ Hz signal is sampled exactly twice per cycle, exactly at the 'zero-passes'; we now don't see it at all). - <li>$f_s=200$ Hz: peak at $80$ Hz. - </ul> -</li> - <li>The sample rate needs to be more than twice the (highest) frequency of the signal, which is the *Nyquist* rate. As long as we do not meet this requirement the alias appears mirrored about the Nyquist frequency (which is half the sampling frequency), e.g. with $f_s=110$ Hz, the alias of $f_i=80$ Hz appears at $110-80=30$ Hz.</li> -</ol> -</p> -</div> - - -As you probably figured out, the sample rate needs to be faster than twice the largest frequency in the signal. In other words, you can measure signals with a frequency up to half the sample rate without aliasing becoming a problem. The frequency above which aliasing occurs (half the sampling rate) is called the *Nyquist frequency* (Chapter 4). - - -### Damped vibrations - -We now know how to create an amplitude/magnitude spectrum. We've seen that we get aliasing if our signal has components at frequencies higher than the *Nyquist frequency* (and leakage if the measurement time is too short). Now, let's consider the damped vibration aceleration signal that an accelerometer would measure (see *Appendix A*). In this case the damping ratio is not equal to zero, unlike in Tasks 1 to 5. - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 6:</b> - -- Create a time-array starting at $t=0$ s, ending at $t = 50$ s, with a sampling rate of $100$ Hz. -- Create a damped harmonic acceleration signal $x(t) = \frac{x(0)}{\sqrt{1-\zeta^2}} e^{-\zeta \omega_0 t} \sin(\omega_d t)$ with $\zeta = 0.05$, $\omega_0 = 10 \pi$ rad/s (corresponding to $5$ Hz), $\omega_d = \omega_0 \sqrt{1-\zeta^2} = 9.987 \pi$ rad/s, and initial displacement $x(0)=1$ (for convenience the initial phase of the signal is kept to zero). -- Create a plot of the signal against time, and of the amplitude spectrum as in the previous Tasks. - -Then answer the following questions: -<ol> - <li>Do you see any changes in the time plot, compared to the earlier plot? Describe them!</li> - <li>What is the dominant frequency of the signal now?</li> -</ol> -</p> -</div> - -```python -YOUR_CODE_HERE - -# # Write your own code or use the template below to create your figure(s) - -# plt.figure(figsize=(12,6)) -# plt.subplot(211) -# YOUR_CODE_HERE -# plt.grid() -# plt.legend() - -# plt.subplot(212) -# YOUR_CODE_HERE -# plt.loglog() -# YOUR_CODE_HERE -# plt.grid() -# plt.tight_layout() -# plt.legend() -``` - -```python -### SOLUTION -T_meas = 50 -f_s = 100 - -t_vec = np.arange(0, T_meas, 1/f_s) - -x_0 = 1 -zeta = 0.05 -omega_0 = 10 * np.pi -omega_d = omega_0 * np.sqrt(1 - zeta**2) -x = x_0 / (np.sqrt(1 - zeta**2)) * np.exp(-zeta * omega_0 * t_vec) * np.sin(omega_d * t_vec) - -N = len(x) -X_cont = np.fft.fft(x) / N - -f_0 = f_s / N -f_vec = np.arange(0, f_s, f_0) - -X_cont = X_cont[:N//2] -f_vec = f_vec[:N//2] - -plt.figure(figsize=(12,6)) -plt.subplot(211) -plt.plot(t_vec, x, color='b', label='signal') -plt.xlabel(r"$t \: [s]$") -plt.ylabel(r"$x(t) \: [V] $") -plt.title('Time signal') -plt.grid() -plt.legend() - -plt.subplot(212) -plt.plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transfrom') -plt.loglog() -plt.xlim(0.04, 100) -plt.ylim(10**(-7), 10) -plt.xlabel(r"$f \: \: [Hz]$") -plt.ylabel(r"$|X(f)| \: [V]$") -plt.title('Amplitude spectrum') -plt.grid() -plt.tight_layout() -plt.legend() - -print(f_vec[np.argmax(np.abs(X_cont))]) -``` - -**In addition to the code output above, write your answer in this Markdown cell.** - - -<div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Solution:</b> -<ol> - <li>The signal is now clearly a sinusoid with an exponentially decaying amplitude, a.k.a. a damped vibration!</li> - <li>Around $5$ Hz (max value of $|X_{cont}|$ at $4.98$ Hz).</li> -</ol> -Instead of a 'crisp' spectrum, with a very clear, distinct and ultimately narrow peak, you now get a kind of smoothed or faded peak. This is simply the result of dealing with a damped harmonic, rather than a perfect harmonic. The signal somehow still looks pretty periodic, but strictly spoken, the signal is not periodic anymore, as the amplitude slightly changes (decreases) with time. -</p> -</div> - - -### Cantilever-beam acceleration measurements - -Now you're ready to start analyzing the cantilever-beam acceleration measurements. - -Read in the data-file: *cantileverbeam_acc50Hz.csv*. - -This dataset contains 5 minutes of measurements with a sampling rate of $50$ Hz (a total of $N=15001$ samples). The first column in the file contains the UTC time of day (in seconds), the second column contains the measured acceleration (in m/s<sup>2</sup>). - - -### Detrending - -In this project the signal of interest is the damped, harmonic motion of the cantilever-beam. In addition the measurements may contain (unwanted) effects of the sensor (think of an offset, due to imperfect manufacturing and/or prior calibration, or a drift over time, for instance due to temperature changes in the electronics during the experiment). By detrending we mean to remove such effects, prior to our spectral analysis, so that we can start with a nice, zero mean signal. A-priori detrending is good practice and generally yields a cleaner spectrum. Next week (week 2.4 on Time Series Analysis) we cover the subject of removing unwanted effects from the signal in more detail, as to obtain a so-called **stationary** signal, meaning that the properties or characteristics of the signal (such as the mean) do not change over time, and, we provide practical means to “stationarize†a given or measured signal. - -There are built-in functions in Python to remove such an offset and/or trend (and you're free to use them). But, earlier in the MUDE, in week 1.3, you learned about least-squares parameter estimation, and that's what you can apply to do the detrending (and actually built-in functions just apply the very same principle). Next week, on Time Series Analysis, you will actually be covering (again) the estimation of a trend in a time series of measurements. -As a re-cap for week 1.3: when a series of observations $y_1, …, y_m$ (in our case with $m=N$) is supposed or expected to exhibit a functional linear trend (a straight line in terms of a graph), this can be modelled as - -$$ -\mathbb{E} = \begin{pmatrix} \begin{bmatrix} Y_{1} \\ Y_{2} \\ \vdots \\ Y_{m} \end{bmatrix} \end{pmatrix} - = - \begin{bmatrix} 1 & t_1 - t_1 \\ 1 & t_2 - t_1 \\ \vdots & \vdots \\ 1 & t_m - t_1 \end{bmatrix} - \begin{pmatrix} x_{1} \\ x_{2} \end{pmatrix} -$$ - -with $x_1$ the offset at time $t_1$ (rather than $t=0$), and $x_2$ the slope of the line. The two unknown parameters in this vector $x$ can be estimated through (unweighted) least-squares, $\hat{x}=(A^T A)^{-1} A^T y$, and next the residuals are obtained as $\hat{\epsilon}=y-\hat{y}=y-A\hat{x}$. The residuals are the 'left-over part' of the observations, once the (estimated) trend has been taken out; these residuals are of interest for further spectral analysis! - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 7:</b> - -- For the cantilever-beam acceleration measurements, perform a least-squares estimation according to the above model, and report the estimated offset and slope of the trend. -- The detrended acceleration measurements, hence the elements of vector $\hat{\epsilon}$ are the input to your spectral analysis, so from here on, we denote them by $x(t)$ (in continuous time), and by $x_n$ (in discrete time) with $n=0,…,N-1$. -- Make a plot of the input signal as a function of time, hence of the detrended accelerations. - -Report the estimated offset and slope of the trend (i.e. numerical values). -</ol> -</p> -</div> - -```python -df = pd.read_csv('cantileverbeam_acc50Hz.csv', header=0) - -t = np.array(df['time']) # -dat = np.array(df['acceleration']) # - -N = len(t) - -plt.figure() -plt.plot(t, dat, color='b', label='acceleration signal') -plt.xlabel('time [s]') -plt.ylabel('acceleration [m/s2]') -plt.title('Vertical cantilever beam acceleration') -plt.legend() - -# observation record length (as N*dt, according to sample-and-hold convention) -T = (t[N-1] - t[0])*N/(N - 1) -dt = T/N - -YOUR_CODE_HERE -``` - -```python -# LOAD DATA - -df = pd.read_csv('cantileverbeam_acc50Hz.csv', header=0) - -t = np.array(df['time']) # -dat = np.array(df['acceleration']) # - -N = len(t) - -# observation record length (as N * dt, according to sample-and-hold convention) -T = (t[N-1] - t[0]) * N / (N - 1) -dt = T / N -plt.figure() -plt.plot(t, dat, color='b', label='acceleration signal') -plt.xlabel('time [s]') -plt.ylabel('acceleration [m/s2]') -plt.title('Vertical cantilever beam acceleration') -plt.legend() - -### SOLUTION - -#detrend data -A = np.column_stack((np.ones(N), t - t[0])) - -#xhat = np.linalg.lstsq(A, dat, rcond=None)[0] -xhat = np.linalg.inv((A.T)@A)@A.T@dat -yhat = A@xhat -ehat = dat - yhat - -plt.figure() -plt.plot(t, ehat, color='b', label='detrended signal') -plt.xlabel('time [s]') -plt.ylabel('detrended accelerations [m/s2]') -plt.title('Detrended vertical cantilever beam acceleration') -plt.legend(); -``` - -**In addition to the code output above, write your answer in this Markdown cell.** - - -<div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Solution:</b> - -The mean is $-0.43$ m/s<sup>2</sup>, so that's considerable, and the slope is $-1.3e^{-4}$ m/s<sup>2</sup>, which is pretty much negligible over the duration of this experiment; mean/offset when one forgets to subtract $t[0]$ from the time column in the A-matrix, hence reporting the offset for 00:00h UTC, this is $8.08$ m/s<sup>2</sup>. -</p> -</div> - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 8:</b> - -Previously, in Task 3, you computed and plotted the magnitude spectrum $|X_k|$ of a signal for positive frequencies $f>0$ (putting a lot of attention to correctly labelling the horizontal frequency axis of the plot!), and now, with the material of Chapter 6 on spectral estimation, you will estimate the power spectral density $S$ of the signal through the periodogram, which is just: $S(k\Delta f)=\frac{|X_k|^2}{T}$ (in [W/Hz] when $x_n$ is a voltage signal; and $|X_k|$ being the result straight from the <code>np.fft</code>, multiplied by sampling interval $\Delta t$), for frequency $k\Delta f$, with frequency resolution $\Delta f=\frac{1}{T}$, and $k=0,…,N-1$ (hence, pretty much the same procedure as with the magnitude spectrum, though just taking the square of the modulus, and dividing by $T$). - -Compute and plot the periodogram for the detrended accelerometer measurements of Task 7 (if you prefer, feel free to use a linear scaling of the axes here, rather a log-log, and, use $T$ as defined already in the code of Task 7). Please, pay attention to correctly labelling the axes, and stating dimensions of the quantities along the axes! -</p> -</div> - -```python -YOUR_CODE_HERE -``` - -```python -### SOLUTION - -#estimate and plot power spectral density (PSD) -# in this solution code we use np.fft (rather than scipy.fft), and we actually compute and plot a (symmetric) -#two-sided PSD-estimate (using also the fftshift), as we like to (optionally) compare it with the Python -#built-in periodogram - -Fs = 1 / dt -f0 = 1 / T -print(Fs) -print(f0) - -f = np.concatenate((np.arange(-Fs / 2 + f0 / 2, 0, f0), np.arange(0, Fs / 2, f0))) -print(f) - -Z = np.fft.fft(ehat) * dt -psd = (np.abs(Z))**2/T -plt.figure() -plt.plot(f,np.fft.fftshift(psd), color='b', label='psd') -print(Z) -plt.xlabel('frequency [Hz]') -plt.ylabel('PSD [m2/s4/Hz]') -plt.title('Power Spectral Density (PSD)') -plt.legend(); -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 9:</b> - -Answer the following questions: -<ol> - <li>Report the damped natural frequency (in Hertz) of this one-degree-of-freedom (1DOF) mechanical system. Does it match the motion of the beam shown in the cantilever-beam video?</li> - <li>The acceleration was measured at quite a high sample rate of $50$ Hz. What is the minimum sampling frequency to correctly identify the damped natural frequency in the periodogram?</li> -</ol> -<p> -</div> - - -**Write your answer(s) in this Markdown cell.** - - -<div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Solution:</b> -<ol> - <li>Around $1.36$ Hz, and yes, this matches the motion in the video.</li> - <li>Nyquist rate is twice the (highest) frequency in the signal, hence $2 \times 1.36 = 2.72$ Hz, so, any value larger than $2.72$ Hz.</li> -</ol> -</p> -</div> - - -## Task 10: Global Mean Sea-Level (GMSL) data (optional) - -Repeat the steps with Tasks 7-9, but now with the Global Mean Sea Level data set. Data is from the Australia's National Science Agency (CSIRO): [GMSL data](https://www.cmar.csiro.au/sealevel/sl_hist_last_decades.html). - -These data result from nearly 3 decades of satellite altimetry (with satellite missions such as TOPEX/Poseidon and the Jason-series). The first column contains the time tag or epoch (in decimal years), the second column is the global mean sea level (in mm). There is one measurement per month (monthly average, so that for instance tide-effects are averaged out, and the measurement typically refers to the middle of the month, hence 1993.042 is mid January in 1993). The single monthly measurement is the global mean sea level, so, the average of the entire world. - -The sampling frequency $f_s = 12$ per year ($\Delta t = 1/12 \sim 0.083$ year), and there are $N=331$ measurements in total. - -```python -data = pd.read_csv('CSIRO_Alt_seas_inc.txt', names=['month', 'sl']) -data.head() -``` - -```python -# create time-array, time relative to t0 [yr] (epoch-time of the first observation; -# t0=1993.042 refers to mid January 1993) -t = data.iloc[:, 0] - data.iloc[0, 0] - -# number of observations -N = len(t) - -# observation record length (as N * dt, according to sample-and-hold convention) -T = (t[N - 1] - t[0]) * N / (N - 1) - -# Delta t [yr]; dt = T/N = (N*dt)/N -dt = T / N - -# observed sea-level height -y = data.iloc[:,1] - -# plot observed time-series, as it is, versus epoch-time in [year] -plt.plot(data.iloc[:,0],y, color='b', label='sea level') -plt.xlabel('time [yr]') -plt.ylabel('sea-level height [mm]') -plt.title('Global Mean Sea-Level (GMSL) rise') -plt.legend(); -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>Task 10 (Optional!):</b> - -Detrend the data. - -Estimate and plot power spectral density (PSD), hence the periodogram, for the (detrended) global mean sea-level data. - -Identify the largest peak in the spectrum, what is the frequency, and can you come up with a physical explanation of this behaviour? -</ol> -</p> -</div> - -```python -YOUR_CODE_HERE -``` - -```python -### SOLUTION - -# prepare for detrending the data, we'll estimate an offset and a slope (two unknown parameters) -A = np.ones((N, 2)) -A[:,1] = t - -# (unweighted) least-squares estimation of two parameters -xhat = (np.linalg.inv(A.T @ A) @ A.T) @ y - -# estimated observations (fitted by a straight line with offset and slope) -yhat = A @ xhat - -# difference of observed value and estimated observation (least-squares residuals) -ehat = y - yhat - -# hence observed time-series but detrended, this will act as our signal x(t), or x_0,...,x_{N-1} -plt.plot(data.iloc[:,0], ehat, color='b', label='detrended signal') -plt.xlabel('time [yr]') -plt.ylabel('detrended sea-level height [mm]') -plt.title('Detrened Global Mean Sea-Level') -plt.legend() -``` - -```python -### SOLUTION - -# sampling frequency [Hz] -Fs = 1 / dt - -# observed signal to length NFFT ( record length is NFFT*dt) -NFFT = N - -# Discrete Fourier Transform (DFT) by fft, to NFFT samples -# and multiply by Delta t (as to maintain analogy with continuous-time Fourier transform) -X = dt * np.fft.fft(ehat, NFFT) - -# frequency resolution -f0 = 1 / (NFFT * dt) - -# frequency array (centered at f=0, and conform fftshift) for NFFT even, covers interval [-Fs/2,Fs/2) -#f = np.concatenate((np.arange(- Fs / 2, 0, f0), np.arange(0, Fs / 2 , f0))); #+ f0/4 -f = np.concatenate((np.arange(-Fs / 2 + f0 / 2, 0, f0), np.arange(0, Fs / 2 , f0))) #- f0 / 4 - - -# for NFFT odd, use instead: f=np.concatenate((np.arange(-Fs/2 + f0/2, 0, f0), np.arange(0, Fs/2, f0))); covers interval (-Fs/2,Fs/2) -#|Xk|^2 / T periodogram (centered, with f=0 in the center), division by T, which is actual data record length -plt.plot(f, np.fft.fftshift((abs(X))**2 / T), color='b', label='psd') -plt.xlabel(r'frequency [$yr^{-1}$]') -plt.ylabel(r'PSD [$mm^2$ yr]') -plt.title('Power Spectral Density of GMSL data') -plt.legend(); -``` - -**Write your answer(s) in this Markdown cell.** - - -<div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Solution:</b> - -The largest peak is $f = 0.996$/ year, hence the annual cycle, related to summer and winter, there is also a peak at $f = 1.992$/year, hence the double frequency (related to a half year cycle), and this one typically shows up if the once per year periodic cycle is not a perfect harmonic (sine or cosine), but instead a bit distorted/skewed, finally, there is also a large peak at $f = \frac{1}{T} = 0.0362$/year, a long term effect, which implies a cycle with the duration of the entire data set, which here seems just coincidence, that a full cycle occurs in $T=27.58$ years. -</p> -</div> - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -<p> -<b>End of task.</b> -</p> -</div> - - -<div style="background-color:#C8FFFF; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Appendix A: Cantilever-beam dynamics:</b> - -The dynamics of the smartphone suspended on a cantilever beam can be considered as the mass-spring-damper system shown below: - -<img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/mass_spring_damper.png" style="margin:auto" width=200/> - -The equation of motion of the deflection $x$ of this mass-spring-damper system (a damped harmonic oscillator) can be described by the following second order differential equation: - -$$ -\ddot{x}(t) + \frac{c}{m} \dot{x}(t) + \frac{k}{m} x(t) =0 -$$ - -Where $\ddot{x}(t)$, $\dot{x}(t)$ and $x(t)$ are the acceleration, velocity and displacement as a function of time of the oscillating mass $m$ [kg] respectively. (with a unit transfer function, $x(t)$ describes the motion of the proof mass inside the smartphone accelerometer). For simplicity, we consider here the homogeneous equation, corresponding to free motion. The other parameters are the damping coefficient $c$ [kg/s] and spring constant $k$ [N/m]. The damping ratio can be obtained from the system parameters: $\zeta = \frac{c}{2 \sqrt{mk}}$, which is dimensionless. The undamped natural frequency is $\omega_0 = \sqrt{\frac{k}{m}}$ [rad/s]. The differential equation becomes: - -$$ -\ddot{x}(t) + 2 \zeta \omega_0 \dot{x}(t) + \omega_0^2 x(t) =0 -$$ - -For the under-damped case ($0 \le \zeta \le 1)$ of our smartphone and assuming an initial zero tip velocity $\dot{x}(t=0)=0$ (release from stand-still), the solution for the position as a function of time is given by: - -$$ -x(t)=e^{-\zeta \omega_0 t} \frac{x(0)}{\sqrt{1-\zeta^2}}\sin(\omega_d t + \varphi) -$$ - -Where $x(0)$ is the initial position $x(t=0)$, $\omega_d$ is the damped natural frequency $\omega_d = \omega_0 \sqrt{1-\zeta^2}$, and the phase shift $\varphi = \arctan \left( \frac{\sqrt{1-\zeta^2}}{\zeta} \right)$. The sinusoid term represents the harmonic motion, and the exponential term represents the damping of that motion over time. Next, the velocity of the smartphone's oscillation can be derived as: - -$\dot{x}(t) = e^{-\zeta \omega_0 t} \frac{x(0)}{\sqrt{1-\zeta^2}}\sin(\omega_d t)$. - -The acceleration of the smartphone (which is what is being measured) is found as: - -$\ddot{x}(t) = e^{-\zeta \omega_0 t} \frac{x(0)}{\sqrt{1-\zeta^2}} \sin (\omega_d t - \phi)$. - -Note that $\omega_0$ and $\omega_d$ are the angular frequencies expressed in radians per second. $\ddot{x}(t)$ is a damped harmonic signal where the rate of damping is determined by the damping ratio $\zeta$. - -In order to get a pure harmonic signal (as used in Tasks 1 to 5), set the damping ratio $\zeta=0$, and optionally set the phase-shift $\phi$ to zero as well, then the tip acceleration is given by the following simple sinusoidal expression: - -$$ -\ddot{x}(t)=x(0) \sin(\omega_0 t). -$$ -</p> -</div> - - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/GA_2_3/Analysis_solution.py b/synced_files/students/GA_2_3/Analysis_solution.py deleted file mode 100644 index b633e56cf08a5db9824037bf233256f5e9fd8153..0000000000000000000000000000000000000000 --- a/synced_files/students/GA_2_3/Analysis_solution.py +++ /dev/null @@ -1,1074 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: mude-base -# language: python -# name: python3 -# --- - -# %% [markdown] -# # GA 2.3: Beam Beats -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px"\> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px"\> -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): week 2.3. Due: Friday, November 29, 2024.* - -# %% [markdown] -# ## Analyzing cantilever-beam accelerations and global Mean Sea-Level measurements -# -# This project covers the week on Signal Processing (week 2.3). -# -# As a warming up you will create and analyze some elementary signals yourself, and next, you will carry out frequency domain analyses on two given data-sets, namely acceleration measurements of a Cantilever-Beam experiment, and (in optional Task 10) Global Mean Sea-Level measurements. -# -# Most of the Tasks in this notebook consist of both coding, producing a plot, and answering (open) questions. Typically, as you work your way through the Tasks, you can often re-use code, or part of it, from earlier Tasks and assignments. That will save you a lot of work!! - -# %% [markdown] id="0491cc69" -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>In many of the code blocks below, template code to create figures is provided. Note that there is a lot of code missing, and one line of <code>YOUR_CODE_HERE</code> does not imply that only one line of code is missing!</p></div> - -# %% [markdown] -# ### Data Acquisition System -# -# A data acquisition (DAQ) system usually consists of four components: -# -# <img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/DAQ.png" style="margin:auto"/> -# -# -# - A sensor transforms a physical signal into a small voltage. The transformation is often frequency dependent or nonlinear, and can show drift or bias. -# - Signal conditioning electronics (often included in the sensor housing) filter unwanted frequencies, such as the 50 Hz line frequency caused by power plant generators, using low-pass or notch filters. In addition the sensor voltage may be amplified. -# - An analog-to-digital (A/D) converter samples the analog voltage with a certain rate, such as 100 Hz. The A/D converter can measure analog voltages within a certain range, the measurement range. The measured voltage is quantized with a certain resolution, such as 14-bit, which means that the full measurement range is divided into $2^{14}=16,384$ discrete intervals. Together, the resolution and measurement range determine the precision. Usually the sample rate, the measurement range, and the sample resolution are configurable. Sampling and quantizing together turns an analog signal into a digital signal. -# - A digital computer reads the sampled data from the A/D converter at specific times, and allows for further processing, analysis and storage of the (digital) signal. -# -# The result is that an analog, physical signal, is turned into a series of numbers (samples of the signal, in the time domain), ready for processing and analysis in a digital computer. -# -#  -# -# One of the data sets that you will analyze during this MUDE Q2 project was acquired by an accelerometer in a smartphone, on top of a vertical cantilever-beam. The accelerometer measures the side-ward accelerations, expressed in m/s<sup>2</sup>, and sampled at 50 Hz. Detailed information about the experiment and the sensor can be found in "Experimental evaluation of smartphone accelerometer and low-cost dual frequency GNSS sensors for deformation monitoring", by Alexandru Lapadat, Christian Tiberius and Peter Teunissen, Sensors 2021, 21, 7946, https://doi.org/10.3390/s21237946. -# -# A quick impression of the test setup can be gained by watching the short video [Cantilever Beam Experiment](https://youtu.be/o4moRwvlBLU?si=aKelBMWm3HB2Of26) (1 minute). -# -# A theoretical description of the motion of the smartphone accelerometer fixed to the cantilever beam is presented in Appendix A. Pulling the beam at the tip and releasing it, results in a (nearly) horizontal side-ward motion of the smartphone, and the (horizontal) position can be described by a *damped harmonic* as a function of time. Consequently, also the first and second derivative with respect to time, the velocity and acceleration as a function of time as the smartphone will measure it, are harmonics. -# -# ### Basic sinusoid signal -# -# You will start with first creating (and analyzing) a few simple signals yourself. In the first few Tasks of this project, we will take the damping ratio zero and use a fairly short measurement time (duration), and hence the acceleration measured by the smartphone is a plain (undamped) sinusoid as shown in Appendix A (a stationary signal). In the following Tasks we also add a phase offset $\varphi$ to the plain sinusoid: -# -# $$ -# x(t) = A \sin(2 \pi f_c t + \varphi) -# $$ -# -# The result is taken from the last equation in Appendix A. We consider here acceleration, though for convenience, we omit the dots on top of the $x(t)$. - -# %% -import numpy as np -import pandas as pd -import matplotlib.pyplot as plt - -# %matplotlib inline - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 1:</b> -# -# - Create a time-array starting at $t=0$ s, ending at $t=5.0$ s, with a sampling rate of 100 Hz. Hint: what is the number of samples $N$? And what should then be the last value in the time-array? Note that, for example, with $N=10$ samples at a sampling rate of $f_s = 100$ Hz, we have signal samples at times $t=0.00, 0.01, 0.02, ... , 0.08, 0.09$ seconds, hence $T_{meas}= N \Delta t =0.1$ seconds (the sample-and-hold convention). -# - Create a sinusoidal signal $x(t) = A \sin(2 \pi f_c t + \varphi)$, with amplitude $A=1.0$ Volt, carrier frequency $f_c=1.0$ Hz, and initial phase $\varphi = 5$ degrees, to be converted into radians. -# - Make a plot of the signal against time. Note that this is strictly a *sampled signal* $x_n$ rather than $x(t)$, but since we use a rather high sampling rate, the signal shown is close to continuous in time. Connecting the sample points of $x_n$ in the graph by lines, as done in the graph below, corroborates the suggestion of a continuous-time signal. Be aware! -# </p> -# </div> - -# %% [markdown] id="0491cc69" -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>We will give you the answers in this code cell for free!</p></div> - -# %% -T_meas = 5 -f_s = 100 #sampling rate [Hz] - -t_vec = np.arange(0, T_meas, 1 / f_s) # ends at 4.99, length 500 according to the sample-and-hold convention - -A = 1 -f_c = 1 -phi = 5 * np.pi / 180 -x = A * np.sin(2 * np.pi * f_c * t_vec + phi) - -plt.plot(t_vec, x, color='b', label='signal') -plt.xlabel(r'$t \: [s]$') -plt.ylabel(r'$x(t) \: [V]$') -plt.legend(loc='upper right') -plt.title(fr'Sinusoidal signal with $A$={A} V, $f_c$={f_c} Hz and initial phase $\phi$={phi:.3f} °') -plt.grid() - -# %% [markdown] -# **In addition to the code output above, write your answer in this Markdown cell.** - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Solution:</b> -# -# The number of samples is $N=\frac{T_{meas}}{\Delta t}=T_{meas}\cdot f_s=5\cdot 100=500$. -# The last value should be $4.99$ because we use a $\Delta t=\frac{1}{f_s}=0.01$ s. -# </p> -# </div> - -# %% [markdown] -# ### The Discrete Fourier Transform (chapter 5) -# -# To discover which frequencies are contained in the signal $x(t)$, we can transform it from the time domain to the frequency domain using the Fourier transform: -# -# $$ -# X(f) = \int_{-\infty}^{\infty} x(t) e^{-j 2\pi f t} dt -# $$ -# -# Which can then be expressed in terms of magnitude and phase: -# -# $$ -# X(f) = |X(f)|e^{j\theta(f)} -# $$ -# -# Where $|X(f)|$ plotted against frequency $f$ is called the *magnitude spectrum* (and practically often referred to as amplitude spectrum). -# -# The set and number of sinusoids required to approximate or re-create a given signal $x(t)$ depends on the shape of that signal. Of course, when the signal is a pure sinusoid, we only need one term. For an example, consider a 2 Hz sinusoidal signal and its magnitude spectrum below (the magnitude spectrum is expressed in [Vs], which equals [V/Hz], hence a magnitude or amplitude density). -# -# <img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/SignalSpectrumExample.png" style="margin:auto" width=800/> - -# %% [markdown] -# You can see a sharp spike in the magnitude plot (which has two logarithmic axes, and we only plot the spectrum for positive frequencies $f>0$). A continuous time sinusoid with amplitude $A$ will produce a magnitude of $\frac{A T_{meas}}{2}$ in the amplitude spectrum (with $T_{meas}$ the *measurement time* or duration), rather than $\frac{A}{2}$ which you would expect (in a double-sided spectrum). This is because of the limited time duration of the input signal, which actually implies multiplication of $x(t)$ by a *rectangular time window* $w(t)=\Pi(\frac{t}{T_{meas}})$. Since the sinusoid has an amplitude of $A=1$ V, and was measured for $T_{meas}=5$ seconds, the magnitude becomes 2.5. The magnitude at all other frequencies is very small, approximately $10^{-15}$, or approximately zero. -# -# The Fourier transform is a continuous-time operation, mapping the continuous time-domain to the continuous frequency domain. Usually, we don't have continuous-time signals, but discrete time signals $x_n$ sampled at a certain sampling rate. The discrete Fourier Transform (DFT) is the discrete-time equivalent of the continuous time-Fourier transform: -# -# $$ -# X_k = \sum_{n=0}^{N-1}x_ne^{-j2\pi kn/N}, k=0,1,...,N-1 -# $$ -# -# Where $X_k$ is the sequence of frequency domain samples. NumPy contains a function to perform the DFT using a fast numerical algorithm, the Fast Fourier Transform: -# -# <code>X_discr = np.fft.fft(x)</code> -# -# For more information on the function see [here](https://numpy.org/doc/stable/reference/generated/numpy.fft.fft.html). -# -# The discrete-time signal $x_n$ and the frequency domain samples $X_k$ returned by Python are of equal length ($N$ samples in, $N$ samples out). When you compare the equations of the DFT with the continuous Fourier Transform, you will see that in the continuous equation we integrate over time $t$, while in the DFT *no information* about the time or sample rate is required (there is no $\Delta t$ in the above equation for $X_k$, as noted at the end of Chapter 5). This results in a *scale factor* in the spectrum when the DFT of signals with different sample rates are compared. To solve this, we have to multiply the DFT as calculated by NumPy by the sample time interval $\Delta t = 1/f_s$ to restore the time dimension and obtain a *discrete approximation of the continuous Fourier Transform*. To account for the measurement duration as described above, we have to divide by $T_{meas} = N \Delta t$. So, in total, multiply by $\Delta t$ and divide by $T_{meas}$, hence, we have to divide the NumPy result by the number of samples $N$: -# -# <code>X_cont = np.fft.fft(x) / N</code> -# -# The DFT only contains information (the complex value of $X_k$) at discrete frequencies, known as the *analysis frequencies*, which are integer multiples of the frequency resolution $f_0$. If we have a sampled signal $x_n$ consisting of $N$ samples, sampled at $f_s$ Hz with $f_s=1/ \Delta t$, the frequency resolution is: -# -# $$ -# f_0 = \frac{1}{T_{meas}} = \frac{1}{N \Delta t} = \frac{f_s}{N} -# $$ -# -# The first value of the complex vector $X_n$ returned by NumPy is the mean of the time-domain signal corresponding to $f=0$ Hz. So, the frequency vector corresponding to the discrete Fourier transform starts at zero and has $N$ elements, the analysis frequencies: -# -# <code>f_vec = np.arange(0, f_s, f_0)</code> -# -# With task 2 you visualize the entire output as you get it from the `np.fft.fft`, hence for frequencies $[0,f_s)$. From Chapter 4 you know that the spectrum of a sampled signal repeats every integer multiple of $f_s$ (copies of the spectrum). - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 2:</b> -# -# - Calculate the Fast Fourier Transform of the signal you generated in Task 1. Remember: the signal has 500 samples and thus does *not* end at exactly 5 second. -# - Create the frequency vector $f$ with the analysis frequencies. -# - Plot the modulus of the Fourier Transform against the frequency $f$ using a log scale on both axes. Use plot markers to see at which frequencies the Fourier transform was calculated. -# -# On top of that, answer to the following questions: -# <ol> -# <li>Describe the amplitude spectrum.</li> -# <li>What is the magnitude of $X(f)$ at $f$ = 1 Hz?</li> -# <li>Do you notice anything peculiar about the amplitude spectrum?</li> -# </ol> -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -# f, axes = plt.subplots(1,1,figsize=(10,5)) - -# axes[0].plot(YOUR_CODE_HERE, YOUR_CODE_HERE, 'x', color='b', label='Fourier transform') -# axes[0].loglog() -# axes[0].set_xlabel('$f \: \: [Hz]$') -# axes[0].set_ylabel('$|X(f)| \: [V]$') -# axes[0].grid() -# axes[0].set_title('Log/Log') - -# %% -## SOLUTION - -T_meas = 5 -f_s = 100 - -t_vec = np.arange(0, T_meas, 1/f_s) # ends at 4.99, length 500 according to the sample-and-hold convention - -A = 1 -f_c = 1 -phi = 5 * np.pi / 180 -x = A * np.sin(2 * np.pi * f_c * t_vec + phi) - -N = len(x) -X_cont = np.fft.fft(x) / N - -f_0 = f_s / N -f_vec = np.arange(0, f_s, f_0) - -f, axes = plt.subplots(1,2,figsize=(10,5)) - -axes[0].plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transform') -axes[0].loglog() -axes[0].set_xlabel(r'$f \: \: [Hz]$') -axes[0].set_ylabel(r'$|X(f)| \: [V]$') -axes[0].grid() -axes[0].set_title('Log/Log') - -axes[1].plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transform') -axes[1].set_xlabel(r'$f \: \: [Hz]$') -axes[1].set_ylabel(r'$|X(f)| \: [V]$') -axes[1].grid() -axes[1].set_title('Linear') -plt.legend() - -print(f_vec[np.abs(X_cont)>0.1]) - -# %% [markdown] -# **In addition to the code output above, write your answer in this Markdown cell.** - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Solution:</b> -# <ol> -# <li>A peak of 0.5 should be found (from theory) at a frequency of 1 Hz and one around 100 Hz (exactly at 99 Hz), the rest all close to zero.</li> -# <li>0.5 (as we divide the fft-result by N to get the equivalent of the continuous-time Fourier transform).</li> -# <li>The peak at 100 Hz (or 99 Hz to be precise) should not be there. We did not input a signal with such a frequency.</li> -# </ol> -# </p> -# </div> - -# %% [markdown] -# ### Symmetry -# -# -# Due to symmetry properties of the DFT, the following holds for a real signal $x(t)$: -# -# $$ -# |X_k| = |X_{-k}| -# $$ -# -# Which means that the modulus of the Fourier coefficients is symmetric about $f=0$. The NumPy <code>fft</code> command appends the Fourier coefficients for $k<0$ to the right side of the Fourier coefficients for $k \ge 0$. This is called the *two-sided* spectrum. -# -# Since we are working with real signals, the symmetry property is valid, and we can just ignore the coefficients for $k<0$. This means that we consider the following range in the frequency domain: -# -# $[0, \frac{f_s}{2}]$ for even values of $N$ -# -# $[0, \frac{f_s}{2})$ for odd values of $N$ -# -# In other words, we are only considering frequencies up to half of $f_s$. This is easily implemented in Python using the floor division operator <code>//</code>: -# -# <code>X_cont = X_cont[:N//2]</code> -# \ -# <code>f_vec = f_vec[:N//2]</code> -# -# If you're unfamiliar with this, consider that <code>A//B</code> returns the number of times <code>B</code> 'fits into' <code>A</code>. In principle, this will always return an integer, so it can be easily used for indexing an array. In this specifc example, <code>N//2</code> will return $\frac{N}{2}$ for even $N$ and $\frac{N-1}{2}$ for odd N, which is exactly what we want. See the example below. - -# %% -N = 100 -print(f'{N} floor divided by 2: {N//2}') -print(f'{N+1} floor divided by 2: {(N+1)//2}') -print(f'{N-1} floor divided by 2: {(N-1)//2}') - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# -# <p> -# <b>Task 3:</b> -# -# - Repeat Task 2 with different measurement times $T_{meas}$ for the signal. Use measurement times such that the $f_c$ = 1 Hz oscillation fits *exactly* 1 time, 5 times and 20 times. -# - Plot the amplitude spectrum for all three measurement times, **only for positive frequencies**, in separate graphs (log-log scale) with the same domains and answer to the following questions: -# -# - What is the effect of changing $T_{meas}$ on the frequency range in the amplitude spectrum? Does the highest analysis frequency change? -# - Does the frequency resolution change? -# - Does the magnitude of at the peaks change? -# -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -plt.figure(figsize=(12,4)) -for i, T_meas in enumerate(YOUR_CODE_HERE): - YOUR_CODE_HERE - - plt.subplot(1, 3, i+1) - - YOUR_CODE_HERE - - plt.grid() - plt.tight_layout() -plt.legend() - -# %% -### SOLUTION -T_lst = [1, 5, 20] -f_s = 100 - -plt.figure(figsize=(12,4)) -for i, T_meas in enumerate(T_lst): - t_vec = np.arange(0, T_meas, 1/f_s) - A = 1 - f_c = 1 - phi = 5 * np.pi / 180 - x = A * np.sin(2 * np.pi * f_c * t_vec + phi) - - N = len(x) - X_cont = np.fft.fft(x) / N - - f_0 = f_s / N - f_vec = np.arange(0, f_s, f_0) - - X_cont = X_cont[:N//2] - f_vec = f_vec[:N//2] - - plt.subplot(1, 3, i+1) - plt.plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transform') - plt.loglog() - plt.xlim(0.04, 100) - plt.ylim(10**(-19), 10) - plt.xlabel(r'$f \: \: [Hz]$') - plt.ylabel(r'$|X(f)| \: [V]$') - plt.grid() - plt.tight_layout() -plt.legend(); - -# %% [markdown] -# **In addition to the code output above, write your answer in this Markdown cell.** - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Solution:</b> -# <ol> -# <li>No, the highest analysis frequency stays the same (as it is related to the sampling frequency, which we did not change).</li> -# <li>Yes, the frequency resolution becomes better/finer (gets smaller).</li> -# <li>No, because we already divide by (we already account for the measurement duration).</li> -# </ol> -# </p> -# </div> - -# %% [markdown] -# ### Aliasing (chapter 4) -# -# So far we have been analyzing a signal with a fairly low frequency, just $1$ or $2$ Hz. Now suppose, due to some unexpected source, our signal contains a second sinusoid with a much higher frequency. This is often caused by the line frequency ($50$ Hz) due to power plant generators providing the $220$ V current in regular buildings, or by electrical interference. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# -# <p> -# <b>Task 4: with this task we'll make you run into an aliasing problem . . .</b> -# -# - Create a time-array starting $t=0$, with a sampling rate of 100 Hz, and ending such that a sinusoid with a frequency of 1 Hz fits exactly 5 times in the measurement time. -# -# - Re-create the signal $x(t) = A \sin(2 \pi f_c t + \varphi)$ from the first Task, with amplitude $A=1.0$ V, carrier frequency $f_c=1.0$ Hz, and initial phase $\varphi = 5$ degrees, to be converted into radians. -# -# - Add to this signal a second sinusoid with a frequency of $80$ Hz and amplitude of $0.1$ V (and zero initial phase). -# -# - Create a plot of the signal against time, and of the amplitude spectrum as in the previous Tasks. -# -# Then answer to the following questions: -# <ol> -# <li>What do you see in the frequency plot? Are there peaks? How many? Where?</li> -# <li>Does this match what you see in the time plot?</li> -# <li>Does changing the measurement time (duration) help?</li> -# </ol> -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -# plt.figure(figsize=(12,6)) -# plt.subplot(211) -# YOUR_CODE_HERE -# plt.grid() -# plt.title('Time signal') -# plt.legend() - -# plt.subplot(212) -# YOUR_CODE_HERE -# plt.loglog() -# YOUR_CODE_HERE -# plt.grid() -# plt.tight_layout() -# plt.title('Amplitude spectrum') -# plt.legend() - -# %% -### SOLUTION -T_meas = 5 -f_s = 100 - -t_vec = np.arange(0, T_meas, 1/f_s) # ends at 4.99, length 500 - -A = 1 -f_c = 1 -phi = 5 * np.pi / 180 -x = A * np.sin(2 * np.pi * f_c * t_vec + phi) - -A_i = 0.1 -f_i = 80 -x += A_i * np.sin(2 * np.pi * f_i * t_vec) - -N = len(x) -X_cont = np.fft.fft(x) / N - -f_0 = f_s / N -f_vec = np.arange(0, f_s, f_0) - -X_cont = X_cont[:N//2] -f_vec = f_vec[:N//2] - -plt.figure(figsize=(12,6)) -plt.subplot(211) -plt.plot(t_vec, x, color='b', label='signal') -plt.xlabel(r"$t \: [s]$") -plt.ylabel(r"$x(t) \: [V]$") -plt.grid() -plt.title('Time signal') -plt.legend() - -plt.subplot(212) -plt.plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transform') -plt.loglog() -plt.xlim(0.04, 100) -plt.ylim(10**(-19), 10) -plt.xlabel(r"$f \: \: [Hz]$") -plt.ylabel(r"$|X(f)| \: [V]$") -plt.grid() -plt.tight_layout() -plt.title('Amplitude spectrum') -plt.legend(); - -# %% [markdown] -# **In addition to the code output above, write your answer in this Markdown cell.** - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Solution:</b> -# <ol> -# <li>There are two peaks, one of $0.5$ at $1$ Hz and one of $0.05$ at $20$ Hz, which should be at $80$ Hz (again exact values are hard to read but should be derived from theory).</li> -# <li>Yes, there is a large amplitude sinusoid with a frequency of $1$ Hz, and a small amplitude sinusoid with a frequency of $20$ Hz on top if it (count the number of wiggles - there are $20$ wavies within 1 second). However, it does not match the input signal we created (with $1$ Hz and $80$ Hz).</li> -# <li>No, the frequency resolution would change, but not the largest frequency of the amplitude spectrum, as that one is determined by the sampling frequency $f_s$.</li> -# </ol> -# </p> -# </div> - -# %% [markdown] -# The effect seen in Task 4 is called *aliasing*, and the cause is that if your sample rate is too low for the signals you're measuring, you will not capture their oscillation period sufficiently - with at least two samples per cycle. Instead, the signal will appear at a much lower frequency, as you can see in the figure below. Here $f_c = 5$ Hz, and the signal was sampled with $f_c = 7$ Hz, and based on the discrete time samples we incorrectly conclude that there is a frequency component at $2$ Hz (at the end of Chapter 4). -# -# <img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/NewSlide38.png" style="margin:auto" width=800/> -# <img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/NewSlide51.png" style="margin:auto" width=800/> -# -# So, how fast do we need to sample to capture an $80$ Hz signal? - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 5:</b> -# -# Repeat Task 4 with different sample rates: $110, 150, 160,$ and $200$ Hz. Plot the signal and amplitude spectrum for each one (you might want to use a loop). -# -# Then answer the following questions: -# <ol> -# <li>At what frequency does the (aliased) 80 Hz signal appear in the spectrum, for the above values of $f_s$ (provide numerical answers)?</li> -# <li>Can you figure out the relationship (a simple equation) between the sample rate and the frequency of the original signal, and the frequency at which the alias appears?</li> -# </ol> -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# Write your own code or use the template below to create your figure(s) - -# for YOUR_CODE_HERE: - -# YOUR_CODE_HERE - -# plt.figure(figsize=(12,6)) -# plt.suptitle(f'$f_s = {YOUR_CODE_HERE}$ Hz') -# plt.subplot(211) -# YOUR_CODE_HERE -# plt.grid() -# plt.legend() - -# plt.subplot(212) -# YOUR_CODE_HERE -# plt.loglog() -# plt.grid() -# plt.tight_layout() -# plt.legend() - -# %% -### SOLUTION - -f_s_lst = [110, 150, 160, 200] - -for f_s in f_s_lst: - T_meas = 5 - # f_s = 100 - - t_vec = np.arange(0, T_meas, 1/f_s) - - A = 1 - f_c = 1 - phi = 5 * np.pi / 180 - x = A * np.sin(2 * np.pi * f_c * t_vec + phi) - - A_i = 0.1 - f_i = 80 - x += A_i * np.sin(2 * np.pi * f_i * t_vec) - - N = len(x) - X_cont = np.fft.fft(x) / N - - f_0 = f_s / N - f_vec = np.arange(0, f_s, f_0) - - X_cont = X_cont[:N//2] - f_vec = f_vec[:N//2] - - plt.figure(figsize=(12,6)) - plt.suptitle(f'$f_s = {f_s}$ Hz') - plt.subplot(211) - plt.plot(t_vec, x, color='b', label='signal') - plt.xlabel(r'$t \: [s]$') - plt.ylabel(r'$x(t) \: [V] $') - plt.grid() - plt.legend() - plt.subplot(212) - plt.plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transform') - plt.loglog() - plt.xlim(0.04, 100) - plt.ylim(10**(- 19), 10) - plt.xlabel(r'$f \: \: [Hz]$') - plt.ylabel(r'$|X(f)| \: [V]$') - plt.grid() - plt.tight_layout() - plt.legend() - -# %% [markdown] -# **In addition to the code output above, write your answer in this Markdown cell.** - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Solution:</b> -# <ul> -# <li> Different frequencies: -# <ul> -# <li>$f_s=110$ Hz: peak at $30$ Hz. -# <li>$f_s=150$ Hz: peak at $70$ Hz. -# <li>$f_s=160$ Hz: no peak (the $80$ Hz signal is sampled exactly twice per cycle, exactly at the 'zero-passes'; we now don't see it at all). -# <li>$f_s=200$ Hz: peak at $80$ Hz. -# </ul> -# </li> -# <li>The sample rate needs to be more than twice the (highest) frequency of the signal, which is the *Nyquist* rate. As long as we do not meet this requirement the alias appears mirrored about the Nyquist frequency (which is half the sampling frequency), e.g. with $f_s=110$ Hz, the alias of $f_i=80$ Hz appears at $110-80=30$ Hz.</li> -# </ol> -# </p> -# </div> - -# %% [markdown] -# As you probably figured out, the sample rate needs to be faster than twice the largest frequency in the signal. In other words, you can measure signals with a frequency up to half the sample rate without aliasing becoming a problem. The frequency above which aliasing occurs (half the sampling rate) is called the *Nyquist frequency* (Chapter 4). - -# %% [markdown] -# ### Damped vibrations -# -# We now know how to create an amplitude/magnitude spectrum. We've seen that we get aliasing if our signal has components at frequencies higher than the *Nyquist frequency* (and leakage if the measurement time is too short). Now, let's consider the damped vibration aceleration signal that an accelerometer would measure (see *Appendix A*). In this case the damping ratio is not equal to zero, unlike in Tasks 1 to 5. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 6:</b> -# -# - Create a time-array starting at $t=0$ s, ending at $t = 50$ s, with a sampling rate of $100$ Hz. -# - Create a damped harmonic acceleration signal $x(t) = \frac{x(0)}{\sqrt{1-\zeta^2}} e^{-\zeta \omega_0 t} \sin(\omega_d t)$ with $\zeta = 0.05$, $\omega_0 = 10 \pi$ rad/s (corresponding to $5$ Hz), $\omega_d = \omega_0 \sqrt{1-\zeta^2} = 9.987 \pi$ rad/s, and initial displacement $x(0)=1$ (for convenience the initial phase of the signal is kept to zero). -# - Create a plot of the signal against time, and of the amplitude spectrum as in the previous Tasks. -# -# Then answer the following questions: -# <ol> -# <li>Do you see any changes in the time plot, compared to the earlier plot? Describe them!</li> -# <li>What is the dominant frequency of the signal now?</li> -# </ol> -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# # Write your own code or use the template below to create your figure(s) - -# plt.figure(figsize=(12,6)) -# plt.subplot(211) -# YOUR_CODE_HERE -# plt.grid() -# plt.legend() - -# plt.subplot(212) -# YOUR_CODE_HERE -# plt.loglog() -# YOUR_CODE_HERE -# plt.grid() -# plt.tight_layout() -# plt.legend() - -# %% -### SOLUTION -T_meas = 50 -f_s = 100 - -t_vec = np.arange(0, T_meas, 1/f_s) - -x_0 = 1 -zeta = 0.05 -omega_0 = 10 * np.pi -omega_d = omega_0 * np.sqrt(1 - zeta**2) -x = x_0 / (np.sqrt(1 - zeta**2)) * np.exp(-zeta * omega_0 * t_vec) * np.sin(omega_d * t_vec) - -N = len(x) -X_cont = np.fft.fft(x) / N - -f_0 = f_s / N -f_vec = np.arange(0, f_s, f_0) - -X_cont = X_cont[:N//2] -f_vec = f_vec[:N//2] - -plt.figure(figsize=(12,6)) -plt.subplot(211) -plt.plot(t_vec, x, color='b', label='signal') -plt.xlabel(r"$t \: [s]$") -plt.ylabel(r"$x(t) \: [V] $") -plt.title('Time signal') -plt.grid() -plt.legend() - -plt.subplot(212) -plt.plot(f_vec, np.abs(X_cont), 'x', color='b', label='Fourier transfrom') -plt.loglog() -plt.xlim(0.04, 100) -plt.ylim(10**(-7), 10) -plt.xlabel(r"$f \: \: [Hz]$") -plt.ylabel(r"$|X(f)| \: [V]$") -plt.title('Amplitude spectrum') -plt.grid() -plt.tight_layout() -plt.legend() - -print(f_vec[np.argmax(np.abs(X_cont))]) - -# %% [markdown] -# **In addition to the code output above, write your answer in this Markdown cell.** - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Solution:</b> -# <ol> -# <li>The signal is now clearly a sinusoid with an exponentially decaying amplitude, a.k.a. a damped vibration!</li> -# <li>Around $5$ Hz (max value of $|X_{cont}|$ at $4.98$ Hz).</li> -# </ol> -# Instead of a 'crisp' spectrum, with a very clear, distinct and ultimately narrow peak, you now get a kind of smoothed or faded peak. This is simply the result of dealing with a damped harmonic, rather than a perfect harmonic. The signal somehow still looks pretty periodic, but strictly spoken, the signal is not periodic anymore, as the amplitude slightly changes (decreases) with time. -# </p> -# </div> - -# %% [markdown] -# ### Cantilever-beam acceleration measurements -# -# Now you're ready to start analyzing the cantilever-beam acceleration measurements. -# -# Read in the data-file: *cantileverbeam_acc50Hz.csv*. -# -# This dataset contains 5 minutes of measurements with a sampling rate of $50$ Hz (a total of $N=15001$ samples). The first column in the file contains the UTC time of day (in seconds), the second column contains the measured acceleration (in m/s<sup>2</sup>). - -# %% [markdown] -# ### Detrending -# -# In this project the signal of interest is the damped, harmonic motion of the cantilever-beam. In addition the measurements may contain (unwanted) effects of the sensor (think of an offset, due to imperfect manufacturing and/or prior calibration, or a drift over time, for instance due to temperature changes in the electronics during the experiment). By detrending we mean to remove such effects, prior to our spectral analysis, so that we can start with a nice, zero mean signal. A-priori detrending is good practice and generally yields a cleaner spectrum. Next week (week 2.4 on Time Series Analysis) we cover the subject of removing unwanted effects from the signal in more detail, as to obtain a so-called **stationary** signal, meaning that the properties or characteristics of the signal (such as the mean) do not change over time, and, we provide practical means to “stationarize†a given or measured signal. -# -# There are built-in functions in Python to remove such an offset and/or trend (and you're free to use them). But, earlier in the MUDE, in week 1.3, you learned about least-squares parameter estimation, and that's what you can apply to do the detrending (and actually built-in functions just apply the very same principle). Next week, on Time Series Analysis, you will actually be covering (again) the estimation of a trend in a time series of measurements. -# As a re-cap for week 1.3: when a series of observations $y_1, …, y_m$ (in our case with $m=N$) is supposed or expected to exhibit a functional linear trend (a straight line in terms of a graph), this can be modelled as -# -# $$ -# \mathbb{E} = \begin{pmatrix} \begin{bmatrix} Y_{1} \\ Y_{2} \\ \vdots \\ Y_{m} \end{bmatrix} \end{pmatrix} -# = -# \begin{bmatrix} 1 & t_1 - t_1 \\ 1 & t_2 - t_1 \\ \vdots & \vdots \\ 1 & t_m - t_1 \end{bmatrix} -# \begin{pmatrix} x_{1} \\ x_{2} \end{pmatrix} -# $$ -# -# with $x_1$ the offset at time $t_1$ (rather than $t=0$), and $x_2$ the slope of the line. The two unknown parameters in this vector $x$ can be estimated through (unweighted) least-squares, $\hat{x}=(A^T A)^{-1} A^T y$, and next the residuals are obtained as $\hat{\epsilon}=y-\hat{y}=y-A\hat{x}$. The residuals are the 'left-over part' of the observations, once the (estimated) trend has been taken out; these residuals are of interest for further spectral analysis! - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 7:</b> -# -# - For the cantilever-beam acceleration measurements, perform a least-squares estimation according to the above model, and report the estimated offset and slope of the trend. -# - The detrended acceleration measurements, hence the elements of vector $\hat{\epsilon}$ are the input to your spectral analysis, so from here on, we denote them by $x(t)$ (in continuous time), and by $x_n$ (in discrete time) with $n=0,…,N-1$. -# - Make a plot of the input signal as a function of time, hence of the detrended accelerations. -# -# Report the estimated offset and slope of the trend (i.e. numerical values). -# </ol> -# </p> -# </div> - -# %% -df = pd.read_csv('cantileverbeam_acc50Hz.csv', header=0) - -t = np.array(df['time']) # -dat = np.array(df['acceleration']) # - -N = len(t) - -plt.figure() -plt.plot(t, dat, color='b', label='acceleration signal') -plt.xlabel('time [s]') -plt.ylabel('acceleration [m/s2]') -plt.title('Vertical cantilever beam acceleration') -plt.legend() - -# observation record length (as N*dt, according to sample-and-hold convention) -T = (t[N-1] - t[0])*N/(N - 1) -dt = T/N - -YOUR_CODE_HERE - -# %% -# LOAD DATA - -df = pd.read_csv('cantileverbeam_acc50Hz.csv', header=0) - -t = np.array(df['time']) # -dat = np.array(df['acceleration']) # - -N = len(t) - -# observation record length (as N * dt, according to sample-and-hold convention) -T = (t[N-1] - t[0]) * N / (N - 1) -dt = T / N -plt.figure() -plt.plot(t, dat, color='b', label='acceleration signal') -plt.xlabel('time [s]') -plt.ylabel('acceleration [m/s2]') -plt.title('Vertical cantilever beam acceleration') -plt.legend() - -### SOLUTION - -#detrend data -A = np.column_stack((np.ones(N), t - t[0])) - -#xhat = np.linalg.lstsq(A, dat, rcond=None)[0] -xhat = np.linalg.inv((A.T)@A)@A.T@dat -yhat = A@xhat -ehat = dat - yhat - -plt.figure() -plt.plot(t, ehat, color='b', label='detrended signal') -plt.xlabel('time [s]') -plt.ylabel('detrended accelerations [m/s2]') -plt.title('Detrended vertical cantilever beam acceleration') -plt.legend(); - -# %% [markdown] -# **In addition to the code output above, write your answer in this Markdown cell.** - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Solution:</b> -# -# The mean is $-0.43$ m/s<sup>2</sup>, so that's considerable, and the slope is $-1.3e^{-4}$ m/s<sup>2</sup>, which is pretty much negligible over the duration of this experiment; mean/offset when one forgets to subtract $t[0]$ from the time column in the A-matrix, hence reporting the offset for 00:00h UTC, this is $8.08$ m/s<sup>2</sup>. -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 8:</b> -# -# Previously, in Task 3, you computed and plotted the magnitude spectrum $|X_k|$ of a signal for positive frequencies $f>0$ (putting a lot of attention to correctly labelling the horizontal frequency axis of the plot!), and now, with the material of Chapter 6 on spectral estimation, you will estimate the power spectral density $S$ of the signal through the periodogram, which is just: $S(k\Delta f)=\frac{|X_k|^2}{T}$ (in [W/Hz] when $x_n$ is a voltage signal; and $|X_k|$ being the result straight from the <code>np.fft</code>, multiplied by sampling interval $\Delta t$), for frequency $k\Delta f$, with frequency resolution $\Delta f=\frac{1}{T}$, and $k=0,…,N-1$ (hence, pretty much the same procedure as with the magnitude spectrum, though just taking the square of the modulus, and dividing by $T$). -# -# Compute and plot the periodogram for the detrended accelerometer measurements of Task 7 (if you prefer, feel free to use a linear scaling of the axes here, rather a log-log, and, use $T$ as defined already in the code of Task 7). Please, pay attention to correctly labelling the axes, and stating dimensions of the quantities along the axes! -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# %% -### SOLUTION - -#estimate and plot power spectral density (PSD) -# in this solution code we use np.fft (rather than scipy.fft), and we actually compute and plot a (symmetric) -#two-sided PSD-estimate (using also the fftshift), as we like to (optionally) compare it with the Python -#built-in periodogram - -Fs = 1 / dt -f0 = 1 / T -print(Fs) -print(f0) - -f = np.concatenate((np.arange(-Fs / 2 + f0 / 2, 0, f0), np.arange(0, Fs / 2, f0))) -print(f) - -Z = np.fft.fft(ehat) * dt -psd = (np.abs(Z))**2/T -plt.figure() -plt.plot(f,np.fft.fftshift(psd), color='b', label='psd') -print(Z) -plt.xlabel('frequency [Hz]') -plt.ylabel('PSD [m2/s4/Hz]') -plt.title('Power Spectral Density (PSD)') -plt.legend(); - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 9:</b> -# -# Answer the following questions: -# <ol> -# <li>Report the damped natural frequency (in Hertz) of this one-degree-of-freedom (1DOF) mechanical system. Does it match the motion of the beam shown in the cantilever-beam video?</li> -# <li>The acceleration was measured at quite a high sample rate of $50$ Hz. What is the minimum sampling frequency to correctly identify the damped natural frequency in the periodogram?</li> -# </ol> -# <p> -# </div> - -# %% [markdown] -# **Write your answer(s) in this Markdown cell.** - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Solution:</b> -# <ol> -# <li>Around $1.36$ Hz, and yes, this matches the motion in the video.</li> -# <li>Nyquist rate is twice the (highest) frequency in the signal, hence $2 \times 1.36 = 2.72$ Hz, so, any value larger than $2.72$ Hz.</li> -# </ol> -# </p> -# </div> - -# %% [markdown] -# ## Task 10: Global Mean Sea-Level (GMSL) data (optional) -# -# Repeat the steps with Tasks 7-9, but now with the Global Mean Sea Level data set. Data is from the Australia's National Science Agency (CSIRO): [GMSL data](https://www.cmar.csiro.au/sealevel/sl_hist_last_decades.html). -# -# These data result from nearly 3 decades of satellite altimetry (with satellite missions such as TOPEX/Poseidon and the Jason-series). The first column contains the time tag or epoch (in decimal years), the second column is the global mean sea level (in mm). There is one measurement per month (monthly average, so that for instance tide-effects are averaged out, and the measurement typically refers to the middle of the month, hence 1993.042 is mid January in 1993). The single monthly measurement is the global mean sea level, so, the average of the entire world. -# -# The sampling frequency $f_s = 12$ per year ($\Delta t = 1/12 \sim 0.083$ year), and there are $N=331$ measurements in total. - -# %% -data = pd.read_csv('CSIRO_Alt_seas_inc.txt', names=['month', 'sl']) -data.head() - -# %% -# create time-array, time relative to t0 [yr] (epoch-time of the first observation; -# t0=1993.042 refers to mid January 1993) -t = data.iloc[:, 0] - data.iloc[0, 0] - -# number of observations -N = len(t) - -# observation record length (as N * dt, according to sample-and-hold convention) -T = (t[N - 1] - t[0]) * N / (N - 1) - -# Delta t [yr]; dt = T/N = (N*dt)/N -dt = T / N - -# observed sea-level height -y = data.iloc[:,1] - -# plot observed time-series, as it is, versus epoch-time in [year] -plt.plot(data.iloc[:,0],y, color='b', label='sea level') -plt.xlabel('time [yr]') -plt.ylabel('sea-level height [mm]') -plt.title('Global Mean Sea-Level (GMSL) rise') -plt.legend(); - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>Task 10 (Optional!):</b> -# -# Detrend the data. -# -# Estimate and plot power spectral density (PSD), hence the periodogram, for the (detrended) global mean sea-level data. -# -# Identify the largest peak in the spectrum, what is the frequency, and can you come up with a physical explanation of this behaviour? -# </ol> -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# %% -### SOLUTION - -# prepare for detrending the data, we'll estimate an offset and a slope (two unknown parameters) -A = np.ones((N, 2)) -A[:,1] = t - -# (unweighted) least-squares estimation of two parameters -xhat = (np.linalg.inv(A.T @ A) @ A.T) @ y - -# estimated observations (fitted by a straight line with offset and slope) -yhat = A @ xhat - -# difference of observed value and estimated observation (least-squares residuals) -ehat = y - yhat - -# hence observed time-series but detrended, this will act as our signal x(t), or x_0,...,x_{N-1} -plt.plot(data.iloc[:,0], ehat, color='b', label='detrended signal') -plt.xlabel('time [yr]') -plt.ylabel('detrended sea-level height [mm]') -plt.title('Detrened Global Mean Sea-Level') -plt.legend() - -# %% -### SOLUTION - -# sampling frequency [Hz] -Fs = 1 / dt - -# observed signal to length NFFT ( record length is NFFT*dt) -NFFT = N - -# Discrete Fourier Transform (DFT) by fft, to NFFT samples -# and multiply by Delta t (as to maintain analogy with continuous-time Fourier transform) -X = dt * np.fft.fft(ehat, NFFT) - -# frequency resolution -f0 = 1 / (NFFT * dt) - -# frequency array (centered at f=0, and conform fftshift) for NFFT even, covers interval [-Fs/2,Fs/2) -#f = np.concatenate((np.arange(- Fs / 2, 0, f0), np.arange(0, Fs / 2 , f0))); #+ f0/4 -f = np.concatenate((np.arange(-Fs / 2 + f0 / 2, 0, f0), np.arange(0, Fs / 2 , f0))) #- f0 / 4 - - -# for NFFT odd, use instead: f=np.concatenate((np.arange(-Fs/2 + f0/2, 0, f0), np.arange(0, Fs/2, f0))); covers interval (-Fs/2,Fs/2) -#|Xk|^2 / T periodogram (centered, with f=0 in the center), division by T, which is actual data record length -plt.plot(f, np.fft.fftshift((abs(X))**2 / T), color='b', label='psd') -plt.xlabel(r'frequency [$yr^{-1}$]') -plt.ylabel(r'PSD [$mm^2$ yr]') -plt.title('Power Spectral Density of GMSL data') -plt.legend(); - -# %% [markdown] -# **Write your answer(s) in this Markdown cell.** - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Solution:</b> -# -# The largest peak is $f = 0.996$/ year, hence the annual cycle, related to summer and winter, there is also a peak at $f = 1.992$/year, hence the double frequency (related to a half year cycle), and this one typically shows up if the once per year periodic cycle is not a perfect harmonic (sine or cosine), but instead a bit distorted/skewed, finally, there is also a large peak at $f = \frac{1}{T} = 0.0362$/year, a long term effect, which implies a cycle with the duration of the entire data set, which here seems just coincidence, that a full cycle occurs in $T=27.58$ years. -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%;"> -# <p> -# <b>End of task.</b> -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#C8FFFF; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Appendix A: Cantilever-beam dynamics:</b> -# -# The dynamics of the smartphone suspended on a cantilever beam can be considered as the mass-spring-damper system shown below: -# -# <img src="https://gitlab.com/JelleKnibbe/public-files/-/raw/main/SP_Practical/mass_spring_damper.png" style="margin:auto" width=200/> -# -# The equation of motion of the deflection $x$ of this mass-spring-damper system (a damped harmonic oscillator) can be described by the following second order differential equation: -# -# $$ -# \ddot{x}(t) + \frac{c}{m} \dot{x}(t) + \frac{k}{m} x(t) =0 -# $$ -# -# Where $\ddot{x}(t)$, $\dot{x}(t)$ and $x(t)$ are the acceleration, velocity and displacement as a function of time of the oscillating mass $m$ [kg] respectively. (with a unit transfer function, $x(t)$ describes the motion of the proof mass inside the smartphone accelerometer). For simplicity, we consider here the homogeneous equation, corresponding to free motion. The other parameters are the damping coefficient $c$ [kg/s] and spring constant $k$ [N/m]. The damping ratio can be obtained from the system parameters: $\zeta = \frac{c}{2 \sqrt{mk}}$, which is dimensionless. The undamped natural frequency is $\omega_0 = \sqrt{\frac{k}{m}}$ [rad/s]. The differential equation becomes: -# -# $$ -# \ddot{x}(t) + 2 \zeta \omega_0 \dot{x}(t) + \omega_0^2 x(t) =0 -# $$ -# -# For the under-damped case ($0 \le \zeta \le 1)$ of our smartphone and assuming an initial zero tip velocity $\dot{x}(t=0)=0$ (release from stand-still), the solution for the position as a function of time is given by: -# -# $$ -# x(t)=e^{-\zeta \omega_0 t} \frac{x(0)}{\sqrt{1-\zeta^2}}\sin(\omega_d t + \varphi) -# $$ -# -# Where $x(0)$ is the initial position $x(t=0)$, $\omega_d$ is the damped natural frequency $\omega_d = \omega_0 \sqrt{1-\zeta^2}$, and the phase shift $\varphi = \arctan \left( \frac{\sqrt{1-\zeta^2}}{\zeta} \right)$. The sinusoid term represents the harmonic motion, and the exponential term represents the damping of that motion over time. Next, the velocity of the smartphone's oscillation can be derived as: -# -# $\dot{x}(t) = e^{-\zeta \omega_0 t} \frac{x(0)}{\sqrt{1-\zeta^2}}\sin(\omega_d t)$. -# -# The acceleration of the smartphone (which is what is being measured) is found as: -# -# $\ddot{x}(t) = e^{-\zeta \omega_0 t} \frac{x(0)}{\sqrt{1-\zeta^2}} \sin (\omega_d t - \phi)$. -# -# Note that $\omega_0$ and $\omega_d$ are the angular frequencies expressed in radians per second. $\ddot{x}(t)$ is a damped harmonic signal where the rate of damping is determined by the damping ratio $\zeta$. -# -# In order to get a pure harmonic signal (as used in Tasks 1 to 5), set the damping ratio $\zeta=0$, and optionally set the phase-shift $\phi$ to zero as well, then the tip acceleration is given by the following simple sinusoidal expression: -# -# $$ -# \ddot{x}(t)=x(0) \sin(\omega_0 t). -# $$ -# </p> -# </div> - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Tutorials/Week_1_3/Analysis.ipynb b/synced_files/students/Tutorials/Week_1_3/Analysis.ipynb deleted file mode 100644 index 1feb3158da8d4a235fa6cd12eb076ddb4fc4f88c..0000000000000000000000000000000000000000 --- a/synced_files/students/Tutorials/Week_1_3/Analysis.ipynb +++ /dev/null @@ -1,222 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Week 1.3: Programming Tutorial\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px\" />\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px\" />\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.3. September 16, 2024.*\n", - "\n", - "_This notebook was prepared by Berend Bouvy and used in an in-class demonstration on Monday (the first of several programming tutorials)._" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def add(a, b):\n", - " result = a+b\n", - " return result\n", - "\n", - "def gen_xhat(A, y):\n", - " x_hat = np.linalg.inv(A.T @ A) @ A.T @ y\n", - " return x_hat" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "a = 1\n", - "b = 2\n", - "result = add(a, b)\n", - "\n", - "result" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Replace 'file.csv' with the path to your CSV file\n", - "data = np.genfromtxt('data.csv', delimiter=',', skip_header=1) # 'skip_header=1' skips the first row (header)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t = data[:,0]\n", - "y = data[:,1]\n", - "n_rows = data.shape[0]\n", - "n_cols = data.shape[1]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.plot(t, y,'o')\n", - "plt.title('t vs y')\n", - "plt.xlabel('t')\n", - "plt.ylabel('y')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "one_vector = np.ones(n_rows)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(one_vector+ t)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A = np.column_stack((one_vector, t))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x_hat = gen_xhat(A, y)\n", - "y_hat = A @ x_hat" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.plot(t, y,'o')\n", - "plt.plot(t, y_hat)\n", - "plt.title('t vs y')\n", - "plt.xlabel('t')\n", - "plt.ylabel('y')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A_new = np.column_stack((one_vector, t, t**2))\n", - "x_hat_new = gen_xhat(A_new, y)\n", - "y_hat_new = A_new @ x_hat_new\n", - "plt.plot(t, y,'o')\n", - "plt.plot(t, y_hat_new)\n", - "plt.title('t vs y')\n", - "plt.xlabel('t')\n", - "plt.ylabel('y')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "e_hat = y-y_hat_new" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" />\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" />\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2024 <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">MUDE</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">CC BY 4.0 License</a>." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "TAMude", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.5" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/synced_files/students/Tutorials/Week_1_3/Analysis.md b/synced_files/students/Tutorials/Week_1_3/Analysis.md deleted file mode 100644 index 452b9c762fb866ac01c992e9a21211b8f6f3598d..0000000000000000000000000000000000000000 --- a/synced_files/students/Tutorials/Week_1_3/Analysis.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: TAMude - language: python - name: python3 ---- - -# Week 1.3: Programming Tutorial - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.3. September 16, 2024.* - -_This notebook was prepared by Berend Bouvy and used in an in-class demonstration on Monday (the first of several programming tutorials)._ - -```python -def add(a, b): - result = a+b - return result - -def gen_xhat(A, y): - x_hat = np.linalg.inv(A.T @ A) @ A.T @ y - return x_hat -``` - -```python -a = 1 -b = 2 -result = add(a, b) - -result -``` - -```python -import numpy as np -import matplotlib.pyplot as plt -``` - -```python -# Replace 'file.csv' with the path to your CSV file -data = np.genfromtxt('data.csv', delimiter=',', skip_header=1) # 'skip_header=1' skips the first row (header) - - -``` - -```python -t = data[:,0] -y = data[:,1] -n_rows = data.shape[0] -n_cols = data.shape[1] -``` - -```python -plt.plot(t, y,'o') -plt.title('t vs y') -plt.xlabel('t') -plt.ylabel('y') -``` - -```python -one_vector = np.ones(n_rows) -``` - -```python -print(one_vector+ t) -``` - -```python -A = np.column_stack((one_vector, t)) -``` - -```python -x_hat = gen_xhat(A, y) -y_hat = A @ x_hat -``` - -```python -plt.plot(t, y,'o') -plt.plot(t, y_hat) -plt.title('t vs y') -plt.xlabel('t') -plt.ylabel('y') -``` - -```python -A_new = np.column_stack((one_vector, t, t**2)) -x_hat_new = gen_xhat(A_new, y) -y_hat_new = A_new @ x_hat_new -plt.plot(t, y,'o') -plt.plot(t, y_hat_new) -plt.title('t vs y') -plt.xlabel('t') -plt.ylabel('y') -``` - -```python -e_hat = y-y_hat_new -``` - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Tutorials/Week_1_3/Analysis.py b/synced_files/students/Tutorials/Week_1_3/Analysis.py deleted file mode 100644 index 6e14bf093ac91d1ccc2d8dfbfbbfd940db24a26d..0000000000000000000000000000000000000000 --- a/synced_files/students/Tutorials/Week_1_3/Analysis.py +++ /dev/null @@ -1,126 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: TAMude -# language: python -# name: python3 -# --- - -# %% [markdown] -# # Week 1.3: Programming Tutorial -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.3. September 16, 2024.* -# -# _This notebook was prepared by Berend Bouvy and used in an in-class demonstration on Monday (the first of several programming tutorials)._ - -# %% -def add(a, b): - result = a+b - return result - -def gen_xhat(A, y): - x_hat = np.linalg.inv(A.T @ A) @ A.T @ y - return x_hat - - -# %% -a = 1 -b = 2 -result = add(a, b) - -result - -# %% -import numpy as np -import matplotlib.pyplot as plt - -# %% -# Replace 'file.csv' with the path to your CSV file -data = np.genfromtxt('data.csv', delimiter=',', skip_header=1) # 'skip_header=1' skips the first row (header) - - - -# %% -t = data[:,0] -y = data[:,1] -n_rows = data.shape[0] -n_cols = data.shape[1] - -# %% -plt.plot(t, y,'o') -plt.title('t vs y') -plt.xlabel('t') -plt.ylabel('y') - -# %% -one_vector = np.ones(n_rows) - -# %% -print(one_vector+ t) - -# %% -A = np.column_stack((one_vector, t)) - -# %% -x_hat = gen_xhat(A, y) -y_hat = A @ x_hat - -# %% -plt.plot(t, y,'o') -plt.plot(t, y_hat) -plt.title('t vs y') -plt.xlabel('t') -plt.ylabel('y') - -# %% -A_new = np.column_stack((one_vector, t, t**2)) -x_hat_new = gen_xhat(A_new, y) -y_hat_new = A_new @ x_hat_new -plt.plot(t, y,'o') -plt.plot(t, y_hat_new) -plt.title('t vs y') -plt.xlabel('t') -plt.ylabel('y') - -# %% -e_hat = y-y_hat_new - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Tutorials/Week_1_5/Tutorial.ipynb b/synced_files/students/Tutorials/Week_1_5/Tutorial.ipynb deleted file mode 100644 index a2146131fa23bb87251cb40acdc4cec14f1b348f..0000000000000000000000000000000000000000 --- a/synced_files/students/Tutorials/Week_1_5/Tutorial.ipynb +++ /dev/null @@ -1,246 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Week 1.5: Programming Tutorial\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px\" />\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px\" />\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.5. September 30, 2024.*\n", - "\n", - "_This notebook was prepared by Berend Bouvy and used in an in-class demonstration on Monday._" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Objects" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import os" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Objective: Create a variable of each type in Python\n", - "int_var = #TODO: create an integer variable\n", - "float_var = #TODO: create a float variable\n", - "bool_var = #TODO: create a boolean variable\n", - "str_var = #TODO: create a string variable\n", - "list_var = #TODO: create a list variable\n", - "tuple_var = #TODO: create a tuple variable\n", - "dict_var = #TODO: create a dictionary variable\n", - "\n", - "\n", - "# Asserts\n", - "assert type(int_var) == int, f'Expected int but got {type(int_var)}' # This will throw an error if the type is incorrect\n", - "assert type(float_var) == float, f'Expected float but got {type(float_var)}' # This will throw an error if the type is incorrect\n", - "assert type(bool_var) == bool, f'Expected bool but got {type(bool_var)}' # This will throw an error if the type is incorrect\n", - "assert type(str_var) == str, f'Expected str but got {type(str_var)}' # This will throw an error if the type is incorrect\n", - "assert type(list_var) == list, f'Expected list but got {type(list_var)}' # This will throw an error if the type is incorrect\n", - "assert type(tuple_var) == tuple, f'Expected tuple but got {type(tuple_var)}' # This will throw an error if the type is incorrect\n", - "assert type(dict_var) == dict, f'Expected dict but got {type(dict_var)}' # This will throw an error if the type is incorrect\n", - "\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# relative path vs absolute path\n", - "# relative path: relative to the current working directory\n", - "# absolute path: full path from the root directory\n", - "\n", - "# Create a variable that contains the current working directory using the os module\n", - "cwd = #TODO: get the current working directory\n", - "print(cwd)\n", - "\n", - "# Get all the files in the current working directory\n", - "files = #TODO: get all the files in the current working directory\n", - "print(files)\n", - "\n", - "# find path to data in data folder\n", - "data_dir = #TODO: find the path to the data folder\n", - "print(data_dir)\n", - "\n", - "# read the data using absolute path and relative path\n", - "data_abs = #TODO: read the data using absolute path\n", - "data_rel = #TODO: read the data using relative path\n", - "\n", - "# Asserts\n", - "assert data_abs == data_rel, 'Data read using absolute path and relative path are not the same' # This will throw an error if the data is not the same\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "$$ H_n = \\sum_{k=1}^{n} \\frac{1}{k} $$" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def harmonic_series(n):\n", - " \"\"\"\n", - " This function calculates the harmonic series of n\n", - " \"\"\"\n", - " result = #TODO: calculate the harmonic series of n\n", - " return result\n", - "\n", - "# Plotting\n", - "n = 100\n", - "x = #TODO: create a list of n values from 1 to n\n", - "y = #TODO: calculate the harmonic series of x, using list comprehension\n", - "\n", - "#TODO: plot x and y, with labels and title\n", - "\n", - "# asserts\n", - "assert harmonic_series(1) == 1, f'Expected 1 but got {harmonic_series(1)}'\n", - "assert harmonic_series(2) == 1.5, f'Expected 1.5 but got {harmonic_series(2)}'\n", - "assert harmonic_series(3) == 1.8333333333333333, f'Expected 1.8333333333333333 but got {harmonic_series(3)}'\n", - "\n", - "# save x, y data\n", - "data = #TODO: create a 2D array with x and y using np.column_stack()\n", - "#TODO: save data to a csv file" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[Wikipedia: Fibonacci sequence](https://en.wikipedia.org/wiki/Fibonacci_sequence)\n", - "\n", - "\n", - "$$ F_n = F_{n-1} + F_{n-2} \\quad \\text{for} \\quad n \\geq 2 \\quad \\text{with} \\quad F_0 = 0, \\quad F_1 = 1$$\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def fibonacci(n):\n", - " \"\"\"\n", - " This function will return the n-th numbers of the fibonacci sequence\n", - " \"\"\"\n", - " #TODO: calculate the n-th number of the fibonacci sequence\n", - " return result\n", - "\n", - "# Asserts\n", - "assert fibonacci(0) == 0, f'Expected 0 but got {fibonacci(0)}' # This will throw an error if the result is incorrect \n", - "assert fibonacci(1) == 1, f'Expected 1 but got {fibonacci(1)}' # This will throw an error if the result is incorrect\n", - "assert fibonacci(2) == 1, f'Expected 1 but got {fibonacci(2)}' # This will throw an error if the result is incorrect\n", - "assert fibonacci(3) == 2, f'Expected 2 but got {fibonacci(3)}' # This will throw an error if the result is incorrect" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def fib_sequence(n):\n", - " \"\"\"\n", - " This function will return the first n numbers of the fibonacci sequence\n", - " \"\"\"\n", - " # result = #TODO: calculate the first n numbers of the fibonacci sequence\n", - " result = [0, 1]\n", - " if n == 0:\n", - " return []\n", - " elif n == 1:\n", - " return [0]\n", - " for i in range(2, n):\n", - " result.append(result[-1] + result[-2])\n", - " return result\n", - "\n", - "# Asserts\n", - "assert fib_sequence(0) == [], f'Expected [] but got {fib_sequence(0)}' # This will throw an error if the result is incorrect\n", - "assert fib_sequence(1) == [0], f'Expected [0] but got {fib_sequence(1)}' # This will throw an error if the result is incorrect\n", - "assert fib_sequence(2) == [0, 1], f'Expected [0, 1] but got {fib_sequence(2)}' # This will throw an error if the result is incorrect\n", - "assert fib_sequence(3) == [0, 1, 1], f'Expected [0, 1, 1] but got {fib_sequence(3)}' # This will throw an error if the result is incorrect\n", - "assert fib_sequence(4) == [0, 1, 1, 2], f'Expected [0, 1, 1, 2] but got {fib_sequence(4)}' # This will throw an error if the result is incorrect\n", - "assert fib_sequence(5) == [0, 1, 1, 2, 3], f'Expected [0, 1, 1, 2, 3] but got {fib_sequence(5)}' # This will throw an error if the result is incorrect\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" />\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" />\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2024 <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">MUDE</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">CC BY 4.0 License</a>." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "TAMude", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.5" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/synced_files/students/Tutorials/Week_1_5/Tutorial.md b/synced_files/students/Tutorials/Week_1_5/Tutorial.md deleted file mode 100644 index 207b7eddd3b31cfbfc5e9f29848e0fbb5e5265b4..0000000000000000000000000000000000000000 --- a/synced_files/students/Tutorials/Week_1_5/Tutorial.md +++ /dev/null @@ -1,186 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: TAMude - language: python - name: python3 ---- - -# Week 1.5: Programming Tutorial - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.5. September 30, 2024.* - -_This notebook was prepared by Berend Bouvy and used in an in-class demonstration on Monday._ - - -## Objects - -```python -import numpy as np -import matplotlib.pyplot as plt -import os -``` - -```python -# Objective: Create a variable of each type in Python -int_var = #TODO: create an integer variable -float_var = #TODO: create a float variable -bool_var = #TODO: create a boolean variable -str_var = #TODO: create a string variable -list_var = #TODO: create a list variable -tuple_var = #TODO: create a tuple variable -dict_var = #TODO: create a dictionary variable - - -# Asserts -assert type(int_var) == int, f'Expected int but got {type(int_var)}' # This will throw an error if the type is incorrect -assert type(float_var) == float, f'Expected float but got {type(float_var)}' # This will throw an error if the type is incorrect -assert type(bool_var) == bool, f'Expected bool but got {type(bool_var)}' # This will throw an error if the type is incorrect -assert type(str_var) == str, f'Expected str but got {type(str_var)}' # This will throw an error if the type is incorrect -assert type(list_var) == list, f'Expected list but got {type(list_var)}' # This will throw an error if the type is incorrect -assert type(tuple_var) == tuple, f'Expected tuple but got {type(tuple_var)}' # This will throw an error if the type is incorrect -assert type(dict_var) == dict, f'Expected dict but got {type(dict_var)}' # This will throw an error if the type is incorrect - - - -``` - -```python -# relative path vs absolute path -# relative path: relative to the current working directory -# absolute path: full path from the root directory - -# Create a variable that contains the current working directory using the os module -cwd = #TODO: get the current working directory -print(cwd) - -# Get all the files in the current working directory -files = #TODO: get all the files in the current working directory -print(files) - -# find path to data in data folder -data_dir = #TODO: find the path to the data folder -print(data_dir) - -# read the data using absolute path and relative path -data_abs = #TODO: read the data using absolute path -data_rel = #TODO: read the data using relative path - -# Asserts -assert data_abs == data_rel, 'Data read using absolute path and relative path are not the same' # This will throw an error if the data is not the same - -``` - -$$ H_n = \sum_{k=1}^{n} \frac{1}{k} $$ - -```python -def harmonic_series(n): - """ - This function calculates the harmonic series of n - """ - result = #TODO: calculate the harmonic series of n - return result - -# Plotting -n = 100 -x = #TODO: create a list of n values from 1 to n -y = #TODO: calculate the harmonic series of x, using list comprehension - -#TODO: plot x and y, with labels and title - -# asserts -assert harmonic_series(1) == 1, f'Expected 1 but got {harmonic_series(1)}' -assert harmonic_series(2) == 1.5, f'Expected 1.5 but got {harmonic_series(2)}' -assert harmonic_series(3) == 1.8333333333333333, f'Expected 1.8333333333333333 but got {harmonic_series(3)}' - -# save x, y data -data = #TODO: create a 2D array with x and y using np.column_stack() -#TODO: save data to a csv file -``` - -<!-- #region --> -[Wikipedia: Fibonacci sequence](https://en.wikipedia.org/wiki/Fibonacci_sequence) - - -$$ F_n = F_{n-1} + F_{n-2} \quad \text{for} \quad n \geq 2 \quad \text{with} \quad F_0 = 0, \quad F_1 = 1$$ - -<!-- #endregion --> - -```python -def fibonacci(n): - """ - This function will return the n-th numbers of the fibonacci sequence - """ - #TODO: calculate the n-th number of the fibonacci sequence - return result - -# Asserts -assert fibonacci(0) == 0, f'Expected 0 but got {fibonacci(0)}' # This will throw an error if the result is incorrect -assert fibonacci(1) == 1, f'Expected 1 but got {fibonacci(1)}' # This will throw an error if the result is incorrect -assert fibonacci(2) == 1, f'Expected 1 but got {fibonacci(2)}' # This will throw an error if the result is incorrect -assert fibonacci(3) == 2, f'Expected 2 but got {fibonacci(3)}' # This will throw an error if the result is incorrect -``` - -```python -def fib_sequence(n): - """ - This function will return the first n numbers of the fibonacci sequence - """ - # result = #TODO: calculate the first n numbers of the fibonacci sequence - result = [0, 1] - if n == 0: - return [] - elif n == 1: - return [0] - for i in range(2, n): - result.append(result[-1] + result[-2]) - return result - -# Asserts -assert fib_sequence(0) == [], f'Expected [] but got {fib_sequence(0)}' # This will throw an error if the result is incorrect -assert fib_sequence(1) == [0], f'Expected [0] but got {fib_sequence(1)}' # This will throw an error if the result is incorrect -assert fib_sequence(2) == [0, 1], f'Expected [0, 1] but got {fib_sequence(2)}' # This will throw an error if the result is incorrect -assert fib_sequence(3) == [0, 1, 1], f'Expected [0, 1, 1] but got {fib_sequence(3)}' # This will throw an error if the result is incorrect -assert fib_sequence(4) == [0, 1, 1, 2], f'Expected [0, 1, 1, 2] but got {fib_sequence(4)}' # This will throw an error if the result is incorrect -assert fib_sequence(5) == [0, 1, 1, 2, 3], f'Expected [0, 1, 1, 2, 3] but got {fib_sequence(5)}' # This will throw an error if the result is incorrect - -``` - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Tutorials/Week_1_5/Tutorial.py b/synced_files/students/Tutorials/Week_1_5/Tutorial.py deleted file mode 100644 index 5d8ee6564e587c5d4df64b227a2a3aac47875f9a..0000000000000000000000000000000000000000 --- a/synced_files/students/Tutorials/Week_1_5/Tutorial.py +++ /dev/null @@ -1,183 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: TAMude -# language: python -# name: python3 -# --- - -# %% [markdown] -# # Week 1.5: Programming Tutorial -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.5. September 30, 2024.* -# -# _This notebook was prepared by Berend Bouvy and used in an in-class demonstration on Monday._ - -# %% [markdown] -# ## Objects - -# %% -import numpy as np -import matplotlib.pyplot as plt -import os - -# %% -# Objective: Create a variable of each type in Python -int_var = #TODO: create an integer variable -float_var = #TODO: create a float variable -bool_var = #TODO: create a boolean variable -str_var = #TODO: create a string variable -list_var = #TODO: create a list variable -tuple_var = #TODO: create a tuple variable -dict_var = #TODO: create a dictionary variable - - -# Asserts -assert type(int_var) == int, f'Expected int but got {type(int_var)}' # This will throw an error if the type is incorrect -assert type(float_var) == float, f'Expected float but got {type(float_var)}' # This will throw an error if the type is incorrect -assert type(bool_var) == bool, f'Expected bool but got {type(bool_var)}' # This will throw an error if the type is incorrect -assert type(str_var) == str, f'Expected str but got {type(str_var)}' # This will throw an error if the type is incorrect -assert type(list_var) == list, f'Expected list but got {type(list_var)}' # This will throw an error if the type is incorrect -assert type(tuple_var) == tuple, f'Expected tuple but got {type(tuple_var)}' # This will throw an error if the type is incorrect -assert type(dict_var) == dict, f'Expected dict but got {type(dict_var)}' # This will throw an error if the type is incorrect - - - - -# %% -# relative path vs absolute path -# relative path: relative to the current working directory -# absolute path: full path from the root directory - -# Create a variable that contains the current working directory using the os module -cwd = #TODO: get the current working directory -print(cwd) - -# Get all the files in the current working directory -files = #TODO: get all the files in the current working directory -print(files) - -# find path to data in data folder -data_dir = #TODO: find the path to the data folder -print(data_dir) - -# read the data using absolute path and relative path -data_abs = #TODO: read the data using absolute path -data_rel = #TODO: read the data using relative path - -# Asserts -assert data_abs == data_rel, 'Data read using absolute path and relative path are not the same' # This will throw an error if the data is not the same - - -# %% [markdown] -# $$ H_n = \sum_{k=1}^{n} \frac{1}{k} $$ - -# %% -def harmonic_series(n): - """ - This function calculates the harmonic series of n - """ - result = #TODO: calculate the harmonic series of n - return result - -# Plotting -n = 100 -x = #TODO: create a list of n values from 1 to n -y = #TODO: calculate the harmonic series of x, using list comprehension - -#TODO: plot x and y, with labels and title - -# asserts -assert harmonic_series(1) == 1, f'Expected 1 but got {harmonic_series(1)}' -assert harmonic_series(2) == 1.5, f'Expected 1.5 but got {harmonic_series(2)}' -assert harmonic_series(3) == 1.8333333333333333, f'Expected 1.8333333333333333 but got {harmonic_series(3)}' - -# save x, y data -data = #TODO: create a 2D array with x and y using np.column_stack() -#TODO: save data to a csv file - -# %% [markdown] -# [Wikipedia: Fibonacci sequence](https://en.wikipedia.org/wiki/Fibonacci_sequence) -# -# -# $$ F_n = F_{n-1} + F_{n-2} \quad \text{for} \quad n \geq 2 \quad \text{with} \quad F_0 = 0, \quad F_1 = 1$$ -# - -# %% -def fibonacci(n): - """ - This function will return the n-th numbers of the fibonacci sequence - """ - #TODO: calculate the n-th number of the fibonacci sequence - return result - -# Asserts -assert fibonacci(0) == 0, f'Expected 0 but got {fibonacci(0)}' # This will throw an error if the result is incorrect -assert fibonacci(1) == 1, f'Expected 1 but got {fibonacci(1)}' # This will throw an error if the result is incorrect -assert fibonacci(2) == 1, f'Expected 1 but got {fibonacci(2)}' # This will throw an error if the result is incorrect -assert fibonacci(3) == 2, f'Expected 2 but got {fibonacci(3)}' # This will throw an error if the result is incorrect - - -# %% -def fib_sequence(n): - """ - This function will return the first n numbers of the fibonacci sequence - """ - # result = #TODO: calculate the first n numbers of the fibonacci sequence - result = [0, 1] - if n == 0: - return [] - elif n == 1: - return [0] - for i in range(2, n): - result.append(result[-1] + result[-2]) - return result - -# Asserts -assert fib_sequence(0) == [], f'Expected [] but got {fib_sequence(0)}' # This will throw an error if the result is incorrect -assert fib_sequence(1) == [0], f'Expected [0] but got {fib_sequence(1)}' # This will throw an error if the result is incorrect -assert fib_sequence(2) == [0, 1], f'Expected [0, 1] but got {fib_sequence(2)}' # This will throw an error if the result is incorrect -assert fib_sequence(3) == [0, 1, 1], f'Expected [0, 1, 1] but got {fib_sequence(3)}' # This will throw an error if the result is incorrect -assert fib_sequence(4) == [0, 1, 1, 2], f'Expected [0, 1, 1, 2] but got {fib_sequence(4)}' # This will throw an error if the result is incorrect -assert fib_sequence(5) == [0, 1, 1, 2, 3], f'Expected [0, 1, 1, 2, 3] but got {fib_sequence(5)}' # This will throw an error if the result is incorrect - - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Tutorials/Week_1_6/Tutorial.ipynb b/synced_files/students/Tutorials/Week_1_6/Tutorial.ipynb deleted file mode 100644 index ab4a78fb12d5cfcf00593c7ed84f0171489fb688..0000000000000000000000000000000000000000 --- a/synced_files/students/Tutorials/Week_1_6/Tutorial.ipynb +++ /dev/null @@ -1,137 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Week 1.5: Programming Tutorial\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px\" />\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px\" />\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.6. October 7, 2024.*\n", - "\n", - "_This notebook was prepared by Berend Bouvy and used in an in-class demonstration on Monday._" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Objects" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "from func import *\n", - "import timeit" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# import data \n", - "data = np.loadtxt('data.txt')\n", - "x = data[:,0]\n", - "y = data[:,1]\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A = #TODO: create the matrix A\n", - "x_hat, y_hat = #TODO: solve the system of equations\n", - "print(f\"x_hat = {x_hat}\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# runtimes\n", - "\n", - "funcs = [FD_1, FD_2, FD_3, FD_4]\n", - "\n", - "assert np.allclose(funcs[0](x, y), funcs[1](x,y)), \"FD_1 and FD_2 are not equal\"\n", - "assert np.allclose(funcs[0](x, y), funcs[2](x,y)), \"FD_1 and FD_3 are not equal\"\n", - "assert np.allclose(funcs[0](x, y), funcs[3](x,y)), \"FD_1 and FD_4 are not equal\"\n", - "\n", - "runtime = np.zeros(4)\n", - "for i in range(4):\n", - " runtime[i] = timeit.timeit(lambda: funcs[i](x, y), number=1000)\n", - "\n", - "print(f\"runtimes: {runtime}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" />\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" />\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2024 <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">MUDE</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">CC BY 4.0 License</a>." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "TAMude", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.6" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/synced_files/students/Tutorials/Week_1_6/Tutorial.md b/synced_files/students/Tutorials/Week_1_6/Tutorial.md deleted file mode 100644 index 6dd601fdc2b50322b7a6b6a824c36d231919accd..0000000000000000000000000000000000000000 --- a/synced_files/students/Tutorials/Week_1_6/Tutorial.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: TAMude - language: python - name: python3 ---- - -# Week 1.5: Programming Tutorial - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.6. October 7, 2024.* - -_This notebook was prepared by Berend Bouvy and used in an in-class demonstration on Monday._ - - -## Objects - -```python -import numpy as np -import matplotlib.pyplot as plt -from func import * -import timeit -``` - -```python -# import data -data = np.loadtxt('data.txt') -x = data[:,0] -y = data[:,1] - -``` - -```python -A = #TODO: create the matrix A -x_hat, y_hat = #TODO: solve the system of equations -print(f"x_hat = {x_hat}") -``` - -```python -# runtimes - -funcs = [FD_1, FD_2, FD_3, FD_4] - -assert np.allclose(funcs[0](x, y), funcs[1](x,y)), "FD_1 and FD_2 are not equal" -assert np.allclose(funcs[0](x, y), funcs[2](x,y)), "FD_1 and FD_3 are not equal" -assert np.allclose(funcs[0](x, y), funcs[3](x,y)), "FD_1 and FD_4 are not equal" - -runtime = np.zeros(4) -for i in range(4): - runtime[i] = timeit.timeit(lambda: funcs[i](x, y), number=1000) - -print(f"runtimes: {runtime}") -``` - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Tutorials/Week_1_6/Tutorial.py b/synced_files/students/Tutorials/Week_1_6/Tutorial.py deleted file mode 100644 index 6e965dd95892ebdf0421f3d46ee407a75042b1b8..0000000000000000000000000000000000000000 --- a/synced_files/students/Tutorials/Week_1_6/Tutorial.py +++ /dev/null @@ -1,90 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: TAMude -# language: python -# name: python3 -# --- - -# %% [markdown] -# # Week 1.5: Programming Tutorial -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.6. October 7, 2024.* -# -# _This notebook was prepared by Berend Bouvy and used in an in-class demonstration on Monday._ - -# %% [markdown] -# ## Objects - -# %% -import numpy as np -import matplotlib.pyplot as plt -from func import * -import timeit - -# %% -# import data -data = np.loadtxt('data.txt') -x = data[:,0] -y = data[:,1] - - -# %% -A = #TODO: create the matrix A -x_hat, y_hat = #TODO: solve the system of equations -print(f"x_hat = {x_hat}") - -# %% -# runtimes - -funcs = [FD_1, FD_2, FD_3, FD_4] - -assert np.allclose(funcs[0](x, y), funcs[1](x,y)), "FD_1 and FD_2 are not equal" -assert np.allclose(funcs[0](x, y), funcs[2](x,y)), "FD_1 and FD_3 are not equal" -assert np.allclose(funcs[0](x, y), funcs[3](x,y)), "FD_1 and FD_4 are not equal" - -runtime = np.zeros(4) -for i in range(4): - runtime[i] = timeit.timeit(lambda: funcs[i](x, y), number=1000) - -print(f"runtimes: {runtime}") - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Week_1_2/PA_1_2_Random_Adventure.ipynb b/synced_files/students/Week_1_2/PA_1_2_Random_Adventure.ipynb deleted file mode 100644 index fbc542c70aa94b8b454b03426829316ef9483625..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_1_2/PA_1_2_Random_Adventure.ipynb +++ /dev/null @@ -1,770 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d14e9d93", - "metadata": {}, - "source": [ - "# PA 1.2: A Random Adventure\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px; height: auto; margin: 0\" />\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px; height: auto; margin: 0\" />\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.2. Due: before Friday, Sep 13, 2023.*\n", - "\n", - "*Note: you do not need to turn this assignment in (you will start doing this in Week 1.3).*" - ] - }, - { - "cell_type": "markdown", - "id": "2f465bec", - "metadata": { - "tags": [] - }, - "source": [ - "## Overview\n", - "\n", - "*This **Programming Assignment** is meant to introduce you to a few key concepts that we will use repeatedly in MUDE. If you are not familiar with them, please visit us in question hours to make sure you understand the concepts well and can apply them in the notebooks.*\n", - "\n", - "One of the main topics of this programming assignment is `numpy`, an essential Python package for scientific computation that facilitates, among other things: vector, matrix and linear algebra operations...in a computationally efficient way! **Note:** this assignment assumes you have a working knowledge of Python **lists**. if you aren't sure what a list is, please take some time to review this concept, perhaps [here](https://teachbooks.github.io/learn-python/main/01/In_a_Nutshell/01.html).\n", - "\n", - "Topics in this assignment include:\n", - "1. Basic matrix operations using numpy\n", - "2. Applying linear algebra to solve a line\n", - "3. Normal distributions\n", - "4. Modelling data with normal distributions\n", - "5. Using Markdown to write richly-formatted text" - ] - }, - { - "cell_type": "markdown", - "id": "34d8ecdd", - "metadata": {}, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\"> <p>For those of you that have never used Python before, or are very new to programming, this assignment will probably be difficult for you. Our intention is to make it obvious what concepts you do not know yet, so that you can ask a teacher (or perhaps a fellow student) for help. Thus, our advice is this: <em>write down all of the concepts and terms that are unfamiliar to you in this assignment and bring them with you to the Tuesday question hour to ask a teacher!</em> This will make it easier for us to help you, and point you to resources where you will be able to catch up with the programming concepts more quickly.</p></div>" - ] - }, - { - "cell_type": "markdown", - "id": "dec2b0c3", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 0:</b> \n", - "Run the following cell to import the Python packages required for this assignment. Be sure to select the <code>mude-base</code> environment, which should already have these packages installed.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a3cbf661", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "from scipy.stats import norm" - ] - }, - { - "cell_type": "markdown", - "id": "59cc6c0e", - "metadata": {}, - "source": [ - "## Task 1: Messing with numpy\n" - ] - }, - { - "cell_type": "markdown", - "id": "c378822c", - "metadata": {}, - "source": [ - "Numpy gives us lots of options for creating arrays, so we'll start by exploring some our main ones. It's worth nothing that a numpy array is an umbrella term for a vector **and** matrix. The easiest way to build a numpy array is to provide a list which represents the data of the array." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f4b81f9d", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Creating an array using lists\n", - "A = np.array([[1, 1], \n", - " [2, 2], \n", - " [3, 3], \n", - " [4, 4]])\n", - "A.shape" - ] - }, - { - "cell_type": "markdown", - "id": "40fa9153", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.1:</b> \n", - "Creating a 2x2 matrix called `scale` which scales the x and y axes by 2.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "81500cfe", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "scale = np.array([YOUR_CODE_HERE])" - ] - }, - { - "cell_type": "markdown", - "id": "66e96891", - "metadata": {}, - "source": [ - "We'll try to scale the data in `A` by `scale` using the cell below, but there seems to be an issue (running the cell should give an error)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "75a66301", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "A = A.T\n", - "scale @ A" - ] - }, - { - "cell_type": "markdown", - "id": "5e64e9a3", - "metadata": {}, - "source": [ - "The error message indicates that we have a mismatch in the dimensions of the arrays. `A` has a dimension of (4, 2) and `scale` has a dimension of (2, 2). Do those dimensions make sense to you? Try using the `shape` method of the arrays to print out this information for yourself, then complete Task 1.2 to try and complete the matrix computation." - ] - }, - { - "cell_type": "markdown", - "id": "4e1ec7d8", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.2:</b> \n", - " Let's treat <code>A</code> as a data array, where each column will be the x-y coordinates of a point. Transform the current <code>A</code> into this form. What you'll need to do is transpose it. Find out how to do so in as short a code as possible! Hint: look through the methods in the <a href=\"https://numpy.org/doc/stable/reference/generated/numpy.ndarray.transpose.html\" target=\"_blank\">numpy documentation</a>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fbc27304", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "A = YOUR_CODE_HERE" - ] - }, - { - "cell_type": "markdown", - "id": "7f9bba81", - "metadata": {}, - "source": [ - "Once you've done **Task 1.2**, re-run the cell that failed earlier. You should see each point has had both the x and y components multiplied by 2.\n", - "\n", - "We can also visualize our data as shown below. Numpy as allows you to index arrays in very complicated ways. For example `A[0, :]` returns an array with all the data from the first row. You can do much more as we'll see later. The documentation for this is found [here](https://numpy.org/doc/stable/user/basics.indexing.html)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "19530f80", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "plt.plot(A[0, :], A[1, :], 'ko') # Same as plt.plot(*A)\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "ad5527d6", - "metadata": {}, - "source": [ - "Let's look at some more ways to make arrays. The most basic ones, but very useful as `np.ones` and `np.zeros`, `np.linspace`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c21ad750", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "empty = np.zeros(shape=(2, 2))\n", - "shear = np.ones(shape=(2, 2))\n", - "\n", - "line_A_x = np.linspace(0, 8, num=10)\n", - "line_A = np.array([line_A_x, 5*line_A_x + 2])\n", - "\n", - "print(empty)\n", - "print()\n", - "print(shear)\n", - "print()\n", - "print(line_A)" - ] - }, - { - "cell_type": "markdown", - "id": "51ad0f20", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3:</b> \n", - "Mess around with the shape keyword argument in the code above to get a feel for what it does. How big can the tuple be? Then, try to generate more data points in <code>line_A</code>, but keeping the same range. Finally, see if you can manipulate the range of <code>line_A</code> and get the last value in the printed array to be 62.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "2eb2be84", - "metadata": {}, - "source": [ - "The `np.eye` function can be used to make a matrix with ones on a diagonal (by default the main diagonal)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2e600b81", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Generate scale through a different method\n", - "identity = np.eye(N = A.shape[0])\n", - "\n", - "# Check it's really identity\n", - "truth_array = identity @ A == A # This is actually an array with some boolean values\n", - "assert (identity @ A == A).all()\n", - "\n", - "# Making scale again:\n", - "scale_2 = 2 * identity\n", - "assert (scale_2 == scale).all()" - ] - }, - { - "cell_type": "markdown", - "id": "a08b2270", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.4:</b> \n", - "Can you understand what the code cell above is doing? You should be able to read and comprehend, but at the moment are not expected to create this exact code yet yourself in MUDE.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "87d14d63", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.5:</b> \n", - "As a final numpy recap exercise, define a matrix which reflects along the x=y axis and apply it to <code>line_A</code>. Plot it to check that it worked. Hint: first think of the reflection matrix, then find a way to implement it in code.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ed248194", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "reflect = np.array([[0, 1], [1, 0]])\n", - "result = YOUR_CODE_HERE\n", - "\n", - "plt.plot(*result, \"or\")\n", - "plt.plot(*line_A, \"ob\")\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "af69db9b", - "metadata": {}, - "source": [ - "## Task 2: Applying multiplication to solve lines" - ] - }, - { - "cell_type": "markdown", - "id": "1e707709", - "metadata": {}, - "source": [ - "Below you've been handed some code that generates the data for a line (with some random error), and a function which calculates the fit of the line using the `lstsq` function you encountered last week. Your task will be to write another function `fit_a_line_to_data_2` that has the same inputs as `fit_a_line_to_data`, but uses `np.linalg.solve` instead of `np.linalg.lstsq`. You'll find the following equation useful:\n", - "$$\n", - "A^\\intercal A x = A^\\intercal b\n", - "$$" - ] - }, - { - "cell_type": "markdown", - "id": "aab0e779", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.1:</b> \n", - "Research the difference between <code>np.linalg.lstsq</code> and <code>np.linalg.solve</code>. Consider when you can interchange them what their main differences are, then complete the function below using <code>np.linalg.solve</code>. The plot commands will help you confirm that your answer is correct: you'll see a red line show up on top of the black line. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a8dc6309", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "data_x = np.linspace(0, 100, num=100)\n", - "data_y = data_x * 5 + 2 + np.random.random(size = (100,))\n", - "\n", - "def fit_a_line_to_data(data_x, data_y):\n", - " A = np.array([data_x, np.ones(len(data_x))]).T\n", - " [slope, intercept], _, _, _ = np.linalg.lstsq(A, data_y, rcond=None)\n", - " return slope, intercept\n", - "\n", - "def fit_a_line_to_data_2(data_x, data_y):\n", - " ## Complete the function here ##\n", - " A = np.array([YOUR_CODE_HERE, np.ones(len(data_x))]).T\n", - " [slope, intercept] = np.linalg.solve(A.T @ A, YOUR_CODE_HERE)\n", - " return slope, intercept\n", - "\n", - "plt.plot(data_x, data_y, \"ok\")\n", - "\n", - "slope1, intercept1 = fit_a_line_to_data(data_x, data_y)\n", - "slope2, intercept2 = fit_a_line_to_data_2(data_x, data_y)\n", - "\n", - "plt.plot(data_x, slope1*data_x + intercept1, \"b\")\n", - "plt.plot(data_x, slope2*data_x + intercept2, \"r\")\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "5fc02d7d", - "metadata": {}, - "source": [ - "## Task 3: normal distribution basics" - ] - }, - { - "cell_type": "markdown", - "id": "5b027134", - "metadata": {}, - "source": [ - "As we discussed in lecture, it is important to have a variety of methods for quantifying uncertainty; one important type of uncertainty is aleatory: due to randomness. Numpy provides a simple way to generate random arrays (from a variety of distributions). For example, `np.random.random` us useful for making random data between 0 and 1 (a continuous Uniform distribution). Note how the code below creates a matrix filled with values, and they are evenly spread over the plot. This represents two random variables each with the standard uniform distribution." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "edebbab4", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "N = 1000\n", - "A = np.random.random(size = (2, N))\n", - "plt.plot(*A, \"ok\")\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "b0c7cfe0", - "metadata": {}, - "source": [ - "We will focus initially in MUDE on the Normal (or Gaussian) distribution, which is also easy to use with numpy, for example: `np.random.normal(loc=?, scale=?, size=(?, ?))`. In this case the `loc` abd `scale` arguments are the location and scale parameters, which are equivalent to the mean and standard deviation for this distribution (we will learn more about this in week 7)." - ] - }, - { - "cell_type": "markdown", - "id": "ae6f4d63", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 3.1:</b> \n", - " Using the examples above as a guide, create and plot a random sample of two normal distributions each with mean 10 and standard deviation 5.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3ac75364", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "A = np.random.normal(YOUR_CODE_HERE, YOUR_CODE_HERE, size = (2, N))\n", - "plt.plot(*A, \"ok\")\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "24f92d77", - "metadata": {}, - "source": [ - "The `norm` class in `scipy.stats` can also be used to model a normal distribution. It is more useful than the numpy methods because you can easily create an instance which has custom `loc` and `scale` parameters, and then call important methods like `X.cdf` and `X.pdf`. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "87046205", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "X = norm(loc = 0, scale = 1)\n", - "print(X.stats())" - ] - }, - { - "cell_type": "markdown", - "id": "58e14cd4", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 3.2:</b> \n", - " Use the <code>cdf</code> method to find P[X < 0].\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "565bd8ea", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "p_x_lt_0 = YOUR_CODE_HERE" - ] - }, - { - "cell_type": "markdown", - "id": "339c713f", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 3.3:</b> \n", - "Find P[X > 1].\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3442b197", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "p_x_gt_1 = YOUR_CODE_HERE" - ] - }, - { - "cell_type": "markdown", - "id": "1ae7cee6", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 3.4:</b> \n", - "Finally, use <code>linspace</code> and the <code>pdf</code> method to plot the distribution <code>X</code>.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "337c578f", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "x = np.linspace(-10, 10, num=1000)\n", - "plt.plot(YOUR_CODE_HERE, YOUR_CODE_HERE)\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "1300fd6a", - "metadata": {}, - "source": [ - "## Task 4: Application 1---Modelling with normal distributions\n", - "\n", - "In this Task we will combine several MUDE topics: modelling concepts, uncertainty, numpy arrays, a function of random variables and propagation of uncertainty. It may seem like a lot, but in the end you are only asked to make a few small changes to the code.\n", - "\n", - "In this Task one of the strategies to keep our code organized is to use **functions.** It is very useful to write simple functions to that can be used repeatedly in our analysis. In addition, it is important to recognize that rather than importing data we are *simulating* our own data using random samples from the normal distributions for length and width. Why? One reason is perhaps we already know what the distribution of values is, and we don't have enough measurements.\n", - "\n", - "Assume that the length and width each have a Normal distribution as follows:\n", - "$$\n", - "height \\sim \\mathcal{N}(5000, 25) \\\\\n", - "width \\sim \\mathcal{N}(2000, 100)\n", - "$$\n", - "\n", - "The exact steps for the Task are:\n", - "1. Create a random sample for two random variables: length and width of an object\n", - "2. Compute the output of the function of random variables: area\n", - "3. Plot the histogram of area\n", - "4. Compute the mean and standard deviation of area\n", - "5. Compute the PDF of area and add it to the histogram\n", - "\n", - "To facilitate this, we will start by writing **four functions** to automate the process. You will see the advantage of writing functions in the beginning of your code, because it makes the code much easier to write, run and interpret later! You may also want to refer to Chapters 1 and 3 of the [online Python course](https://teachbooks.github.io/learn-python/main/intro.html) to refresh your memory of functions." - ] - }, - { - "cell_type": "markdown", - "id": "63175d69", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 4.1:</b> \n", - " Complete the functions outlined in the code cells below. The function name and docstring should indicate what is required for each. You can also look at the code for Task 4.2 to see exactly how each function should be used.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "61eed80b", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "def create_sample(N):\n", - " \"Create N samples each of height and width.\"\n", - " height = np.array(norm.rvs(YOUR_CODE_HERE))\n", - " width = np.array(norm.rvs(YOUR_CODE_HERE))\n", - " return height, width\n", - "\n", - "def compute_area(height, width):\n", - " \"Compute the area of the rectangle.\"\n", - " return YOUR_CODE_HERE\n", - "\n", - "def area_mean_std(area_data):\n", - " \"Find the mean and std dev of the area.\"\n", - " area_mean = YOUR_CODE_HERE\n", - " area_std = YOUR_CODE_HERE\n", - " return area_mean, area_std\n", - "\n", - "def plot_data_and_pdf(data, mean, std):\n", - " \"Compare the histogram of data to a normal pdf defined by mean and std.\"\n", - " histogram_data = plt.hist(data, bins = 10,\n", - " density=True, stacked=True, edgecolor='black', linewidth=1.2)\n", - " x = np.linspace(min(histogram_data[1]), max(histogram_data[1]), num=1000)\n", - " area_norm = norm(loc=mean, scale=std)\n", - " plt.plot(x, YOUR_CODE_HERE, color='red', linewidth=2.0)\n", - " plt.title(\"\")\n", - " plt.xlabel(\"\")\n", - " plt.ylabel(\"\")\n", - " plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "0d96c24b", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 4.2:</b> \n", - " Run the cell below to see if your functions worked. The correct output will be a plot with histogram in blue and the PDF as a red line.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2d60bb8b", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "N = 500\n", - "height, width = create_sample(N)\n", - "area = compute_area(height, width)\n", - "area_mean, area_std = area_mean_std(area)\n", - "plot_data_and_pdf(area, area_mean, area_std)" - ] - }, - { - "cell_type": "markdown", - "id": "447e5033", - "metadata": {}, - "source": [ - "## Task 5: Reporting your Results with Markdown\n", - "\n", - "Now we would like to quickly communicate our results; imagine you will be sending this notebook to a classmate or a teacher and you really want them to be able to see the final answer easily, while also being able to understand how you arrived at it. We can do this quick easily using Markdown cells in the notebook (of course if you haven't realized it yet, this cell you are reading is a Markdown cell).\n", - "\n", - "Markdown is a _markup language_ that makes it possible to write richly-formatted text in Jupyter notebooks (see the course website for more information and examples). We will use Markdown on a weekly basis in our MUDE project reports, so this is a good chance to use it for the first time, if you never have. Use the cell below to write your answer to Q1, using the following formatting tips:\n", - "- Write out lists by beginning the line with a hyphen `- my item`, or a number and dot `1. first item`\n", - "- You make text **bold** by using `**double asterisk**` and *italics* with `*one asterisk*`.\n", - "- `Highlight` code-related words or other important concepts using back-ticks `` `like this` ``\n", - "```python\n", - "message=\"You can also make multi-line code blocks with three back-ticks\n", - "extra_message=\"Provide a language after the first backticks to get syntax highlighting\n", - "# e.g. \n", - "#```python\n", - "# this explanation\n", - "# ```\n", - "print(message)\n", - "print(extra_message)\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "c11a5654", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 5:</b> \n", - "Use the Markdown cell below to document your answer from the previous tasks; try to use as many Markdown elements as possible. For example, describe the mean, explain what the figure shows, list a few observations, describe the code you wrote, etc..\n", - "<br><br>Note that there is no \"wrong\" answer here: as long as you feel comfortable with Markdown you can move on, comfortable you will be ready for the Group Assignment this Friday.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "4f0eac5e", - "metadata": {}, - "source": [ - "Write your Markdown **here!**" - ] - }, - { - "cell_type": "markdown", - "id": "ef45c1a7", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" />\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" />\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2024 <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">MUDE</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">CC BY 4.0 License</a>." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.4" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/synced_files/students/Week_1_2/PA_1_2_Random_Adventure.md b/synced_files/students/Week_1_2/PA_1_2_Random_Adventure.md deleted file mode 100644 index 118c72ae385fecfa821784e4d449b61cf54b518e..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_1_2/PA_1_2_Random_Adventure.md +++ /dev/null @@ -1,420 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -# PA 1.2: A Random Adventure - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px; height: auto; margin: 0" /> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px; height: auto; margin: 0" /> -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.2. Due: before Friday, Sep 13, 2023.* - -*Note: you do not need to turn this assignment in (you will start doing this in Week 1.3).* - - -## Overview - -*This **Programming Assignment** is meant to introduce you to a few key concepts that we will use repeatedly in MUDE. If you are not familiar with them, please visit us in question hours to make sure you understand the concepts well and can apply them in the notebooks.* - -One of the main topics of this programming assignment is `numpy`, an essential Python package for scientific computation that facilitates, among other things: vector, matrix and linear algebra operations...in a computationally efficient way! **Note:** this assignment assumes you have a working knowledge of Python **lists**. if you aren't sure what a list is, please take some time to review this concept, perhaps [here](https://teachbooks.github.io/learn-python/main/01/In_a_Nutshell/01.html). - -Topics in this assignment include: -1. Basic matrix operations using numpy -2. Applying linear algebra to solve a line -3. Normal distributions -4. Modelling data with normal distributions -5. Using Markdown to write richly-formatted text - - -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>For those of you that have never used Python before, or are very new to programming, this assignment will probably be difficult for you. Our intention is to make it obvious what concepts you do not know yet, so that you can ask a teacher (or perhaps a fellow student) for help. Thus, our advice is this: <em>write down all of the concepts and terms that are unfamiliar to you in this assignment and bring them with you to the Tuesday question hour to ask a teacher!</em> This will make it easier for us to help you, and point you to resources where you will be able to catch up with the programming concepts more quickly.</p></div> - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 0:</b> -Run the following cell to import the Python packages required for this assignment. Be sure to select the <code>mude-base</code> environment, which should already have these packages installed. -</p> -</div> - -```python -import numpy as np -import matplotlib.pyplot as plt -from scipy.stats import norm -``` - -## Task 1: Messing with numpy - - - -Numpy gives us lots of options for creating arrays, so we'll start by exploring some our main ones. It's worth nothing that a numpy array is an umbrella term for a vector **and** matrix. The easiest way to build a numpy array is to provide a list which represents the data of the array. - -```python -# Creating an array using lists -A = np.array([[1, 1], - [2, 2], - [3, 3], - [4, 4]]) -A.shape -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.1:</b> -Creating a 2x2 matrix called `scale` which scales the x and y axes by 2. -</p> -</div> - -```python -scale = np.array([YOUR_CODE_HERE]) -``` - -We'll try to scale the data in `A` by `scale` using the cell below, but there seems to be an issue (running the cell should give an error). - -```python -A = A.T -scale @ A -``` - -The error message indicates that we have a mismatch in the dimensions of the arrays. `A` has a dimension of (4, 2) and `scale` has a dimension of (2, 2). Do those dimensions make sense to you? Try using the `shape` method of the arrays to print out this information for yourself, then complete Task 1.2 to try and complete the matrix computation. - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.2:</b> - Let's treat <code>A</code> as a data array, where each column will be the x-y coordinates of a point. Transform the current <code>A</code> into this form. What you'll need to do is transpose it. Find out how to do so in as short a code as possible! Hint: look through the methods in the <a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.transpose.html" target="_blank">numpy documentation</a> -</p> -</div> - -```python -A = YOUR_CODE_HERE -``` - -Once you've done **Task 1.2**, re-run the cell that failed earlier. You should see each point has had both the x and y components multiplied by 2. - -We can also visualize our data as shown below. Numpy as allows you to index arrays in very complicated ways. For example `A[0, :]` returns an array with all the data from the first row. You can do much more as we'll see later. The documentation for this is found [here](https://numpy.org/doc/stable/user/basics.indexing.html). - -```python -plt.plot(A[0, :], A[1, :], 'ko') # Same as plt.plot(*A) -plt.show() -``` - -Let's look at some more ways to make arrays. The most basic ones, but very useful as `np.ones` and `np.zeros`, `np.linspace`. - -```python -empty = np.zeros(shape=(2, 2)) -shear = np.ones(shape=(2, 2)) - -line_A_x = np.linspace(0, 8, num=10) -line_A = np.array([line_A_x, 5*line_A_x + 2]) - -print(empty) -print() -print(shear) -print() -print(line_A) -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3:</b> -Mess around with the shape keyword argument in the code above to get a feel for what it does. How big can the tuple be? Then, try to generate more data points in <code>line_A</code>, but keeping the same range. Finally, see if you can manipulate the range of <code>line_A</code> and get the last value in the printed array to be 62. -</p> -</div> - - -The `np.eye` function can be used to make a matrix with ones on a diagonal (by default the main diagonal) - -```python -# Generate scale through a different method -identity = np.eye(N = A.shape[0]) - -# Check it's really identity -truth_array = identity @ A == A # This is actually an array with some boolean values -assert (identity @ A == A).all() - -# Making scale again: -scale_2 = 2 * identity -assert (scale_2 == scale).all() -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.4:</b> -Can you understand what the code cell above is doing? You should be able to read and comprehend, but at the moment are not expected to create this exact code yet yourself in MUDE. -</p> -</div> - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.5:</b> -As a final numpy recap exercise, define a matrix which reflects along the x=y axis and apply it to <code>line_A</code>. Plot it to check that it worked. Hint: first think of the reflection matrix, then find a way to implement it in code. -</p> -</div> - -```python -reflect = np.array([[0, 1], [1, 0]]) -result = YOUR_CODE_HERE - -plt.plot(*result, "or") -plt.plot(*line_A, "ob") -plt.show() -``` - -## Task 2: Applying multiplication to solve lines - - -Below you've been handed some code that generates the data for a line (with some random error), and a function which calculates the fit of the line using the `lstsq` function you encountered last week. Your task will be to write another function `fit_a_line_to_data_2` that has the same inputs as `fit_a_line_to_data`, but uses `np.linalg.solve` instead of `np.linalg.lstsq`. You'll find the following equation useful: -$$ -A^\intercal A x = A^\intercal b -$$ - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.1:</b> -Research the difference between <code>np.linalg.lstsq</code> and <code>np.linalg.solve</code>. Consider when you can interchange them what their main differences are, then complete the function below using <code>np.linalg.solve</code>. The plot commands will help you confirm that your answer is correct: you'll see a red line show up on top of the black line. -</p> -</div> - -```python -data_x = np.linspace(0, 100, num=100) -data_y = data_x * 5 + 2 + np.random.random(size = (100,)) - -def fit_a_line_to_data(data_x, data_y): - A = np.array([data_x, np.ones(len(data_x))]).T - [slope, intercept], _, _, _ = np.linalg.lstsq(A, data_y, rcond=None) - return slope, intercept - -def fit_a_line_to_data_2(data_x, data_y): - ## Complete the function here ## - A = np.array([YOUR_CODE_HERE, np.ones(len(data_x))]).T - [slope, intercept] = np.linalg.solve(A.T @ A, YOUR_CODE_HERE) - return slope, intercept - -plt.plot(data_x, data_y, "ok") - -slope1, intercept1 = fit_a_line_to_data(data_x, data_y) -slope2, intercept2 = fit_a_line_to_data_2(data_x, data_y) - -plt.plot(data_x, slope1*data_x + intercept1, "b") -plt.plot(data_x, slope2*data_x + intercept2, "r") -plt.show() -``` - -## Task 3: normal distribution basics - - -As we discussed in lecture, it is important to have a variety of methods for quantifying uncertainty; one important type of uncertainty is aleatory: due to randomness. Numpy provides a simple way to generate random arrays (from a variety of distributions). For example, `np.random.random` us useful for making random data between 0 and 1 (a continuous Uniform distribution). Note how the code below creates a matrix filled with values, and they are evenly spread over the plot. This represents two random variables each with the standard uniform distribution. - -```python -N = 1000 -A = np.random.random(size = (2, N)) -plt.plot(*A, "ok") -plt.show() -``` - -We will focus initially in MUDE on the Normal (or Gaussian) distribution, which is also easy to use with numpy, for example: `np.random.normal(loc=?, scale=?, size=(?, ?))`. In this case the `loc` abd `scale` arguments are the location and scale parameters, which are equivalent to the mean and standard deviation for this distribution (we will learn more about this in week 7). - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 3.1:</b> - Using the examples above as a guide, create and plot a random sample of two normal distributions each with mean 10 and standard deviation 5. -</p> -</div> - -```python -A = np.random.normal(YOUR_CODE_HERE, YOUR_CODE_HERE, size = (2, N)) -plt.plot(*A, "ok") -plt.show() -``` - -The `norm` class in `scipy.stats` can also be used to model a normal distribution. It is more useful than the numpy methods because you can easily create an instance which has custom `loc` and `scale` parameters, and then call important methods like `X.cdf` and `X.pdf`. - -```python -X = norm(loc = 0, scale = 1) -print(X.stats()) -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 3.2:</b> - Use the <code>cdf</code> method to find P[X < 0]. -</p> -</div> - -```python -p_x_lt_0 = YOUR_CODE_HERE -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 3.3:</b> -Find P[X > 1]. -</p> -</div> - -```python -p_x_gt_1 = YOUR_CODE_HERE -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 3.4:</b> -Finally, use <code>linspace</code> and the <code>pdf</code> method to plot the distribution <code>X</code>. -</p> -</div> - -```python -x = np.linspace(-10, 10, num=1000) -plt.plot(YOUR_CODE_HERE, YOUR_CODE_HERE) -plt.show() -``` - -## Task 4: Application 1---Modelling with normal distributions - -In this Task we will combine several MUDE topics: modelling concepts, uncertainty, numpy arrays, a function of random variables and propagation of uncertainty. It may seem like a lot, but in the end you are only asked to make a few small changes to the code. - -In this Task one of the strategies to keep our code organized is to use **functions.** It is very useful to write simple functions to that can be used repeatedly in our analysis. In addition, it is important to recognize that rather than importing data we are *simulating* our own data using random samples from the normal distributions for length and width. Why? One reason is perhaps we already know what the distribution of values is, and we don't have enough measurements. - -Assume that the length and width each have a Normal distribution as follows: -$$ -height \sim \mathcal{N}(5000, 25) \\ -width \sim \mathcal{N}(2000, 100) -$$ - -The exact steps for the Task are: -1. Create a random sample for two random variables: length and width of an object -2. Compute the output of the function of random variables: area -3. Plot the histogram of area -4. Compute the mean and standard deviation of area -5. Compute the PDF of area and add it to the histogram - -To facilitate this, we will start by writing **four functions** to automate the process. You will see the advantage of writing functions in the beginning of your code, because it makes the code much easier to write, run and interpret later! You may also want to refer to Chapters 1 and 3 of the [online Python course](https://teachbooks.github.io/learn-python/main/intro.html) to refresh your memory of functions. - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 4.1:</b> - Complete the functions outlined in the code cells below. The function name and docstring should indicate what is required for each. You can also look at the code for Task 4.2 to see exactly how each function should be used. -</p> -</div> - -```python -def create_sample(N): - "Create N samples each of height and width." - height = np.array(norm.rvs(YOUR_CODE_HERE)) - width = np.array(norm.rvs(YOUR_CODE_HERE)) - return height, width - -def compute_area(height, width): - "Compute the area of the rectangle." - return YOUR_CODE_HERE - -def area_mean_std(area_data): - "Find the mean and std dev of the area." - area_mean = YOUR_CODE_HERE - area_std = YOUR_CODE_HERE - return area_mean, area_std - -def plot_data_and_pdf(data, mean, std): - "Compare the histogram of data to a normal pdf defined by mean and std." - histogram_data = plt.hist(data, bins = 10, - density=True, stacked=True, edgecolor='black', linewidth=1.2) - x = np.linspace(min(histogram_data[1]), max(histogram_data[1]), num=1000) - area_norm = norm(loc=mean, scale=std) - plt.plot(x, YOUR_CODE_HERE, color='red', linewidth=2.0) - plt.title("") - plt.xlabel("") - plt.ylabel("") - plt.show() -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 4.2:</b> - Run the cell below to see if your functions worked. The correct output will be a plot with histogram in blue and the PDF as a red line. -</p> -</div> - -```python -N = 500 -height, width = create_sample(N) -area = compute_area(height, width) -area_mean, area_std = area_mean_std(area) -plot_data_and_pdf(area, area_mean, area_std) -``` - -<!-- #region --> -## Task 5: Reporting your Results with Markdown - -Now we would like to quickly communicate our results; imagine you will be sending this notebook to a classmate or a teacher and you really want them to be able to see the final answer easily, while also being able to understand how you arrived at it. We can do this quick easily using Markdown cells in the notebook (of course if you haven't realized it yet, this cell you are reading is a Markdown cell). - -Markdown is a _markup language_ that makes it possible to write richly-formatted text in Jupyter notebooks (see the course website for more information and examples). We will use Markdown on a weekly basis in our MUDE project reports, so this is a good chance to use it for the first time, if you never have. Use the cell below to write your answer to Q1, using the following formatting tips: -- Write out lists by beginning the line with a hyphen `- my item`, or a number and dot `1. first item` -- You make text **bold** by using `**double asterisk**` and *italics* with `*one asterisk*`. -- `Highlight` code-related words or other important concepts using back-ticks `` `like this` `` -```python -message="You can also make multi-line code blocks with three back-ticks -extra_message="Provide a language after the first backticks to get syntax highlighting -# e.g. -#```python -# this explanation -# ``` -print(message) -print(extra_message) -``` -<!-- #endregion --> - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 5:</b> -Use the Markdown cell below to document your answer from the previous tasks; try to use as many Markdown elements as possible. For example, describe the mean, explain what the figure shows, list a few observations, describe the code you wrote, etc.. -<br><br>Note that there is no "wrong" answer here: as long as you feel comfortable with Markdown you can move on, comfortable you will be ready for the Group Assignment this Friday. -</p> -</div> - - -Write your Markdown **here!** - - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Week_1_2/PA_1_2_Random_Adventure.py b/synced_files/students/Week_1_2/PA_1_2_Random_Adventure.py deleted file mode 100644 index 051f0a95cf7d52af1c71edff3165913aa091f4c3..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_1_2/PA_1_2_Random_Adventure.py +++ /dev/null @@ -1,422 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: Python 3 (ipykernel) -# language: python -# name: python3 -# --- - -# %% [markdown] -# # PA 1.2: A Random Adventure -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px; height: auto; margin: 0" /> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px; height: auto; margin: 0" /> -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.2. Due: before Friday, Sep 13, 2023.* -# -# *Note: you do not need to turn this assignment in (you will start doing this in Week 1.3).* - -# %% [markdown] -# ## Overview -# -# *This **Programming Assignment** is meant to introduce you to a few key concepts that we will use repeatedly in MUDE. If you are not familiar with them, please visit us in question hours to make sure you understand the concepts well and can apply them in the notebooks.* -# -# One of the main topics of this programming assignment is `numpy`, an essential Python package for scientific computation that facilitates, among other things: vector, matrix and linear algebra operations...in a computationally efficient way! **Note:** this assignment assumes you have a working knowledge of Python **lists**. if you aren't sure what a list is, please take some time to review this concept, perhaps [here](https://teachbooks.github.io/learn-python/main/01/In_a_Nutshell/01.html). -# -# Topics in this assignment include: -# 1. Basic matrix operations using numpy -# 2. Applying linear algebra to solve a line -# 3. Normal distributions -# 4. Modelling data with normal distributions -# 5. Using Markdown to write richly-formatted text - -# %% [markdown] -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>For those of you that have never used Python before, or are very new to programming, this assignment will probably be difficult for you. Our intention is to make it obvious what concepts you do not know yet, so that you can ask a teacher (or perhaps a fellow student) for help. Thus, our advice is this: <em>write down all of the concepts and terms that are unfamiliar to you in this assignment and bring them with you to the Tuesday question hour to ask a teacher!</em> This will make it easier for us to help you, and point you to resources where you will be able to catch up with the programming concepts more quickly.</p></div> - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 0:</b> -# Run the following cell to import the Python packages required for this assignment. Be sure to select the <code>mude-base</code> environment, which should already have these packages installed. -# </p> -# </div> - -# %% -import numpy as np -import matplotlib.pyplot as plt -from scipy.stats import norm - -# %% [markdown] -# ## Task 1: Messing with numpy -# - -# %% [markdown] -# Numpy gives us lots of options for creating arrays, so we'll start by exploring some our main ones. It's worth nothing that a numpy array is an umbrella term for a vector **and** matrix. The easiest way to build a numpy array is to provide a list which represents the data of the array. - -# %% -# Creating an array using lists -A = np.array([[1, 1], - [2, 2], - [3, 3], - [4, 4]]) -A.shape - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.1:</b> -# Creating a 2x2 matrix called `scale` which scales the x and y axes by 2. -# </p> -# </div> - -# %% -scale = np.array([YOUR_CODE_HERE]) - -# %% [markdown] -# We'll try to scale the data in `A` by `scale` using the cell below, but there seems to be an issue (running the cell should give an error). - -# %% -A = A.T -scale @ A - -# %% [markdown] -# The error message indicates that we have a mismatch in the dimensions of the arrays. `A` has a dimension of (4, 2) and `scale` has a dimension of (2, 2). Do those dimensions make sense to you? Try using the `shape` method of the arrays to print out this information for yourself, then complete Task 1.2 to try and complete the matrix computation. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.2:</b> -# Let's treat <code>A</code> as a data array, where each column will be the x-y coordinates of a point. Transform the current <code>A</code> into this form. What you'll need to do is transpose it. Find out how to do so in as short a code as possible! Hint: look through the methods in the <a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.transpose.html" target="_blank">numpy documentation</a> -# </p> -# </div> - -# %% -A = YOUR_CODE_HERE - -# %% [markdown] -# Once you've done **Task 1.2**, re-run the cell that failed earlier. You should see each point has had both the x and y components multiplied by 2. -# -# We can also visualize our data as shown below. Numpy as allows you to index arrays in very complicated ways. For example `A[0, :]` returns an array with all the data from the first row. You can do much more as we'll see later. The documentation for this is found [here](https://numpy.org/doc/stable/user/basics.indexing.html). - -# %% -plt.plot(A[0, :], A[1, :], 'ko') # Same as plt.plot(*A) -plt.show() - -# %% [markdown] -# Let's look at some more ways to make arrays. The most basic ones, but very useful as `np.ones` and `np.zeros`, `np.linspace`. - -# %% -empty = np.zeros(shape=(2, 2)) -shear = np.ones(shape=(2, 2)) - -line_A_x = np.linspace(0, 8, num=10) -line_A = np.array([line_A_x, 5*line_A_x + 2]) - -print(empty) -print() -print(shear) -print() -print(line_A) - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3:</b> -# Mess around with the shape keyword argument in the code above to get a feel for what it does. How big can the tuple be? Then, try to generate more data points in <code>line_A</code>, but keeping the same range. Finally, see if you can manipulate the range of <code>line_A</code> and get the last value in the printed array to be 62. -# </p> -# </div> - -# %% [markdown] -# The `np.eye` function can be used to make a matrix with ones on a diagonal (by default the main diagonal) - -# %% -# Generate scale through a different method -identity = np.eye(N = A.shape[0]) - -# Check it's really identity -truth_array = identity @ A == A # This is actually an array with some boolean values -assert (identity @ A == A).all() - -# Making scale again: -scale_2 = 2 * identity -assert (scale_2 == scale).all() - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.4:</b> -# Can you understand what the code cell above is doing? You should be able to read and comprehend, but at the moment are not expected to create this exact code yet yourself in MUDE. -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.5:</b> -# As a final numpy recap exercise, define a matrix which reflects along the x=y axis and apply it to <code>line_A</code>. Plot it to check that it worked. Hint: first think of the reflection matrix, then find a way to implement it in code. -# </p> -# </div> - -# %% -reflect = np.array([[0, 1], [1, 0]]) -result = YOUR_CODE_HERE - -plt.plot(*result, "or") -plt.plot(*line_A, "ob") -plt.show() - -# %% [markdown] -# ## Task 2: Applying multiplication to solve lines - -# %% [markdown] -# Below you've been handed some code that generates the data for a line (with some random error), and a function which calculates the fit of the line using the `lstsq` function you encountered last week. Your task will be to write another function `fit_a_line_to_data_2` that has the same inputs as `fit_a_line_to_data`, but uses `np.linalg.solve` instead of `np.linalg.lstsq`. You'll find the following equation useful: -# $$ -# A^\intercal A x = A^\intercal b -# $$ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.1:</b> -# Research the difference between <code>np.linalg.lstsq</code> and <code>np.linalg.solve</code>. Consider when you can interchange them what their main differences are, then complete the function below using <code>np.linalg.solve</code>. The plot commands will help you confirm that your answer is correct: you'll see a red line show up on top of the black line. -# </p> -# </div> - -# %% -data_x = np.linspace(0, 100, num=100) -data_y = data_x * 5 + 2 + np.random.random(size = (100,)) - -def fit_a_line_to_data(data_x, data_y): - A = np.array([data_x, np.ones(len(data_x))]).T - [slope, intercept], _, _, _ = np.linalg.lstsq(A, data_y, rcond=None) - return slope, intercept - -def fit_a_line_to_data_2(data_x, data_y): - ## Complete the function here ## - A = np.array([YOUR_CODE_HERE, np.ones(len(data_x))]).T - [slope, intercept] = np.linalg.solve(A.T @ A, YOUR_CODE_HERE) - return slope, intercept - -plt.plot(data_x, data_y, "ok") - -slope1, intercept1 = fit_a_line_to_data(data_x, data_y) -slope2, intercept2 = fit_a_line_to_data_2(data_x, data_y) - -plt.plot(data_x, slope1*data_x + intercept1, "b") -plt.plot(data_x, slope2*data_x + intercept2, "r") -plt.show() - -# %% [markdown] -# ## Task 3: normal distribution basics - -# %% [markdown] -# As we discussed in lecture, it is important to have a variety of methods for quantifying uncertainty; one important type of uncertainty is aleatory: due to randomness. Numpy provides a simple way to generate random arrays (from a variety of distributions). For example, `np.random.random` us useful for making random data between 0 and 1 (a continuous Uniform distribution). Note how the code below creates a matrix filled with values, and they are evenly spread over the plot. This represents two random variables each with the standard uniform distribution. - -# %% -N = 1000 -A = np.random.random(size = (2, N)) -plt.plot(*A, "ok") -plt.show() - -# %% [markdown] -# We will focus initially in MUDE on the Normal (or Gaussian) distribution, which is also easy to use with numpy, for example: `np.random.normal(loc=?, scale=?, size=(?, ?))`. In this case the `loc` abd `scale` arguments are the location and scale parameters, which are equivalent to the mean and standard deviation for this distribution (we will learn more about this in week 7). - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 3.1:</b> -# Using the examples above as a guide, create and plot a random sample of two normal distributions each with mean 10 and standard deviation 5. -# </p> -# </div> - -# %% -A = np.random.normal(YOUR_CODE_HERE, YOUR_CODE_HERE, size = (2, N)) -plt.plot(*A, "ok") -plt.show() - -# %% [markdown] -# The `norm` class in `scipy.stats` can also be used to model a normal distribution. It is more useful than the numpy methods because you can easily create an instance which has custom `loc` and `scale` parameters, and then call important methods like `X.cdf` and `X.pdf`. - -# %% -X = norm(loc = 0, scale = 1) -print(X.stats()) - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 3.2:</b> -# Use the <code>cdf</code> method to find P[X < 0]. -# </p> -# </div> - -# %% -p_x_lt_0 = YOUR_CODE_HERE - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 3.3:</b> -# Find P[X > 1]. -# </p> -# </div> - -# %% -p_x_gt_1 = YOUR_CODE_HERE - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 3.4:</b> -# Finally, use <code>linspace</code> and the <code>pdf</code> method to plot the distribution <code>X</code>. -# </p> -# </div> - -# %% -x = np.linspace(-10, 10, num=1000) -plt.plot(YOUR_CODE_HERE, YOUR_CODE_HERE) -plt.show() - - -# %% [markdown] -# ## Task 4: Application 1---Modelling with normal distributions -# -# In this Task we will combine several MUDE topics: modelling concepts, uncertainty, numpy arrays, a function of random variables and propagation of uncertainty. It may seem like a lot, but in the end you are only asked to make a few small changes to the code. -# -# In this Task one of the strategies to keep our code organized is to use **functions.** It is very useful to write simple functions to that can be used repeatedly in our analysis. In addition, it is important to recognize that rather than importing data we are *simulating* our own data using random samples from the normal distributions for length and width. Why? One reason is perhaps we already know what the distribution of values is, and we don't have enough measurements. -# -# Assume that the length and width each have a Normal distribution as follows: -# $$ -# height \sim \mathcal{N}(5000, 25) \\ -# width \sim \mathcal{N}(2000, 100) -# $$ -# -# The exact steps for the Task are: -# 1. Create a random sample for two random variables: length and width of an object -# 2. Compute the output of the function of random variables: area -# 3. Plot the histogram of area -# 4. Compute the mean and standard deviation of area -# 5. Compute the PDF of area and add it to the histogram -# -# To facilitate this, we will start by writing **four functions** to automate the process. You will see the advantage of writing functions in the beginning of your code, because it makes the code much easier to write, run and interpret later! You may also want to refer to Chapters 1 and 3 of the [online Python course](https://teachbooks.github.io/learn-python/main/intro.html) to refresh your memory of functions. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 4.1:</b> -# Complete the functions outlined in the code cells below. The function name and docstring should indicate what is required for each. You can also look at the code for Task 4.2 to see exactly how each function should be used. -# </p> -# </div> - -# %% -def create_sample(N): - "Create N samples each of height and width." - height = np.array(norm.rvs(YOUR_CODE_HERE)) - width = np.array(norm.rvs(YOUR_CODE_HERE)) - return height, width - -def compute_area(height, width): - "Compute the area of the rectangle." - return YOUR_CODE_HERE - -def area_mean_std(area_data): - "Find the mean and std dev of the area." - area_mean = YOUR_CODE_HERE - area_std = YOUR_CODE_HERE - return area_mean, area_std - -def plot_data_and_pdf(data, mean, std): - "Compare the histogram of data to a normal pdf defined by mean and std." - histogram_data = plt.hist(data, bins = 10, - density=True, stacked=True, edgecolor='black', linewidth=1.2) - x = np.linspace(min(histogram_data[1]), max(histogram_data[1]), num=1000) - area_norm = norm(loc=mean, scale=std) - plt.plot(x, YOUR_CODE_HERE, color='red', linewidth=2.0) - plt.title("") - plt.xlabel("") - plt.ylabel("") - plt.show() - - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 4.2:</b> -# Run the cell below to see if your functions worked. The correct output will be a plot with histogram in blue and the PDF as a red line. -# </p> -# </div> - -# %% -N = 500 -height, width = create_sample(N) -area = compute_area(height, width) -area_mean, area_std = area_mean_std(area) -plot_data_and_pdf(area, area_mean, area_std) - -# %% [markdown] -# ## Task 5: Reporting your Results with Markdown -# -# Now we would like to quickly communicate our results; imagine you will be sending this notebook to a classmate or a teacher and you really want them to be able to see the final answer easily, while also being able to understand how you arrived at it. We can do this quick easily using Markdown cells in the notebook (of course if you haven't realized it yet, this cell you are reading is a Markdown cell). -# -# Markdown is a _markup language_ that makes it possible to write richly-formatted text in Jupyter notebooks (see the course website for more information and examples). We will use Markdown on a weekly basis in our MUDE project reports, so this is a good chance to use it for the first time, if you never have. Use the cell below to write your answer to Q1, using the following formatting tips: -# - Write out lists by beginning the line with a hyphen `- my item`, or a number and dot `1. first item` -# - You make text **bold** by using `**double asterisk**` and *italics* with `*one asterisk*`. -# - `Highlight` code-related words or other important concepts using back-ticks `` `like this` `` -# ```python -# message="You can also make multi-line code blocks with three back-ticks -# extra_message="Provide a language after the first backticks to get syntax highlighting -# # e.g. -# #```python -# # this explanation -# # ``` -# print(message) -# print(extra_message) -# ``` - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 5:</b> -# Use the Markdown cell below to document your answer from the previous tasks; try to use as many Markdown elements as possible. For example, describe the mean, explain what the figure shows, list a few observations, describe the code you wrote, etc.. -# <br><br>Note that there is no "wrong" answer here: as long as you feel comfortable with Markdown you can move on, comfortable you will be ready for the Group Assignment this Friday. -# </p> -# </div> - -# %% [markdown] -# Write your Markdown **here!** - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Week_1_2/WS_1_2_Pipe_Dreams.ipynb b/synced_files/students/Week_1_2/WS_1_2_Pipe_Dreams.ipynb deleted file mode 100644 index a6d202951ea31175830f26dea6e5cf86025333af..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_1_2/WS_1_2_Pipe_Dreams.ipynb +++ /dev/null @@ -1,762 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "9adbf457-797f-45b7-8f8b-0e46e0e2f5ff", - "metadata": { - "id": "9adbf457-797f-45b7-8f8b-0e46e0e2f5ff" - }, - "source": [ - "# WS 1.2: Mean and Variance Propagation\n", - "\n", - "**Sewer Pipe Flow Velocity**\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px; height: auto; margin: 0\" />\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px; height: auto; margin: 0\" />\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.2. Wed Sep 11, 2024.*" - ] - }, - { - "cell_type": "markdown", - "id": "1db6fea9-f3ad-44bc-a4c8-7b2b3008e945", - "metadata": { - "id": "1db6fea9-f3ad-44bc-a4c8-7b2b3008e945" - }, - "source": [ - "## Overview\n", - "\n", - "In this notebook you will apply the propagation laws for the mean and variance for a function of two independent random variables. You will assess how well the approximations correspond with the <em>simulation-based</em> equivalents. You will also assess the distribution of the function.\n", - "\n", - "_You do not need to turn in this notebook._\n", - "\n", - "### Objectives\n", - "\n", - "1. Observe how uncertainty \"propagates\" from the inputs to the output of a function by estimating moments of the function of random variables and seeing how they change relative to the moments of the input random variables.\n", - "2. Recognize that a non-linear function of random variables that have the (joint) Normal distribution (the inputs) produces a non-Normal random variable (the output).\n", - "3. Using _sampling_ (Monte Carlo Simulation) to _validate_ the linearized error propagation technique introduced in the textbook. Specifically, by:\n", - " 1. Comparing the estimated moments with that of the sample, and\n", - " 2. Comparing the Normal distribution defined by the estimated moments to the sample\n", - "\n", - "### A Note on \"Sampling\"\n", - "\n", - "We will use Monte Carlo Simulation to create an empirical \"sample\" of the random values of our function of random variables, $V$ (the output). This is a commonly used approach widely used in science and engineering applications. It is a numerical way of computing the distribution of a function that is useful when analytic approaches are not possible (for example, when the input distributions are non-Normal or the function is non-linear). For our purposes today, Monte Carlo Simulation is quite simple and involves the following steps:\n", - "\n", - "1. Define a function of random variables and the distributions of its input parameters.\n", - "2. Create a random sample of each input parameter according to the specified distribution.\n", - "3. Create a random sample of the output variable by computing the function for every set of input samples.\n", - "4. Evaluate the resulting distribution of the output.\n", - "\n", - "A few key points to recognize are:\n", - "1. As the sample size increases, the resulting distribution becomes more accurate.\n", - "2. This is a way to get the (approximately) \"true\" distribution of a function of random variables.\n", - "3. Accuracy is relative to the propagation of uncertainty through the function based on the assumed distributions of the input random variables. In other words, MCS can't help you if your function and distributions are poor representations of reality!\n", - "\n", - "### Application: Sewer Pipe Flow Velocity\n", - "\n", - "We will apply Manning's formula for the flow velocity $V$ in a sewer:\n", - "\n", - "$$\n", - "V =\\frac{1}{n}R^{2/3}S^{1/2}\n", - "$$\n", - "\n", - "where $R$ is the hydraulic radius of the sewer pipe (in $m$), $S$ the slope of the pipe (in $m/m$), and $n$ is the coefficient of roughness [$-$].\n", - "\n", - "Both $R$ and $S$ are random variables, as it is known that sewer pipes are susceptible to deformations; $n$ is assumed to be deterministic and in our case $n=0.013$ $s/m^{1/3}$. The sewer pipe considered here has mean values $\\mu_R$, $\\mu_S$, and standard deviations $\\sigma_R$ and $\\sigma_S$; $R$ and $S$ are independent.\n", - "\n", - "We are now interested in the mean flow velocity in the sewer as well as the uncertainty expressed by the standard deviation. This is important for the design of the sewer system.\n", - "\n", - "*Disclaimer: the dimensions of the pipe come from a real case study, but some aspects of the exercise are...less realistic.*\n", - "\n", - "### Programming\n", - "\n", - "Remember to use your `mude-base` environment when running this notebook.\n", - "\n", - "Some of the functions below uses <em>keyword arguments</em> to specify some of the parameter values; this is a way of setting \"default\" values. You can override them when using the function by specifying an alternative syntax. For example, the function here can be used in the following way to return `x=5` and `x=6`, respectively:\n", - "\n", - "```python\n", - "def test(x=5)\n", - " return x\n", - " \n", - "print(test())\n", - "print(test(x=6))\n", - "```\n", - "Copy/paste into a cell to explore further!\n", - "\n", - "Note also in the cell below that we can increase the default size of the text in our figures to make them more readable!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4fc6e87d-c66e-43df-a937-e969acc409f8", - "metadata": { - "id": "4fc6e87d-c66e-43df-a937-e969acc409f8", - "tags": [] - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "\n", - "from scipy.stats import norm\n", - "from scipy.stats import probplot\n", - "\n", - "import ipywidgets as widgets\n", - "from ipywidgets import interact\n", - "\n", - "plt.rcParams.update({'font.size': 14})" - ] - }, - { - "cell_type": "markdown", - "id": "be5078d7", - "metadata": {}, - "source": [ - "### Theory: Propagation laws for a function of 2 random variables \n", - "\n", - "We are interested in the mean and variance of $X$, which is a function of 2 random variables: $X=q(Y_1,Y_2)$. The mean and covariance matrix of $Y$ are assumed to be known:\n", - "\n", - "$$\\mu_Y = [\\mu_1\\;\\mu_2]^T$$\n", - "\n", - "$$\\Sigma_Y = \\begin{bmatrix} \\sigma^2_1 & Cov(Y_1,Y_2) \\\\ Cov(Y_1,Y_2) & \\sigma^2_2\\end{bmatrix}$$\n", - "\n", - "The second-order Taylor series approximation of the mean $\\mu_X$ is then given by:\n", - "\n", - "$$\\mu_X=\\mathbb{E}(q(Y))\\approx q(\\mu_Y )+\\frac{1}{2}\\frac{\\partial^2 q(\\mu_Y )}{\\partial Y_1^2 } \\sigma_1^2+\\frac{1}{2}\\frac{\\partial^2 q(\\mu_Y )}{\\partial Y_2^2 }\\sigma_2^2+\\frac{\\partial^2 q(\\mu_Y )}{\\partial Y_1 \\partial Y_2 } Cov(Y_1,Y_2) $$\n", - "\n", - "In most practical situations, the second-order approximation suffices. \n", - "\n", - "For the variance $\\sigma_X^2$ it is common to use only the first-order approximation, given by:\n", - "\n", - "$$\\sigma^2_X \\approx \\left(\\frac{\\partial q(\\mu_Y )}{\\partial Y_1 } \\right)^2 \\sigma^2_1 +\\left(\\frac{\\partial q(\\mu_Y )}{\\partial Y_2 } \\right)^2 \\sigma^2_2 + 2\\left(\\frac{\\partial q(\\mu_Y )}{\\partial Y_1 } \\right) \\left(\\frac{\\partial q(\\mu_Y )}{\\partial Y_2 } \\right) Cov(Y_1,Y_2)$$" - ] - }, - { - "cell_type": "markdown", - "id": "1ee42f39", - "metadata": {}, - "source": [ - "## Part 1: Apply the Propagation Laws\n", - "\n", - "We are interested to know how the uncertainty in $R$ and $S$ propagates into the uncertainty of the flow velocity $V$. We will first do this analytically and then implement it in code." - ] - }, - { - "cell_type": "markdown", - "id": "bfadcf3f-4578-4809-acdb-625ab3a71f27", - "metadata": { - "id": "bfadcf3f-4578-4809-acdb-625ab3a71f27" - }, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.1:</b> \n", - "\n", - "Use the Taylor series approximation to find the expression for $\\mu_V$ and $\\sigma_V$ as function of $\\mu_R$, $\\sigma_R$, $\\mu_S$, $\\sigma_S$. Write your answer on paper or using a tablet; later we will learn how to include images directly in our notebooks! For now you can skip this step, as you are not turning this notebook in.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "0cde3bdf-e0ba-4cdd-93ac-39a721b000c3", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.2:</b> \n", - "\n", - "Complete the function below, such that <code>moments_of_taylor_approximation</code> will compute the approximated $\\mu_V$ and $\\sigma_V$, as found in the previous Task.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a2f08dc7", - "metadata": {}, - "outputs": [], - "source": [ - "def moments_of_taylor_approximation(mu_R, mu_S, sigma_R, sigma_S,n):\n", - " \"\"\"Compute Taylor series approximation of mean and std of V.\n", - " \n", - " Take moments and function parameters as inputs (type float).\n", - " Returns mean and standard deviation of V (type float).\n", - " \"\"\"\n", - " \n", - " constant = 1/n\n", - " \n", - " dVdR = YOUR_CODE_HERE\n", - " dVdS = YOUR_CODE_HERE\n", - " \n", - " dVdR_2 = YOUR_CODE_HERE\n", - " dVdS_2 = YOUR_CODE_HERE\n", - " \n", - " mu_V_0 = YOUR_CODE_HERE\n", - " mu_V = YOUR_CODE_HERE\n", - " \n", - " var_V = YOUR_CODE_HERE\n", - " sigma_V = YOUR_CODE_HERE\n", - " \n", - " return mu_V, sigma_V" - ] - }, - { - "cell_type": "markdown", - "id": "3e823e7a", - "metadata": {}, - "source": [ - "Now we use the Taylor approximation and make two plots of $\\sigma_V$ as a function of $\\sigma_R$ for the following cases:\n", - "- $\\sigma_S$ = 0.002 $m/m$\n", - "- $\\sigma_S$ = 0 $m/m$ (i.e., slope is deterministic, not susceptible to deformation)\n", - "\n", - "We will use $\\mu_R = 0.5 m$ and $\\mu_S = 0.015 m/m$, and vary $\\sigma_R$ from 0 to 0.1 $m$. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "55ff8dd6-86ef-401a-9a56-02551c348698", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 425 - }, - "id": "55ff8dd6-86ef-401a-9a56-02551c348698", - "outputId": "3add4ee9-1054-4726-dc4f-72dca5c1c6c8" - }, - "outputs": [], - "source": [ - "n = 0.013\n", - "mu_R = 0.5\n", - "mu_S = 0.015\n", - "sigma_R = np.linspace(0.0, 0.1, 50)\n", - "\n", - "# case 1 for sigma_S\n", - "sigma_S_1 = 0.002\n", - "mu_V_1, sigma_V_1 = moments_of_taylor_approximation(mu_R, mu_S, sigma_R, sigma_S_1, n)\n", - "\n", - "# case 2 for sigma_S\n", - "sigma_S_2 = 0\n", - "mu_V_2, sigma_V_2 = moments_of_taylor_approximation(mu_R, mu_S, sigma_R, sigma_S_2, n)\n", - "\n", - "fig, ax = plt.subplots(1, 2, figsize = (16, 6))\n", - "# left side plot for case 1 \n", - "ax[0].plot(sigma_R, sigma_V_1, linewidth=4)\n", - "ax[0].set_ylabel(r'$\\sigma_V$ [$m/s$]', size = 20)\n", - "ax[0].set_xlabel(r'$\\sigma_R$ [$m$]', size = 20)\n", - "ax[0].set_title(r'$\\sigma_S$ = ' + f'{sigma_S_1} $m/m$, Case 1')\n", - "ax[0].set_xlim(0, 0.1)\n", - "ax[0].set_ylim(0, 1)\n", - "# right side plot for case 2\n", - "ax[1].plot(sigma_R, sigma_V_2, linewidth=4)\n", - "ax[1].set_ylabel(r'$\\sigma_V$ [$m/s$]', size = 20)\n", - "ax[1].set_xlabel(r'$\\sigma_R$ [m]', size = 20)\n", - "ax[1].set_title(r'$\\sigma_S$ = ' + f'{sigma_S_2} $m/m$, Case 2')\n", - "ax[1].set_xlim(0, 0.1)\n", - "ax[1].set_ylim(0, 1)\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "9091cfce", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3:</b> \n", - "Interpret the figures above, specifically looking at differences between Case 1 and Case 2. Also look at the equations you derived to understand why for Case 1 we get a non-linear relation, and for Case 2 a linear one.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "4487a9d6", - "metadata": {}, - "source": [ - "_You can write an answer in this cell using Markdown._" - ] - }, - { - "cell_type": "markdown", - "id": "a7e4c13f-a2ca-4c2d-a3e2-92d4630715a0", - "metadata": { - "id": "a7e4c13f-a2ca-4c2d-a3e2-92d4630715a0" - }, - "source": [ - "## Part 2: Simulation-Based Propagation \n", - "\n", - "We will use again the following values:\n", - "- $\\mu_R = 0.5$ m\n", - "- $\\mu_S = 0.015$ m/m\n", - "- $\\sigma_R=0.05$ m\n", - "- $\\sigma_S=0.002$ m/m\n", - "\n", - "Furthermore, it is assumed that $R$ and $S$ are independent normally distributed random variables. We will generate at least 10,000 simulated realizations each of $R$ and $S$ using a random number generator, and then you need to use these to calculate the corresponding sample values of $V$ and find the moments of that sample.\n" - ] - }, - { - "cell_type": "markdown", - "id": "c5a9d7ed", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.1:</b> \n", - "Complete the functions <code>function_of_random_variables</code> and <code>get_samples</code> below to define the function of random variables and then generate a sample of the output from this function, assuming the inputs are also random variables with the Normal distribution. Then find the moments of the samples.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6896ba98", - "metadata": {}, - "outputs": [], - "source": [ - "def function_of_random_variables(R, S):\n", - " V = YOUR_CODE_HERE\n", - " return V\n", - "\n", - "def get_samples(N, sigma_R, mu_R=0.5, mu_S=0.015, sigma_S=0.002, n=0.013):\n", - " \"\"\"Generate random samples for V from R and S.\"\"\"\n", - " R = np.random.normal(mu_R, sigma_R, N)\n", - " S = np.random.normal(mu_S, sigma_S, N)\n", - " V = YOUR_CODE_HERE\n", - " return V\n", - "\n", - "V_samples = get_samples(10000, 0.05)\n", - "\n", - "mu_V_samples = YOUR_CODE_HERE\n", - "sigma_V_samples = YOUR_CODE_HERE\n", - "\n", - "print('Moments of the SAMPLES:')\n", - "print(f' {mu_V_samples:.4f} m/s is the mean, and')\n", - "print(f' {sigma_V_samples:.4f} m/s is the std dev.')\n", - "\n", - "mu_V_taylor, sigma_V_taylor = moments_of_taylor_approximation(mu_R, mu_S, 0.05, 0.002, n)\n", - "print('\\nMoments of the TAYLOR SERIES APPROXIMATION:')\n", - "print(f' {mu_V_taylor:.4f} m/s is the mean, and')\n", - "print(f' {sigma_V_taylor:.4f} m/s is the std dev.')" - ] - }, - { - "cell_type": "markdown", - "id": "5fe4cf2c", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "\n", - "$\\textbf{Task 2.2:}$ \n", - "Are the results similar for the linearized and simulated values? Describe the difference quantitatively. Check your result also for the range of values of $\\sigma_R$ from 0.01 to 0.10; are they consistent?\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "af7f4e6f", - "metadata": {}, - "source": [ - "_You can write an answer in this cell using Markdown._" - ] - }, - { - "cell_type": "markdown", - "id": "97f3a877", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "\n", - "$\\textbf{Task 2.3:}$ \n", - "Run the cell with the sampling algorithm above repeatedly and look at the values printed in the cell output. Which values change? Which values do <em>not</em> change? Explain why, in each case.\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "095cd3e4", - "metadata": {}, - "source": [ - "_You can write an answer in this cell using Markdown._" - ] - }, - { - "cell_type": "markdown", - "id": "7cfc8c41", - "metadata": {}, - "source": [ - "## Part 3: Validating the Moments with a Distribution\n", - "\n", - "In Part 2 we used a sample of the function of random variables to _validate_ the Taylor approximation (we found that they are generally well-approximated). Now we will assume that the function of random variables has the Normal distribution to validate the moments and see for which range of values they remain a good approximation. This is done by comparing the sample to the assumed distribution; the former is represented by a histogram (also called an empirical probability density function, PDF, when normalized), the latter by a Normal distribution with moments calculated using the Taylor approximation.\n", - "\n", - "We will also use a normal probability plot to assess how well the assumption that $V$ is normally distributed holds up while varying the value of $\\sigma_R$, introduced next.\n", - "\n", - "### Theoretical Quantiles with `probplot`\n", - "\n", - "The method `probplot` is built into `scipy.stats` (Documentation [here](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.probplot.html)) and _validates_ a probability model by comparing samples (i.e., data) to a theoretical distribution (in this case, Normal). The \"Theoretical quantile\" that is plotted on the x-axis of this plot and measures the distance from the median of a distribution, normalized by the standard deviation, such that $\\mathrm{quantile}=q\\cdot\\sigma$. For example, $q=-1.5$ is $\\mu-1.5\\cdot\\sigma$. The vertical axis is the value of the random variable.\n", - "\n", - "Because we are comparing a theoretical distribution and a sample (data) on the same plot, one of the lines is the Normal PDF, which of course will have an exact match with the _theoretical quantiles_. This is why the Normal PDF will plot as a straight line in `probplot`. Comparing the (vertical) distance between the samples and the theoretical distribution (the red line) allows us to _validate_ our model. In particular, it allows us to validate the model for different regions of the distribution. In your interpretation, for example, you should try and identify whether the model is a good fit for the center and/or tails of the distribution.\n", - "\n", - "Note that `probplot` needs to know what to use for samples (you will tell it this), and what type of theoretical distribution you are using (we already did this for you...`norm`)." - ] - }, - { - "cell_type": "markdown", - "id": "e11a76d9", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 3.1:</b> \n", - "Complete the function <code>validate_distribution</code> below (instructions are in the docstring) to plot the empirical probability density function (PDF) of $V$ using your simulated samples. Also plot the Normal PDF in the same figure using the moments computed from the error propagation law. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "eea242ab", - "metadata": {}, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\"> <p><em>Hint: if you are struggling with the code below, re-read the introduction to Part 3 carefully!</em></p></div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "80005a5a-510b-4236-a2d6-184d9569eed4", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 475, - "referenced_widgets": [ - "b560714d739d431d85b3ca1a9b378c8f", - "56b7808a3e2241679b15d517565eaf85", - "d867da2ab3d441599b8356ac8e493611", - "481c67caa6d1405ea2e00cfe6dbfa32f", - "392504e006074b76af62e617c4cde70e", - "b0d26f90109f4e0eb6839f0ba43ba980", - "ea4c3dc473df41a684cfe7fd1e7fb35d" - ] - }, - "id": "80005a5a-510b-4236-a2d6-184d9569eed4", - "outputId": "80ae9e8d-e450-4e17-f092-fbf09fc885e6" - }, - "outputs": [], - "source": [ - "def validate_distribution(N, sigma_R, mu_R=0.5, mu_S=0.015, sigma_S=0.002, n=0.013):\n", - " \"\"\"Generate samples and plots for V\n", - " \n", - " Compares the sampled distribution of V to a Normal distribution defined\n", - " by the first moments of the error propagation law.\n", - " \n", - " Comparison is made via two plots:\n", - " 1. PDF of V~N(mu,sigma) (the approximation) and a histogram (sample)\n", - " 2. Probability plot, compares quantiles of sample and CDF of V\n", - " \n", - " Only a plot is returned.\n", - " \n", - " MUDE students fill in the missing code (see: YOUR_CODE_HERE):\n", - " 1. Generate samples and find moments\n", - " 2. Find moments of the function of random variables using Taylor series\n", - " 3. Enter data for the histogram\n", - " 4. Define the moments of the Normal distribution to be plotted\n", - " 5. Identify the appropriate variables to be printed in the plot titles\n", - " 6. Enter the data required for the probability plot\n", - " \"\"\"\n", - " \n", - " # Generate a sample and compute moments\n", - " V_samples = YOUR_CODE_HERE\n", - " mu_V_samples = YOUR_CODE_HERE\n", - " sigma_V_samples = YOUR_CODE_HERE\n", - " \n", - " # Compute moments using Taylor\n", - " mu_V_taylor, sigma_V_taylor = YOUR_CODE_HERE\n", - "\n", - " # Create left-side plot with histogram and normal distribution\n", - " # Plot histogram\n", - " xmin = 0\n", - " xmax = 10\n", - " x = np.linspace(xmin, xmax, 100)\n", - " fig, ax = plt.subplots(1, 2, figsize = (16, 6))\n", - " \n", - " ax[0].hist(YOUR_CODE_HERE, bins = 40, density = True, \n", - " label = 'Empirical PDF of V')\n", - " \n", - " # Add normal pdf in same figure\n", - " ax[0].plot(x, norm.pdf(x, YOUR_CODE_HERE, YOUR_CODE_HERE), color = 'black',\n", - " lw = 2.5, label='Normal PDF')\n", - "\n", - " ax[0].legend()\n", - " ax[0].set_xlabel('V [$m/s$]')\n", - " ax[0].set_xlim(xmin, xmax)\n", - " ax[0].set_ylim(0, 1)\n", - " ax[0].set_ylabel('Density')\n", - " ax[0].set_title(f'Simulation with {N} simulated realizations'\n", - " + '\\n' + f'mean = {round(YOUR_CODE_HERE, 3)}' \n", - " f'm/s and std = {round(YOUR_CODE_HERE, 3)} m/s')\n", - " \n", - " # Add probability plot in right-side panel\n", - " probplot(YOUR_CODE_HERE, dist = norm, fit = True, plot = ax[1])\n", - "\n", - " ax[1].legend(['Generated samples', 'Normal fit'])\n", - " ax[1].get_lines()[1].set_linewidth(2.5)\n", - " plt.show()\n", - "\n", - "validate_distribution(10000, 0.01)" - ] - }, - { - "cell_type": "markdown", - "id": "1566c23d-b8d0-416a-9fe8-8cd93940f9b0", - "metadata": {}, - "source": [ - "### Validate the Distribution of $V$ for Various $\\sigma_R$\n", - "\n", - "The code below uses a widget to call your function to make the plots and add a slider to change the values of $\\sigma_R$ and visualize the change in the distributions." - ] - }, - { - "cell_type": "markdown", - "id": "48dc608a", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "\n", - "$\\textbf{Task 3.2:}$\n", - "Run the cell below, then play with the slider to change $\\sigma_R$. How well does the error propagation law match the \"true\" distribution (the samples)? State your conclusion and explain why. Check also whether there is an impact for different $\\sigma_R$ values.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9a403e17", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 475, - "referenced_widgets": [ - "b560714d739d431d85b3ca1a9b378c8f", - "56b7808a3e2241679b15d517565eaf85", - "d867da2ab3d441599b8356ac8e493611", - "481c67caa6d1405ea2e00cfe6dbfa32f", - "392504e006074b76af62e617c4cde70e", - "b0d26f90109f4e0eb6839f0ba43ba980", - "ea4c3dc473df41a684cfe7fd1e7fb35d" - ] - }, - "id": "80005a5a-510b-4236-a2d6-184d9569eed4", - "outputId": "80ae9e8d-e450-4e17-f092-fbf09fc885e6" - }, - "outputs": [], - "source": [ - "@interact(sigma_R=(0, 0.1, 0.005))\n", - "def samples_slideplot(sigma_R):\n", - " validate_distribution(50000, sigma_R);" - ] - }, - { - "cell_type": "markdown", - "id": "996fc183", - "metadata": {}, - "source": [ - "_You can write an answer in this cell using Markdown._" - ] - }, - { - "cell_type": "markdown", - "id": "35c20211", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "\n", - "$\\textbf{Task 3.3:}$\n", - "To further validate the error propagation law, estimate the probability that the \"true\" velocity of the tunnel is in the inaccurate range of values (assuming that the Normal distribution is a suitable model for the distribution of the function of random variables).\n", - "\n", - "<em>Hint: recall that in this notebook a quantile, $q$, is defined as a standard deviation, and that the probability of observing a random variable $X$ such that $P[X\\lt q]$ can be found with the CDF of the standard Normal distribution, evaluated in Python using <code>scipy.stats.norm.cdf(q)</code>.</em>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "adbd9933", - "metadata": {}, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\"> <p><em>\n", - "\n", - "$\\textbf{Note:}$\n", - "As we saw in 3.2, the Normal distribution does not fit the tails of the distribution of the function of random variables perfectly. Although this means using the Normal distribution may not be a good way of estimating the probability of \"being in the tails,\" the approach in this Task is still suitable for getting an idea of the order of magnitude, and observing how sever this \"error\" maybe for different assumptions of $\\sigma_R$.</em></p></div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c7a8d678", - "metadata": {}, - "outputs": [], - "source": [ - "p = YOUR_CODE_HERE\n", - "\n", - "print(f'The probability is {p:0.6e}')" - ] - }, - { - "cell_type": "markdown", - "id": "15f6ad77", - "metadata": {}, - "source": [ - "_You can write an answer in this cell using Markdown._" - ] - }, - { - "cell_type": "markdown", - "id": "37038bb6", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" />\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" />\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2024 <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">MUDE</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">CC BY 4.0 License</a>." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "provenance": [] - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.4" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": { - "2082c60151554578805c2be3a31ffd8f": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "VBoxModel", - "state": { - "_dom_classes": [ - "widget-interact" - ], - "children": [ - "IPY_MODEL_47b254e4f85448dc95d858718b75e064", - "IPY_MODEL_4df814e341224be3a57d82ee44acd790" - ], - "layout": "IPY_MODEL_f003ee4f4ed449629e85cac95f7b6abc" - } - }, - "47b254e4f85448dc95d858718b75e064": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "FloatSliderModel", - "state": { - "behavior": "drag-tap", - "description": "sigma_R", - "layout": "IPY_MODEL_d927becd53d548219761a47bbe3489b3", - "max": 0.1, - "step": 0.005, - "style": "IPY_MODEL_d9d7ec418b5a4761a7b956ec83500ea8", - "value": 0.05 - } - }, - "4df814e341224be3a57d82ee44acd790": { - "model_module": "@jupyter-widgets/output", - "model_module_version": "1.0.0", - "model_name": "OutputModel", - "state": { - "layout": "IPY_MODEL_e10896000fd1499387e79765dacb3eb8", - "outputs": [ - { - "data": { - "image/png": "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2NhYjh07Ro4cOejUqROHDh0yO0nE81S/fn2t26Sp8SobNGigpWW2aziktjLdunUr7dq1w8HBgSNHjmjH7Xlr3LgxQ4YMISAgACsrK0JDQzl58iSenp506NCBdevWsWjRImxtbU2Wt7e356+//mLKlClUqVKF69evExYWRqVKlfjpp5/YuHGjwUQdabm5uXHo0CHGjBlD6dKluXDhArdu3cLf35958+YxZ84cs91VfX19+eeffxg8eDCFChXi9OnTxMTE0LhxY9atW6d15TelatWqnDhxgr59++Lp6UloaCiJiYm0adOGPXv20Lt370wdwxIlSjBr1iw6d+5MwYIFuXr1KiEhISQkJNCoUSN+//13li1bli3GLn0Zzxe5c+dm586dzJs3j6ZNm6KUIiQkhGvXrlGwYEF69erFqlWrjFpPenh4sG/fPoYOHUrhwoW5ePEi//77L126dOHo0aMUKVIk0/uaGc2aNePMmTMMGzaMChUqcOPGDUJCQnj48CE1a9Zk1KhRhISEGJTJly8fBw8epEuXLri5uXH+/HmioqLo3r07ISEhz2WCr0uXLqU7y3l0dLS27JgxY5g5cyYVK1YkNjaWc+fOUaxYMWbOnMmMGTPMbkOn07F+/Xq6d++Ou7s7x44d095rc+PhpuXs7My2bduYPn06tWvXJiIign/++QcvLy/69OnDP//8Q7NmzbLkeAC0a9eOCRMm0Lx5c1xcXDh79iwnT57E2dmZd955h127djFo0KAs254QQgghhBAvE51SZkabF0IIIYQQQgghhBBCCAuQlpZCCCGEEEIIIYQQQohsRYKWQgghhBBCCCGEEEKIbEWClkIIIYQQQgghhBBCiGxFgpZCCCGEEEIIIYQQQohsRYKWQgghhBBCCCGEEEKIbEWClkIIIYQQQgghhBBCiGxFgpZCCCGEEEIIIYQQQohsRYKWQgghhBBCCCGEEEKIbEWClkII8Zrr0aMHOp2OoKAgS1flicLDw9HpdOh0OktXRQghhBDCJF9fX3Q6HTt27Hhh2wwMDESn0zFnzpwsK7tjxw50Oh2+vr5Zur3sRn9vGR4ebumqCCEeI0FLIbIx/Q1Pen9nzpx5qnVHR0czZswYKlasSM6cOcmZMyfly5fn66+/5uHDh2bLnTp1il9++YXevXtToUIFbG1t0el09OjRI0PbvXjxIv369aNo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999/T/v27cmTJw/t2rXj8uXLT7UfQgghLGfUqFHaM0JycjL37t1j3759DBkyxOx1JL1nBf19SZ48ecwuo79n1S/7uIzc06Qtu3//fj7++GMSEhLo378/hw4d4t69eyQlJRn0EEuvVV9mt2kp3bt3x97ens2bN3PlyhUg9Vlw0aJFALz33ntPve7t27drn4XExERu3brFhg0btBnJMyIz73/a5YUQWUtaWornLmfOnERGRrJy5Upat26d4XLr16/n9u3bFChQgLVr1xq1alNKZejBOqt16NAh063SILVb5dSpU7O0Lvrup+kFuczJly8fkyZNYtKkSUZ5Q4cOBVK7/Gf0wp5RVapUYcGCBSbzDh8+DKB1XXkRVq1ahVLKqDWWnre3N9OmTWPq1KmcOnWK3bt3s2HDBtatW8fEiRO5ceOG2f15nL716meffUZQUJBRfnpBrqelDzr/+++/ZpdJLy89RYsW5ffffyc5OZljx46xe/du1q5dy9atWxk2bBixsbF8++232aKuAP7+/k9VrlmzZgwbNizDy5csWZJr164ZddVPS//QUbJkyaeqkznmzgmlSpXS/m9vb2+ybNr0zASca9WqhYeHB3fu3CEkJET7McmSTp06xblz56hVq5bJhw07OzuGDBnCkCFDuHbtGnv27GHLli38+eefLF++nBMnThASEvLULTyEEEK8/JydnYmKikp3iCD9M4G5H/kzck+TtuzcuXOB1OeNadOmGZXJyL1iZrdpKR4eHrRv35758+cze/ZsgoKCWLx4MTExMVSsWFEbesxS9McoI+9/2uWFEFlLgpbiufPz8yM8PJy9e/dmKmgZFhYGpAawTHXD/eeff4zGbXsRDh8+/FStcJ6mu2x6IiIitG7zWRkkSElJ0VpOmQvkPQ9hYWEcOnTohW/X3HiWj9PpdJQtW5ayZcvSr18/Vq9eTevWrVm4cCE///wzuXLleuK29J9pU+OsAuzbty8zVc+QUqVKcezYMU6dOmUyPzk5Wev+8rSsra2pUqUKVapUYeDAgfz000988skn/PLLLwZByycFwPWBtdjYWK5du2ayi7i+VfbT2Lt371OVM9c12ZxatWqxdetWdu/ebTI/Li5O+6zXqlXrqepkSlJSktY97fFzgn7MU0gNmJoa31QfSHVwcMh0F2l9kDOzrWufl4x+rwF8fHzo2LEjHTt2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u3jR9S5edL2Ll4K63hphWbiZzWbKly9v6zSypf+zigdd5+JB17n40LUuHuztOuf2ftScz3nctdatWwOwYsWKLG2Zscw+dzrPtWvX2LhxY5a2X3/9NdfnERERERERERERkYJld0XLdu3aUblyZebOncuuXbss8YSEBN5++20cHR0JDw+3xC9cuMCBAwe4cOGC1XmeeeYZAN58802Sk5Mt8dWrV/Prr7/SqlUrqlWrlq+vRURERERERERERO6e3RUtHR0d+fLLL0lPT6dly5Y888wzjBgxgnr16rFv3z4iIiKsio3Tpk2jZs2aTJs2zeo8oaGhDBkyhPXr19OgQQNee+01Bg4cSJcuXfD29uazzz4r6JeW71xcXBg3blyWae1SNOl6Fy+63sWLrnfxousthZ1+hosHXefiQde5+NC1Lh4K+3U2GbnZY9wGtm7dyrhx44iJiSE5OZmQkBBefvllnnzySat+ERERjB8/nnHjxhEREWHVlp6ezv/93//xxRdfcPjwYTw9PQkNDWXixIkaZSkiIiIiIiIiImKn7LZoKSIiIiIiIiIiIsWT3U0PFxERERERERERkeJNRUsRERERERERERGxKypaioiIiIiIiIiIiF1R0bKImTx5MiaTCZPJxObNm22djuSx4OBgy/X95+Pf//63rdOTfPLjjz/SoUMH/P39cXNzo1KlSvTr148TJ07YOjXJI7Nnz87x33bmo127drZOU/KQYRhERkYSGhpKmTJlcHd3p3r16jz77LMcPXrU1umJ5KnNmzfj4OCAyWTi3XfftXU6kgeuXbvGt99+yxNPPEG1atVwc3OjRIkStG7dmnnz5tk6PblH27Zto3Pnzvj6+uLh4UHjxo2ZO3eurdOSPHLq1Ck++ugjOnbsSIUKFXB2dqZ06dI8/vjjbNmyxdbpST4qzHUiR1snIHln//79jB07Fg8PD65du2brdCSf+Pj48PLLL2eJP/TQQwWfjOQrwzD497//zfTp06lSpQp9+/bFy8uLv//+m3Xr1nH8+HGCgoJsnabkgfr16zNu3Lhs2xYuXMi+ffvo1KlTAWcl+WnEiBF8+OGHlClThh49euDt7c3u3buZMWMG8+bNY9OmTdSuXdvWaYrct+vXrxMeHo6bm5vuT4uQ9evXM2DAAPz9/WnXrh2PP/44586dIzIykv79+7Np0yY++eQTW6cp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lFKlStk6FREREZF8s337dt5//33atGnDs88+y86dO1m0aBF79uxh7969uLq6Wvpu2bKFTp06ce3aNbp168YDDzxAbGws3333Hb/88gsxMTFUrlzZ0v8///kPffv2xdnZmbCwMEqWLMmqVasYP348K1asYO3atbi4uFjlc/HiRZo1a4afnx9hYWEkJyfj7e0NwOeff87zzz+Pr68v3bp1IzAwkG3btjFx4kTWrl3L2rVrcXZ2pk2bNsTGxjJnzhxat25NmzZtLOe/0xvLP/74I/369SM9PZ1u3bpRvXp1zp07x5YtW/jqq6/o1q0bAPv372fs2LGEhobSs2dPPDw8OHDgAHPnzuXnn39mx44dVKxY8Z6vy+rVq3n00Ucxm82EhYVRtmxZVq9eTfPmzfH19b3n82a6dOkSL7/8Mi1btqRz5874+vpy9OhRlixZwi+//EJ0dDSNGjXK8rylS5fy008/0a1bN5577jmio6P5+uuvOXLkCBs2bACgfv36vPTSS0ydOpV69erRo0cPy/PvZZMdwzB46qmnmDt3LtWqVaN///44OzuzcuVKnn76af744w8++OADS/+BAweyYMEC6taty6BBg3BxceGvv/5i7dq1dOrUiTp16tx1DiKFniEiIoZhGMb48eMNwHj77bezbd++fbsBGI0bN77juWbNmmUAxqxZs3Lss2DBAgMwPvnkE2PZsmVG69atDU9PT6NUqVLG66+/bqSlpRmGYRhz5841mjRpYnh4eBgVK1Y0pk6dmu35Dh06ZADGe++9ZxVftmyZ0alTJyMoKMhwdnY2ypQpY7Rr186YO3dulnNUrFjRqFix4h1fn4iIiEh+AG57L7J27VoDMABj/vz5Vm0DBgwwAGPevHmWWHJyshEcHGx4eXkZu3btsuq/fv16w8HBwejataslFh8fb5QoUcJwcXExdu/ebYmnp6cb/fv3z/ZeMTOfQYMGGampqVZt+/btMxwdHY0GDRoYFy9etGqbNGmSARgffPBBltc3bty4bF//uHHjDMBYu3atJXb27FnD09PT8PDwMHbs2JHlOSdOnLB8fuXKlSx5GIZhrFmzxjCbzcaQIUOs4rm5p82UlpZmVK5c2TCZTMb69est8Vu/d/8sQQwcONAAjGPHjuXqtd64ccM4efJklr579+41PD09jfbt22ebv6Ojo7FhwwZLPDU11WjT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3tXXHzp0KPXr17eM9lyyZAk+Pj5UqFCB4cOHW70x7uDgQGRkJK+//jrffPMNCQkJAPTt2zfHoiVAz5492bJlC5MmTWLdunUsWbKEgIAA6tevz9ChQy39XnjhBZycnPjkk0+YMWMGJUqUoEuXLrzzzjs88cQTd/W6stO+fXtWr17Nm2++yQ8//ICbmxvt2rXjhx9+4F//+leW/m5ubqxevZrhw4ezZs0aNm/eTNOmTYmOjuann37KUrTs2rWrZcOab7/9Fnd3d9q2bcuPP/7IW2+9dd/5A3zzzTcMHz6cRYsWERcXh2EYNG3a9K6LlpmbG3Xu3JkZM2bw008/cfXqVUqWLEnVqlX54IMPLPfvwcHBREREsGbNGlatWsXFixcJCAigYcOGDB8+PNc7w4sUNSbDMAxbJyEiYm/i4+MpU6YMiYmJACxatOi2Ixn/afbs2QwaNIhZs2ZlmUKUmJiIl5cX7du359dff7Vq+/PPP6levTpDhw5l+vTpVm3R0dG0bt2asWPHWnYhTE9Pp0yZMjz88MP8+OOPlr7h4eF88803PPzww9SqVYsSJUrwxx9/8Msvv1CmTBk2btyY7Y1X5uLt97uzo4iIiIjIrdq0acO6detQCUJEcksjLUVEsuHt7U3v3r35+uuvKVWqVJbRjffj999/Jz09Pcep4XD79SxvfV5MTAznzp3LUlDt0aMHKSkpbN26lZ07d5KSkkJwcDDDhw9n5MiR+Pv759nrEREREREREclrGmkpIpIPbjfSMi+99tprTJkyhbNnzxIQEHDf59NISxERERHJDxppKSJ3S7uHi4jko0GDBmEymejbt2++nH/x4sU8/PDD91WwPHz4MCaTCZPJxPHjx/MwOxEREREREZF7o+nhIiL5oH79+owbN85ynLlLZV47ePDgfZ/Dz8/PKtcSJUrc9zlFRERERG51vzt7i0jxo+nhIiIiIiIiIiIiYlc0PVxERERERERERETsioqWIiIiIiIiIiIiYldUtBQRERERERERERG7oqKliIiIiIiIiIiI2BUVLUVERERERERERMSuqGgpIiIiIiIiIiIidkVFSxEREREREREREbErKlqKiIiIiIiIiIiIXVHRUkREREREREREROyKipYiIiIiIiIiIiJiV/4/nGeemaZOEqwAAAAASUVORK5CYII=", - "text/plain": "<Figure size 1600x600 with 2 Axes>" - }, - "metadata": {}, - "output_type": "display_data" - } - ] - } - }, - "d927becd53d548219761a47bbe3489b3": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "d9d7ec418b5a4761a7b956ec83500ea8": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "SliderStyleModel", - "state": { - "description_width": "" - } - }, - "e10896000fd1499387e79765dacb3eb8": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "f003ee4f4ed449629e85cac95f7b6abc": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - } - }, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/synced_files/students/Week_1_2/WS_1_2_Pipe_Dreams.md b/synced_files/students/Week_1_2/WS_1_2_Pipe_Dreams.md deleted file mode 100644 index 8aeeec1b0211ecfcc69f252217d4e5c35facbc65..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_1_2/WS_1_2_Pipe_Dreams.md +++ /dev/null @@ -1,444 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -<!-- #region id="9adbf457-797f-45b7-8f8b-0e46e0e2f5ff" --> -# WS 1.2: Mean and Variance Propagation - -**Sewer Pipe Flow Velocity** - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px; height: auto; margin: 0" /> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px; height: auto; margin: 0" /> -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.2. Wed Sep 11, 2024.* -<!-- #endregion --> - -<!-- #region id="1db6fea9-f3ad-44bc-a4c8-7b2b3008e945" --> -## Overview - -In this notebook you will apply the propagation laws for the mean and variance for a function of two independent random variables. You will assess how well the approximations correspond with the <em>simulation-based</em> equivalents. You will also assess the distribution of the function. - -_You do not need to turn in this notebook._ - -### Objectives - -1. Observe how uncertainty "propagates" from the inputs to the output of a function by estimating moments of the function of random variables and seeing how they change relative to the moments of the input random variables. -2. Recognize that a non-linear function of random variables that have the (joint) Normal distribution (the inputs) produces a non-Normal random variable (the output). -3. Using _sampling_ (Monte Carlo Simulation) to _validate_ the linearized error propagation technique introduced in the textbook. Specifically, by: - 1. Comparing the estimated moments with that of the sample, and - 2. Comparing the Normal distribution defined by the estimated moments to the sample - -### A Note on "Sampling" - -We will use Monte Carlo Simulation to create an empirical "sample" of the random values of our function of random variables, $V$ (the output). This is a commonly used approach widely used in science and engineering applications. It is a numerical way of computing the distribution of a function that is useful when analytic approaches are not possible (for example, when the input distributions are non-Normal or the function is non-linear). For our purposes today, Monte Carlo Simulation is quite simple and involves the following steps: - -1. Define a function of random variables and the distributions of its input parameters. -2. Create a random sample of each input parameter according to the specified distribution. -3. Create a random sample of the output variable by computing the function for every set of input samples. -4. Evaluate the resulting distribution of the output. - -A few key points to recognize are: -1. As the sample size increases, the resulting distribution becomes more accurate. -2. This is a way to get the (approximately) "true" distribution of a function of random variables. -3. Accuracy is relative to the propagation of uncertainty through the function based on the assumed distributions of the input random variables. In other words, MCS can't help you if your function and distributions are poor representations of reality! - -### Application: Sewer Pipe Flow Velocity - -We will apply Manning's formula for the flow velocity $V$ in a sewer: - -$$ -V =\frac{1}{n}R^{2/3}S^{1/2} -$$ - -where $R$ is the hydraulic radius of the sewer pipe (in $m$), $S$ the slope of the pipe (in $m/m$), and $n$ is the coefficient of roughness [$-$]. - -Both $R$ and $S$ are random variables, as it is known that sewer pipes are susceptible to deformations; $n$ is assumed to be deterministic and in our case $n=0.013$ $s/m^{1/3}$. The sewer pipe considered here has mean values $\mu_R$, $\mu_S$, and standard deviations $\sigma_R$ and $\sigma_S$; $R$ and $S$ are independent. - -We are now interested in the mean flow velocity in the sewer as well as the uncertainty expressed by the standard deviation. This is important for the design of the sewer system. - -*Disclaimer: the dimensions of the pipe come from a real case study, but some aspects of the exercise are...less realistic.* - -### Programming - -Remember to use your `mude-base` environment when running this notebook. - -Some of the functions below uses <em>keyword arguments</em> to specify some of the parameter values; this is a way of setting "default" values. You can override them when using the function by specifying an alternative syntax. For example, the function here can be used in the following way to return `x=5` and `x=6`, respectively: - -```python -def test(x=5) - return x - -print(test()) -print(test(x=6)) -``` -Copy/paste into a cell to explore further! - -Note also in the cell below that we can increase the default size of the text in our figures to make them more readable! -<!-- #endregion --> - -```python id="4fc6e87d-c66e-43df-a937-e969acc409f8" -import numpy as np -import matplotlib.pyplot as plt - -from scipy.stats import norm -from scipy.stats import probplot - -import ipywidgets as widgets -from ipywidgets import interact - -plt.rcParams.update({'font.size': 14}) -``` - -### Theory: Propagation laws for a function of 2 random variables - -We are interested in the mean and variance of $X$, which is a function of 2 random variables: $X=q(Y_1,Y_2)$. The mean and covariance matrix of $Y$ are assumed to be known: - -$$\mu_Y = [\mu_1\;\mu_2]^T$$ - -$$\Sigma_Y = \begin{bmatrix} \sigma^2_1 & Cov(Y_1,Y_2) \\ Cov(Y_1,Y_2) & \sigma^2_2\end{bmatrix}$$ - -The second-order Taylor series approximation of the mean $\mu_X$ is then given by: - -$$\mu_X=\mathbb{E}(q(Y))\approx q(\mu_Y )+\frac{1}{2}\frac{\partial^2 q(\mu_Y )}{\partial Y_1^2 } \sigma_1^2+\frac{1}{2}\frac{\partial^2 q(\mu_Y )}{\partial Y_2^2 }\sigma_2^2+\frac{\partial^2 q(\mu_Y )}{\partial Y_1 \partial Y_2 } Cov(Y_1,Y_2) $$ - -In most practical situations, the second-order approximation suffices. - -For the variance $\sigma_X^2$ it is common to use only the first-order approximation, given by: - -$$\sigma^2_X \approx \left(\frac{\partial q(\mu_Y )}{\partial Y_1 } \right)^2 \sigma^2_1 +\left(\frac{\partial q(\mu_Y )}{\partial Y_2 } \right)^2 \sigma^2_2 + 2\left(\frac{\partial q(\mu_Y )}{\partial Y_1 } \right) \left(\frac{\partial q(\mu_Y )}{\partial Y_2 } \right) Cov(Y_1,Y_2)$$ - - -## Part 1: Apply the Propagation Laws - -We are interested to know how the uncertainty in $R$ and $S$ propagates into the uncertainty of the flow velocity $V$. We will first do this analytically and then implement it in code. - -<!-- #region id="bfadcf3f-4578-4809-acdb-625ab3a71f27" --> -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.1:</b> - -Use the Taylor series approximation to find the expression for $\mu_V$ and $\sigma_V$ as function of $\mu_R$, $\sigma_R$, $\mu_S$, $\sigma_S$. Write your answer on paper or using a tablet; later we will learn how to include images directly in our notebooks! For now you can skip this step, as you are not turning this notebook in. -</p> -</div> -<!-- #endregion --> - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.2:</b> - -Complete the function below, such that <code>moments_of_taylor_approximation</code> will compute the approximated $\mu_V$ and $\sigma_V$, as found in the previous Task. -</p> -</div> - -```python -def moments_of_taylor_approximation(mu_R, mu_S, sigma_R, sigma_S,n): - """Compute Taylor series approximation of mean and std of V. - - Take moments and function parameters as inputs (type float). - Returns mean and standard deviation of V (type float). - """ - - constant = 1/n - - dVdR = YOUR_CODE_HERE - dVdS = YOUR_CODE_HERE - - dVdR_2 = YOUR_CODE_HERE - dVdS_2 = YOUR_CODE_HERE - - mu_V_0 = YOUR_CODE_HERE - mu_V = YOUR_CODE_HERE - - var_V = YOUR_CODE_HERE - sigma_V = YOUR_CODE_HERE - - return mu_V, sigma_V -``` - -Now we use the Taylor approximation and make two plots of $\sigma_V$ as a function of $\sigma_R$ for the following cases: -- $\sigma_S$ = 0.002 $m/m$ -- $\sigma_S$ = 0 $m/m$ (i.e., slope is deterministic, not susceptible to deformation) - -We will use $\mu_R = 0.5 m$ and $\mu_S = 0.015 m/m$, and vary $\sigma_R$ from 0 to 0.1 $m$. - -```python colab={"base_uri": "https://localhost:8080/", "height": 425} id="55ff8dd6-86ef-401a-9a56-02551c348698" outputId="3add4ee9-1054-4726-dc4f-72dca5c1c6c8" -n = 0.013 -mu_R = 0.5 -mu_S = 0.015 -sigma_R = np.linspace(0.0, 0.1, 50) - -# case 1 for sigma_S -sigma_S_1 = 0.002 -mu_V_1, sigma_V_1 = moments_of_taylor_approximation(mu_R, mu_S, sigma_R, sigma_S_1, n) - -# case 2 for sigma_S -sigma_S_2 = 0 -mu_V_2, sigma_V_2 = moments_of_taylor_approximation(mu_R, mu_S, sigma_R, sigma_S_2, n) - -fig, ax = plt.subplots(1, 2, figsize = (16, 6)) -# left side plot for case 1 -ax[0].plot(sigma_R, sigma_V_1, linewidth=4) -ax[0].set_ylabel(r'$\sigma_V$ [$m/s$]', size = 20) -ax[0].set_xlabel(r'$\sigma_R$ [$m$]', size = 20) -ax[0].set_title(r'$\sigma_S$ = ' + f'{sigma_S_1} $m/m$, Case 1') -ax[0].set_xlim(0, 0.1) -ax[0].set_ylim(0, 1) -# right side plot for case 2 -ax[1].plot(sigma_R, sigma_V_2, linewidth=4) -ax[1].set_ylabel(r'$\sigma_V$ [$m/s$]', size = 20) -ax[1].set_xlabel(r'$\sigma_R$ [m]', size = 20) -ax[1].set_title(r'$\sigma_S$ = ' + f'{sigma_S_2} $m/m$, Case 2') -ax[1].set_xlim(0, 0.1) -ax[1].set_ylim(0, 1) -plt.show() -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3:</b> -Interpret the figures above, specifically looking at differences between Case 1 and Case 2. Also look at the equations you derived to understand why for Case 1 we get a non-linear relation, and for Case 2 a linear one. -</p> -</div> - - -_You can write an answer in this cell using Markdown._ - -<!-- #region id="a7e4c13f-a2ca-4c2d-a3e2-92d4630715a0" --> -## Part 2: Simulation-Based Propagation - -We will use again the following values: -- $\mu_R = 0.5$ m -- $\mu_S = 0.015$ m/m -- $\sigma_R=0.05$ m -- $\sigma_S=0.002$ m/m - -Furthermore, it is assumed that $R$ and $S$ are independent normally distributed random variables. We will generate at least 10,000 simulated realizations each of $R$ and $S$ using a random number generator, and then you need to use these to calculate the corresponding sample values of $V$ and find the moments of that sample. - -<!-- #endregion --> - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.1:</b> -Complete the functions <code>function_of_random_variables</code> and <code>get_samples</code> below to define the function of random variables and then generate a sample of the output from this function, assuming the inputs are also random variables with the Normal distribution. Then find the moments of the samples. -</p> -</div> - -```python -def function_of_random_variables(R, S): - V = YOUR_CODE_HERE - return V - -def get_samples(N, sigma_R, mu_R=0.5, mu_S=0.015, sigma_S=0.002, n=0.013): - """Generate random samples for V from R and S.""" - R = np.random.normal(mu_R, sigma_R, N) - S = np.random.normal(mu_S, sigma_S, N) - V = YOUR_CODE_HERE - return V - -V_samples = get_samples(10000, 0.05) - -mu_V_samples = YOUR_CODE_HERE -sigma_V_samples = YOUR_CODE_HERE - -print('Moments of the SAMPLES:') -print(f' {mu_V_samples:.4f} m/s is the mean, and') -print(f' {sigma_V_samples:.4f} m/s is the std dev.') - -mu_V_taylor, sigma_V_taylor = moments_of_taylor_approximation(mu_R, mu_S, 0.05, 0.002, n) -print('\nMoments of the TAYLOR SERIES APPROXIMATION:') -print(f' {mu_V_taylor:.4f} m/s is the mean, and') -print(f' {sigma_V_taylor:.4f} m/s is the std dev.') -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> - -$\textbf{Task 2.2:}$ -Are the results similar for the linearized and simulated values? Describe the difference quantitatively. Check your result also for the range of values of $\sigma_R$ from 0.01 to 0.10; are they consistent? -</div> - - -_You can write an answer in this cell using Markdown._ - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> - -$\textbf{Task 2.3:}$ -Run the cell with the sampling algorithm above repeatedly and look at the values printed in the cell output. Which values change? Which values do <em>not</em> change? Explain why, in each case. -</div> - - -_You can write an answer in this cell using Markdown._ - - -## Part 3: Validating the Moments with a Distribution - -In Part 2 we used a sample of the function of random variables to _validate_ the Taylor approximation (we found that they are generally well-approximated). Now we will assume that the function of random variables has the Normal distribution to validate the moments and see for which range of values they remain a good approximation. This is done by comparing the sample to the assumed distribution; the former is represented by a histogram (also called an empirical probability density function, PDF, when normalized), the latter by a Normal distribution with moments calculated using the Taylor approximation. - -We will also use a normal probability plot to assess how well the assumption that $V$ is normally distributed holds up while varying the value of $\sigma_R$, introduced next. - -### Theoretical Quantiles with `probplot` - -The method `probplot` is built into `scipy.stats` (Documentation [here](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.probplot.html)) and _validates_ a probability model by comparing samples (i.e., data) to a theoretical distribution (in this case, Normal). The "Theoretical quantile" that is plotted on the x-axis of this plot and measures the distance from the median of a distribution, normalized by the standard deviation, such that $\mathrm{quantile}=q\cdot\sigma$. For example, $q=-1.5$ is $\mu-1.5\cdot\sigma$. The vertical axis is the value of the random variable. - -Because we are comparing a theoretical distribution and a sample (data) on the same plot, one of the lines is the Normal PDF, which of course will have an exact match with the _theoretical quantiles_. This is why the Normal PDF will plot as a straight line in `probplot`. Comparing the (vertical) distance between the samples and the theoretical distribution (the red line) allows us to _validate_ our model. In particular, it allows us to validate the model for different regions of the distribution. In your interpretation, for example, you should try and identify whether the model is a good fit for the center and/or tails of the distribution. - -Note that `probplot` needs to know what to use for samples (you will tell it this), and what type of theoretical distribution you are using (we already did this for you...`norm`). - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 3.1:</b> -Complete the function <code>validate_distribution</code> below (instructions are in the docstring) to plot the empirical probability density function (PDF) of $V$ using your simulated samples. Also plot the Normal PDF in the same figure using the moments computed from the error propagation law. -</p> -</div> - - -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p><em>Hint: if you are struggling with the code below, re-read the introduction to Part 3 carefully!</em></p></div> - -```python colab={"base_uri": "https://localhost:8080/", "height": 475, "referenced_widgets": ["b560714d739d431d85b3ca1a9b378c8f", "56b7808a3e2241679b15d517565eaf85", "d867da2ab3d441599b8356ac8e493611", "481c67caa6d1405ea2e00cfe6dbfa32f", "392504e006074b76af62e617c4cde70e", "b0d26f90109f4e0eb6839f0ba43ba980", "ea4c3dc473df41a684cfe7fd1e7fb35d"]} id="80005a5a-510b-4236-a2d6-184d9569eed4" outputId="80ae9e8d-e450-4e17-f092-fbf09fc885e6" -def validate_distribution(N, sigma_R, mu_R=0.5, mu_S=0.015, sigma_S=0.002, n=0.013): - """Generate samples and plots for V - - Compares the sampled distribution of V to a Normal distribution defined - by the first moments of the error propagation law. - - Comparison is made via two plots: - 1. PDF of V~N(mu,sigma) (the approximation) and a histogram (sample) - 2. Probability plot, compares quantiles of sample and CDF of V - - Only a plot is returned. - - MUDE students fill in the missing code (see: YOUR_CODE_HERE): - 1. Generate samples and find moments - 2. Find moments of the function of random variables using Taylor series - 3. Enter data for the histogram - 4. Define the moments of the Normal distribution to be plotted - 5. Identify the appropriate variables to be printed in the plot titles - 6. Enter the data required for the probability plot - """ - - # Generate a sample and compute moments - V_samples = YOUR_CODE_HERE - mu_V_samples = YOUR_CODE_HERE - sigma_V_samples = YOUR_CODE_HERE - - # Compute moments using Taylor - mu_V_taylor, sigma_V_taylor = YOUR_CODE_HERE - - # Create left-side plot with histogram and normal distribution - # Plot histogram - xmin = 0 - xmax = 10 - x = np.linspace(xmin, xmax, 100) - fig, ax = plt.subplots(1, 2, figsize = (16, 6)) - - ax[0].hist(YOUR_CODE_HERE, bins = 40, density = True, - label = 'Empirical PDF of V') - - # Add normal pdf in same figure - ax[0].plot(x, norm.pdf(x, YOUR_CODE_HERE, YOUR_CODE_HERE), color = 'black', - lw = 2.5, label='Normal PDF') - - ax[0].legend() - ax[0].set_xlabel('V [$m/s$]') - ax[0].set_xlim(xmin, xmax) - ax[0].set_ylim(0, 1) - ax[0].set_ylabel('Density') - ax[0].set_title(f'Simulation with {N} simulated realizations' - + '\n' + f'mean = {round(YOUR_CODE_HERE, 3)}' - f'm/s and std = {round(YOUR_CODE_HERE, 3)} m/s') - - # Add probability plot in right-side panel - probplot(YOUR_CODE_HERE, dist = norm, fit = True, plot = ax[1]) - - ax[1].legend(['Generated samples', 'Normal fit']) - ax[1].get_lines()[1].set_linewidth(2.5) - plt.show() - -validate_distribution(10000, 0.01) -``` - -### Validate the Distribution of $V$ for Various $\sigma_R$ - -The code below uses a widget to call your function to make the plots and add a slider to change the values of $\sigma_R$ and visualize the change in the distributions. - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> - -$\textbf{Task 3.2:}$ -Run the cell below, then play with the slider to change $\sigma_R$. How well does the error propagation law match the "true" distribution (the samples)? State your conclusion and explain why. Check also whether there is an impact for different $\sigma_R$ values. -</p> -</div> - -```python colab={"base_uri": "https://localhost:8080/", "height": 475, "referenced_widgets": ["b560714d739d431d85b3ca1a9b378c8f", "56b7808a3e2241679b15d517565eaf85", "d867da2ab3d441599b8356ac8e493611", "481c67caa6d1405ea2e00cfe6dbfa32f", "392504e006074b76af62e617c4cde70e", "b0d26f90109f4e0eb6839f0ba43ba980", "ea4c3dc473df41a684cfe7fd1e7fb35d"]} id="80005a5a-510b-4236-a2d6-184d9569eed4" outputId="80ae9e8d-e450-4e17-f092-fbf09fc885e6" -@interact(sigma_R=(0, 0.1, 0.005)) -def samples_slideplot(sigma_R): - validate_distribution(50000, sigma_R); -``` - -_You can write an answer in this cell using Markdown._ - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> - -$\textbf{Task 3.3:}$ -To further validate the error propagation law, estimate the probability that the "true" velocity of the tunnel is in the inaccurate range of values (assuming that the Normal distribution is a suitable model for the distribution of the function of random variables). - -<em>Hint: recall that in this notebook a quantile, $q$, is defined as a standard deviation, and that the probability of observing a random variable $X$ such that $P[X\lt q]$ can be found with the CDF of the standard Normal distribution, evaluated in Python using <code>scipy.stats.norm.cdf(q)</code>.</em> -</p> -</div> - - -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p><em> - -$\textbf{Note:}$ -As we saw in 3.2, the Normal distribution does not fit the tails of the distribution of the function of random variables perfectly. Although this means using the Normal distribution may not be a good way of estimating the probability of "being in the tails," the approach in this Task is still suitable for getting an idea of the order of magnitude, and observing how sever this "error" maybe for different assumptions of $\sigma_R$.</em></p></div> - -```python -p = YOUR_CODE_HERE - -print(f'The probability is {p:0.6e}') -``` - -_You can write an answer in this cell using Markdown._ - - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Week_1_2/WS_1_2_Pipe_Dreams.py b/synced_files/students/Week_1_2/WS_1_2_Pipe_Dreams.py deleted file mode 100644 index a40c2a35e8bd6bbd9456e86f46bd08d5bf25229d..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_1_2/WS_1_2_Pipe_Dreams.py +++ /dev/null @@ -1,448 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: Python 3 (ipykernel) -# language: python -# name: python3 -# --- - -# %% [markdown] id="9adbf457-797f-45b7-8f8b-0e46e0e2f5ff" -# # WS 1.2: Mean and Variance Propagation -# -# **Sewer Pipe Flow Velocity** -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px; height: auto; margin: 0" /> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px; height: auto; margin: 0" /> -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.2. Wed Sep 11, 2024.* - -# %% [markdown] id="1db6fea9-f3ad-44bc-a4c8-7b2b3008e945" -# ## Overview -# -# In this notebook you will apply the propagation laws for the mean and variance for a function of two independent random variables. You will assess how well the approximations correspond with the <em>simulation-based</em> equivalents. You will also assess the distribution of the function. -# -# _You do not need to turn in this notebook._ -# -# ### Objectives -# -# 1. Observe how uncertainty "propagates" from the inputs to the output of a function by estimating moments of the function of random variables and seeing how they change relative to the moments of the input random variables. -# 2. Recognize that a non-linear function of random variables that have the (joint) Normal distribution (the inputs) produces a non-Normal random variable (the output). -# 3. Using _sampling_ (Monte Carlo Simulation) to _validate_ the linearized error propagation technique introduced in the textbook. Specifically, by: -# 1. Comparing the estimated moments with that of the sample, and -# 2. Comparing the Normal distribution defined by the estimated moments to the sample -# -# ### A Note on "Sampling" -# -# We will use Monte Carlo Simulation to create an empirical "sample" of the random values of our function of random variables, $V$ (the output). This is a commonly used approach widely used in science and engineering applications. It is a numerical way of computing the distribution of a function that is useful when analytic approaches are not possible (for example, when the input distributions are non-Normal or the function is non-linear). For our purposes today, Monte Carlo Simulation is quite simple and involves the following steps: -# -# 1. Define a function of random variables and the distributions of its input parameters. -# 2. Create a random sample of each input parameter according to the specified distribution. -# 3. Create a random sample of the output variable by computing the function for every set of input samples. -# 4. Evaluate the resulting distribution of the output. -# -# A few key points to recognize are: -# 1. As the sample size increases, the resulting distribution becomes more accurate. -# 2. This is a way to get the (approximately) "true" distribution of a function of random variables. -# 3. Accuracy is relative to the propagation of uncertainty through the function based on the assumed distributions of the input random variables. In other words, MCS can't help you if your function and distributions are poor representations of reality! -# -# ### Application: Sewer Pipe Flow Velocity -# -# We will apply Manning's formula for the flow velocity $V$ in a sewer: -# -# $$ -# V =\frac{1}{n}R^{2/3}S^{1/2} -# $$ -# -# where $R$ is the hydraulic radius of the sewer pipe (in $m$), $S$ the slope of the pipe (in $m/m$), and $n$ is the coefficient of roughness [$-$]. -# -# Both $R$ and $S$ are random variables, as it is known that sewer pipes are susceptible to deformations; $n$ is assumed to be deterministic and in our case $n=0.013$ $s/m^{1/3}$. The sewer pipe considered here has mean values $\mu_R$, $\mu_S$, and standard deviations $\sigma_R$ and $\sigma_S$; $R$ and $S$ are independent. -# -# We are now interested in the mean flow velocity in the sewer as well as the uncertainty expressed by the standard deviation. This is important for the design of the sewer system. -# -# *Disclaimer: the dimensions of the pipe come from a real case study, but some aspects of the exercise are...less realistic.* -# -# ### Programming -# -# Remember to use your `mude-base` environment when running this notebook. -# -# Some of the functions below uses <em>keyword arguments</em> to specify some of the parameter values; this is a way of setting "default" values. You can override them when using the function by specifying an alternative syntax. For example, the function here can be used in the following way to return `x=5` and `x=6`, respectively: -# -# ```python -# def test(x=5) -# return x -# -# print(test()) -# print(test(x=6)) -# ``` -# Copy/paste into a cell to explore further! -# -# Note also in the cell below that we can increase the default size of the text in our figures to make them more readable! - -# %% id="4fc6e87d-c66e-43df-a937-e969acc409f8" -import numpy as np -import matplotlib.pyplot as plt - -from scipy.stats import norm -from scipy.stats import probplot - -import ipywidgets as widgets -from ipywidgets import interact - -plt.rcParams.update({'font.size': 14}) - - -# %% [markdown] -# ### Theory: Propagation laws for a function of 2 random variables -# -# We are interested in the mean and variance of $X$, which is a function of 2 random variables: $X=q(Y_1,Y_2)$. The mean and covariance matrix of $Y$ are assumed to be known: -# -# $$\mu_Y = [\mu_1\;\mu_2]^T$$ -# -# $$\Sigma_Y = \begin{bmatrix} \sigma^2_1 & Cov(Y_1,Y_2) \\ Cov(Y_1,Y_2) & \sigma^2_2\end{bmatrix}$$ -# -# The second-order Taylor series approximation of the mean $\mu_X$ is then given by: -# -# $$\mu_X=\mathbb{E}(q(Y))\approx q(\mu_Y )+\frac{1}{2}\frac{\partial^2 q(\mu_Y )}{\partial Y_1^2 } \sigma_1^2+\frac{1}{2}\frac{\partial^2 q(\mu_Y )}{\partial Y_2^2 }\sigma_2^2+\frac{\partial^2 q(\mu_Y )}{\partial Y_1 \partial Y_2 } Cov(Y_1,Y_2) $$ -# -# In most practical situations, the second-order approximation suffices. -# -# For the variance $\sigma_X^2$ it is common to use only the first-order approximation, given by: -# -# $$\sigma^2_X \approx \left(\frac{\partial q(\mu_Y )}{\partial Y_1 } \right)^2 \sigma^2_1 +\left(\frac{\partial q(\mu_Y )}{\partial Y_2 } \right)^2 \sigma^2_2 + 2\left(\frac{\partial q(\mu_Y )}{\partial Y_1 } \right) \left(\frac{\partial q(\mu_Y )}{\partial Y_2 } \right) Cov(Y_1,Y_2)$$ - -# %% [markdown] -# ## Part 1: Apply the Propagation Laws -# -# We are interested to know how the uncertainty in $R$ and $S$ propagates into the uncertainty of the flow velocity $V$. We will first do this analytically and then implement it in code. - -# %% [markdown] id="bfadcf3f-4578-4809-acdb-625ab3a71f27" -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.1:</b> -# -# Use the Taylor series approximation to find the expression for $\mu_V$ and $\sigma_V$ as function of $\mu_R$, $\sigma_R$, $\mu_S$, $\sigma_S$. Write your answer on paper or using a tablet; later we will learn how to include images directly in our notebooks! For now you can skip this step, as you are not turning this notebook in. -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.2:</b> -# -# Complete the function below, such that <code>moments_of_taylor_approximation</code> will compute the approximated $\mu_V$ and $\sigma_V$, as found in the previous Task. -# </p> -# </div> - -# %% -def moments_of_taylor_approximation(mu_R, mu_S, sigma_R, sigma_S,n): - """Compute Taylor series approximation of mean and std of V. - - Take moments and function parameters as inputs (type float). - Returns mean and standard deviation of V (type float). - """ - - constant = 1/n - - dVdR = YOUR_CODE_HERE - dVdS = YOUR_CODE_HERE - - dVdR_2 = YOUR_CODE_HERE - dVdS_2 = YOUR_CODE_HERE - - mu_V_0 = YOUR_CODE_HERE - mu_V = YOUR_CODE_HERE - - var_V = YOUR_CODE_HERE - sigma_V = YOUR_CODE_HERE - - return mu_V, sigma_V - - -# %% [markdown] -# Now we use the Taylor approximation and make two plots of $\sigma_V$ as a function of $\sigma_R$ for the following cases: -# - $\sigma_S$ = 0.002 $m/m$ -# - $\sigma_S$ = 0 $m/m$ (i.e., slope is deterministic, not susceptible to deformation) -# -# We will use $\mu_R = 0.5 m$ and $\mu_S = 0.015 m/m$, and vary $\sigma_R$ from 0 to 0.1 $m$. - -# %% colab={"base_uri": "https://localhost:8080/", "height": 425} id="55ff8dd6-86ef-401a-9a56-02551c348698" outputId="3add4ee9-1054-4726-dc4f-72dca5c1c6c8" -n = 0.013 -mu_R = 0.5 -mu_S = 0.015 -sigma_R = np.linspace(0.0, 0.1, 50) - -# case 1 for sigma_S -sigma_S_1 = 0.002 -mu_V_1, sigma_V_1 = moments_of_taylor_approximation(mu_R, mu_S, sigma_R, sigma_S_1, n) - -# case 2 for sigma_S -sigma_S_2 = 0 -mu_V_2, sigma_V_2 = moments_of_taylor_approximation(mu_R, mu_S, sigma_R, sigma_S_2, n) - -fig, ax = plt.subplots(1, 2, figsize = (16, 6)) -# left side plot for case 1 -ax[0].plot(sigma_R, sigma_V_1, linewidth=4) -ax[0].set_ylabel(r'$\sigma_V$ [$m/s$]', size = 20) -ax[0].set_xlabel(r'$\sigma_R$ [$m$]', size = 20) -ax[0].set_title(r'$\sigma_S$ = ' + f'{sigma_S_1} $m/m$, Case 1') -ax[0].set_xlim(0, 0.1) -ax[0].set_ylim(0, 1) -# right side plot for case 2 -ax[1].plot(sigma_R, sigma_V_2, linewidth=4) -ax[1].set_ylabel(r'$\sigma_V$ [$m/s$]', size = 20) -ax[1].set_xlabel(r'$\sigma_R$ [m]', size = 20) -ax[1].set_title(r'$\sigma_S$ = ' + f'{sigma_S_2} $m/m$, Case 2') -ax[1].set_xlim(0, 0.1) -ax[1].set_ylim(0, 1) -plt.show() - - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3:</b> -# Interpret the figures above, specifically looking at differences between Case 1 and Case 2. Also look at the equations you derived to understand why for Case 1 we get a non-linear relation, and for Case 2 a linear one. -# </p> -# </div> - -# %% [markdown] -# _You can write an answer in this cell using Markdown._ - -# %% [markdown] id="a7e4c13f-a2ca-4c2d-a3e2-92d4630715a0" -# ## Part 2: Simulation-Based Propagation -# -# We will use again the following values: -# - $\mu_R = 0.5$ m -# - $\mu_S = 0.015$ m/m -# - $\sigma_R=0.05$ m -# - $\sigma_S=0.002$ m/m -# -# Furthermore, it is assumed that $R$ and $S$ are independent normally distributed random variables. We will generate at least 10,000 simulated realizations each of $R$ and $S$ using a random number generator, and then you need to use these to calculate the corresponding sample values of $V$ and find the moments of that sample. -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.1:</b> -# Complete the functions <code>function_of_random_variables</code> and <code>get_samples</code> below to define the function of random variables and then generate a sample of the output from this function, assuming the inputs are also random variables with the Normal distribution. Then find the moments of the samples. -# </p> -# </div> - -# %% -def function_of_random_variables(R, S): - V = YOUR_CODE_HERE - return V - -def get_samples(N, sigma_R, mu_R=0.5, mu_S=0.015, sigma_S=0.002, n=0.013): - """Generate random samples for V from R and S.""" - R = np.random.normal(mu_R, sigma_R, N) - S = np.random.normal(mu_S, sigma_S, N) - V = YOUR_CODE_HERE - return V - -V_samples = get_samples(10000, 0.05) - -mu_V_samples = YOUR_CODE_HERE -sigma_V_samples = YOUR_CODE_HERE - -print('Moments of the SAMPLES:') -print(f' {mu_V_samples:.4f} m/s is the mean, and') -print(f' {sigma_V_samples:.4f} m/s is the std dev.') - -mu_V_taylor, sigma_V_taylor = moments_of_taylor_approximation(mu_R, mu_S, 0.05, 0.002, n) -print('\nMoments of the TAYLOR SERIES APPROXIMATION:') -print(f' {mu_V_taylor:.4f} m/s is the mean, and') -print(f' {sigma_V_taylor:.4f} m/s is the std dev.') - - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# -# $\textbf{Task 2.2:}$ -# Are the results similar for the linearized and simulated values? Describe the difference quantitatively. Check your result also for the range of values of $\sigma_R$ from 0.01 to 0.10; are they consistent? -# </div> - -# %% [markdown] -# _You can write an answer in this cell using Markdown._ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# -# $\textbf{Task 2.3:}$ -# Run the cell with the sampling algorithm above repeatedly and look at the values printed in the cell output. Which values change? Which values do <em>not</em> change? Explain why, in each case. -# </div> - -# %% [markdown] -# _You can write an answer in this cell using Markdown._ - -# %% [markdown] -# ## Part 3: Validating the Moments with a Distribution -# -# In Part 2 we used a sample of the function of random variables to _validate_ the Taylor approximation (we found that they are generally well-approximated). Now we will assume that the function of random variables has the Normal distribution to validate the moments and see for which range of values they remain a good approximation. This is done by comparing the sample to the assumed distribution; the former is represented by a histogram (also called an empirical probability density function, PDF, when normalized), the latter by a Normal distribution with moments calculated using the Taylor approximation. -# -# We will also use a normal probability plot to assess how well the assumption that $V$ is normally distributed holds up while varying the value of $\sigma_R$, introduced next. -# -# ### Theoretical Quantiles with `probplot` -# -# The method `probplot` is built into `scipy.stats` (Documentation [here](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.probplot.html)) and _validates_ a probability model by comparing samples (i.e., data) to a theoretical distribution (in this case, Normal). The "Theoretical quantile" that is plotted on the x-axis of this plot and measures the distance from the median of a distribution, normalized by the standard deviation, such that $\mathrm{quantile}=q\cdot\sigma$. For example, $q=-1.5$ is $\mu-1.5\cdot\sigma$. The vertical axis is the value of the random variable. -# -# Because we are comparing a theoretical distribution and a sample (data) on the same plot, one of the lines is the Normal PDF, which of course will have an exact match with the _theoretical quantiles_. This is why the Normal PDF will plot as a straight line in `probplot`. Comparing the (vertical) distance between the samples and the theoretical distribution (the red line) allows us to _validate_ our model. In particular, it allows us to validate the model for different regions of the distribution. In your interpretation, for example, you should try and identify whether the model is a good fit for the center and/or tails of the distribution. -# -# Note that `probplot` needs to know what to use for samples (you will tell it this), and what type of theoretical distribution you are using (we already did this for you...`norm`). - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 3.1:</b> -# Complete the function <code>validate_distribution</code> below (instructions are in the docstring) to plot the empirical probability density function (PDF) of $V$ using your simulated samples. Also plot the Normal PDF in the same figure using the moments computed from the error propagation law. -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p><em>Hint: if you are struggling with the code below, re-read the introduction to Part 3 carefully!</em></p></div> - -# %% colab={"base_uri": "https://localhost:8080/", "height": 475, "referenced_widgets": ["b560714d739d431d85b3ca1a9b378c8f", "56b7808a3e2241679b15d517565eaf85", "d867da2ab3d441599b8356ac8e493611", "481c67caa6d1405ea2e00cfe6dbfa32f", "392504e006074b76af62e617c4cde70e", "b0d26f90109f4e0eb6839f0ba43ba980", "ea4c3dc473df41a684cfe7fd1e7fb35d"]} id="80005a5a-510b-4236-a2d6-184d9569eed4" outputId="80ae9e8d-e450-4e17-f092-fbf09fc885e6" -def validate_distribution(N, sigma_R, mu_R=0.5, mu_S=0.015, sigma_S=0.002, n=0.013): - """Generate samples and plots for V - - Compares the sampled distribution of V to a Normal distribution defined - by the first moments of the error propagation law. - - Comparison is made via two plots: - 1. PDF of V~N(mu,sigma) (the approximation) and a histogram (sample) - 2. Probability plot, compares quantiles of sample and CDF of V - - Only a plot is returned. - - MUDE students fill in the missing code (see: YOUR_CODE_HERE): - 1. Generate samples and find moments - 2. Find moments of the function of random variables using Taylor series - 3. Enter data for the histogram - 4. Define the moments of the Normal distribution to be plotted - 5. Identify the appropriate variables to be printed in the plot titles - 6. Enter the data required for the probability plot - """ - - # Generate a sample and compute moments - V_samples = YOUR_CODE_HERE - mu_V_samples = YOUR_CODE_HERE - sigma_V_samples = YOUR_CODE_HERE - - # Compute moments using Taylor - mu_V_taylor, sigma_V_taylor = YOUR_CODE_HERE - - # Create left-side plot with histogram and normal distribution - # Plot histogram - xmin = 0 - xmax = 10 - x = np.linspace(xmin, xmax, 100) - fig, ax = plt.subplots(1, 2, figsize = (16, 6)) - - ax[0].hist(YOUR_CODE_HERE, bins = 40, density = True, - label = 'Empirical PDF of V') - - # Add normal pdf in same figure - ax[0].plot(x, norm.pdf(x, YOUR_CODE_HERE, YOUR_CODE_HERE), color = 'black', - lw = 2.5, label='Normal PDF') - - ax[0].legend() - ax[0].set_xlabel('V [$m/s$]') - ax[0].set_xlim(xmin, xmax) - ax[0].set_ylim(0, 1) - ax[0].set_ylabel('Density') - ax[0].set_title(f'Simulation with {N} simulated realizations' - + '\n' + f'mean = {round(YOUR_CODE_HERE, 3)}' - f'm/s and std = {round(YOUR_CODE_HERE, 3)} m/s') - - # Add probability plot in right-side panel - probplot(YOUR_CODE_HERE, dist = norm, fit = True, plot = ax[1]) - - ax[1].legend(['Generated samples', 'Normal fit']) - ax[1].get_lines()[1].set_linewidth(2.5) - plt.show() - -validate_distribution(10000, 0.01) - - -# %% [markdown] -# ### Validate the Distribution of $V$ for Various $\sigma_R$ -# -# The code below uses a widget to call your function to make the plots and add a slider to change the values of $\sigma_R$ and visualize the change in the distributions. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# -# $\textbf{Task 3.2:}$ -# Run the cell below, then play with the slider to change $\sigma_R$. How well does the error propagation law match the "true" distribution (the samples)? State your conclusion and explain why. Check also whether there is an impact for different $\sigma_R$ values. -# </p> -# </div> - -# %% colab={"base_uri": "https://localhost:8080/", "height": 475, "referenced_widgets": ["b560714d739d431d85b3ca1a9b378c8f", "56b7808a3e2241679b15d517565eaf85", "d867da2ab3d441599b8356ac8e493611", "481c67caa6d1405ea2e00cfe6dbfa32f", "392504e006074b76af62e617c4cde70e", "b0d26f90109f4e0eb6839f0ba43ba980", "ea4c3dc473df41a684cfe7fd1e7fb35d"]} id="80005a5a-510b-4236-a2d6-184d9569eed4" outputId="80ae9e8d-e450-4e17-f092-fbf09fc885e6" -@interact(sigma_R=(0, 0.1, 0.005)) -def samples_slideplot(sigma_R): - validate_distribution(50000, sigma_R); - - -# %% [markdown] -# _You can write an answer in this cell using Markdown._ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# -# $\textbf{Task 3.3:}$ -# To further validate the error propagation law, estimate the probability that the "true" velocity of the tunnel is in the inaccurate range of values (assuming that the Normal distribution is a suitable model for the distribution of the function of random variables). -# -# <em>Hint: recall that in this notebook a quantile, $q$, is defined as a standard deviation, and that the probability of observing a random variable $X$ such that $P[X\lt q]$ can be found with the CDF of the standard Normal distribution, evaluated in Python using <code>scipy.stats.norm.cdf(q)</code>.</em> -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p><em> -# -# $\textbf{Note:}$ -# As we saw in 3.2, the Normal distribution does not fit the tails of the distribution of the function of random variables perfectly. Although this means using the Normal distribution may not be a good way of estimating the probability of "being in the tails," the approach in this Task is still suitable for getting an idea of the order of magnitude, and observing how sever this "error" maybe for different assumptions of $\sigma_R$.</em></p></div> - -# %% -p = YOUR_CODE_HERE - -print(f'The probability is {p:0.6e}') - -# %% [markdown] -# _You can write an answer in this cell using Markdown._ - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Week_1_3/WS_1_3_Moving_Ice.ipynb b/synced_files/students/Week_1_3/WS_1_3_Moving_Ice.ipynb deleted file mode 100644 index 4f19f2c7d0658ce662aec64ec295a2ef44655106..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_1_3/WS_1_3_Moving_Ice.ipynb +++ /dev/null @@ -1,569 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "# Workshop 2: Is it Melting?\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px; height: auto; margin: 0\" />\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px; height: auto; margin: 0\" />\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.3. Wednesday, Sep 18, 2024.*" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this notebook you will fit a model to a time series of height observations of a point on a glacier, to assess whether it is melting. \n", - "\n", - "**Learning objectives:**\n", - "- apply least-squares (LS) and best linear unbiased (BLU) estimation\n", - "- evaluate the precision of the estimated parameters\n", - "- discuss the differences between least-squares and best linear unbiased estimation" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You have 12 monthly measurements of the height of a point on a glacier. The measurements are obtained from a satellite laser altimeter. The observations are given in the code below.\n", - "\n", - "We will fit a model assuming a linear trend (constant velocity) to account for the melting, plus an annual signal due to the seasonal impact on ice. Formulating a generalized form of this model is part of your task below. Note, however, that the periodic signal can be implemented in many ways. For this assignment you can assume that the periodic term is implemented as follows:\n", - "\n", - "$$\n", - "\\cos(2 \\pi t / 12 + \\phi)\n", - "$$\n", - "\n", - "where $\\phi$ is the phase angle, which we will assume is 0 for this workshop and will leave out of the model formulation in order to keep our model linear (i.e., leave it out of the A-matrix).\n", - "\n", - "The precision (1 $\\sigma$) of the first six observations is 0.7 meter, the last six observations have a precision of 2 meter due to a change in the settings of the instrument. All observations are mutually independent." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from scipy.stats import norm\n", - "import matplotlib.pyplot as plt\n", - "\n", - "\n", - "# this will print all float arrays with 3 decimal places\n", - "float_formatter = \"{:.3f}\".format\n", - "np.set_printoptions(formatter={'float_kind':float_formatter})\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Part 1: Observation model\n", - "\n", - "First we will construct the observation model, based on the following information that is provided: times of observations, observed heights and number of observations. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Task 1.1}:$\n", - "\n", - "Complete the definition of the observation time array <code>times</code> and define the other variables such that the print statements correctly describe the design matrix <code>A</code>.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y = [59.82, 57.20, 59.09, 59.49, 59.68, 59.34, 60.95, 59.34, 55.38, 54.33, 48.71, 48.47]\n", - "\n", - "times = YOUR_CODE_HERE\n", - "number_of_observations = YOUR_CODE_HERE\n", - "number_of_parameters = YOUR_CODE_HERE\n", - "print(f'Dimensions of the design matrix A:')\n", - "print(f' {YOUR_CODE_HERE} rows')\n", - "print(f' {YOUR_CODE_HERE} columns')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, we need to assemble the design matrix in Python. Rather than enter each value manually, we have a few tricks to make this easier. Here is an example Python cell that illustrates how one-dimensional arrays (i.e., columns or rows) can be assembled into a matrix in two ways:\n", - "1. As diagonal elements, and \n", - "2. As parallel elements (columns, in this case)\n", - "\n", - "Note also the use of `np.ones()` to quickly make a row or column of any size with the same values in each element." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "column_1 = np.array([33333, 0, 0])\n", - "column_2 = 99999*np.ones(3)\n", - "\n", - "example_1 = np.diagflat([column_1, column_2])\n", - "example_2 = np.column_stack((column_1, column_2))\n", - "\n", - "print(example_1, '\\n\\n', example_2)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\"> <p>See documentation on <a href=\"https://numpy.org/doc/stable/reference/generated/numpy.diagflat.html#numpy.diagflat\" target=\"_blank\">np.diagflat</a> and <a href=\"https://numpy.org/doc/stable/reference/generated/numpy.column_stack.html\" target=\"_blank\">np.column_stack</a> if you would like to understand more about these Numpy methods.</p></div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Task 1.2}:$\n", - "\n", - "Complete the $\\mathrm{A}$-matrix (design matrix) and covariance matrix $\\Sigma_Y$ (stochastic model) as a linear trend with an annual signal. The <code>assert</code> statement is used to confirm that the dimensions of your design matrix are correct (an error will occur if not).\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "A = YOUR_CODE_HERE\n", - "Sigma_Y = YOUR_CODE_HERE\n", - "\n", - "assert A.shape == (number_of_observations, number_of_parameters)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 2. Least-squares and Best linear unbiased (BLU) estimation\n", - "\n", - "The BLU estimator is a *linear* and *unbiased* estimator, which provides the *best* precision, where:\n", - "\n", - "- linear estimation: $\\hat{X}$ is a linear function of the observables $Y$,\n", - "- unbiased estimation: $\\mathbb{E}(\\hat{X})=\\mathrm{x}$,\n", - "- best precision: sum of variances, $\\sum_i \\sigma_{\\hat{x}_i}^2$, is minimized.\n", - "\n", - "The solution $\\hat{X}$ is obtained as:\n", - "$$\n", - "\\hat{X} = \\left(\\mathrm{A}^T\\Sigma_Y^{-1} \\mathrm{A} \\right)^{-1} \\mathrm{A}^T\\Sigma_Y^{-1}Y\n", - "$$\n", - "Note that here we are looking at the *estimator*, which is random, since it is expressed as a function of the observable vector $Y$. Once we have a realization $y$ of $Y$, the estimate $\\hat{\\mathrm{x}}$ can be computed.\n", - "\n", - "It can be shown that the covariance matrix of $\\hat{X}$ is given by:\n", - "$$\n", - "\\Sigma_{\\hat{X}} = \\left(\\mathrm{A}^T\\Sigma_Y^{-1} \\mathrm{A} \\right)^{-1}\n", - "$$" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Task 2.1}$\n", - "\n", - "Apply least-squares, and best linear unbiased estimation to estimate $\\mathrm{x}$. The code cell below outlines how you should compute the inverse of $\\Sigma_Y$. Compute the least squares estimates then the best linear unbiased estimate.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\"> <p>Remember that the <code>@</code> operator (matmul operator) can be used to easily carry out matrix multiplication for Numpy arrays. The transpose method of an array, <code>my_array.T</code>, is also useful.</p></div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "inv_Sigma_Y = np.linalg.inv(Sigma_Y)\n", - "\n", - "xhat_LS = YOUR_CODE_HERE\n", - "xhat_BLU = YOUR_CODE_HERE\n", - "\n", - "print('LS estimates in [m], [m/month], [m], resp.:\\t', xhat_LS)\n", - "print('BLU estimates in [m], [m/month], [m], resp.:\\t', xhat_BLU)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.2:</b> \n", - "The covariance matrix of least-squares can be obtained as well by applying the covariance propagation law.\n", - "Calculate the covariance matrix and vector with standard deviations of both the least-squares and BLU estimates. What is the precision of the estimated parameters? The diagonal of a matrix can be extracted with <a href=\"https://numpy.org/doc/stable/reference/generated/numpy.diagonal.html#numpy.diagonal\" target=\"_blank\">np.diagonal</a>.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\"> <p><em>Hint: define an intermediate variable first to collect some of the repetitive matrix terms.</em></p></div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "LT = YOUR_CODE_HERE\n", - "Sigma_xhat_LS = LT YOUR_CODE_HERE\n", - "std_xhat_LS = YOUR_CODE_HERE\n", - "\n", - "\n", - "Sigma_xhat_BLU = YOUR_CODE_HERE\n", - "std_xhat_BLU = YOUR_CODE_HERE\n", - "\n", - "print(f'Precision of LS estimates in [m], [m/month], [m], resp.:', std_xhat_LS)\n", - "print(f'Precision of BLU estimates in [m], [m/month], [m], resp.:', std_xhat_BLU)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.3:</b> \n", - "We are mostly interested in the melting rate. Discuss the estimated melting rate with respect to its precision.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "_Write your answer here._" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3. Residuals and plot with observations and fitted models.\n", - "\n", - "Run the code below (no changes needed) to calculate the weighted squared norm of residuals with both estimation methods, and create plots of the observations and fitted models. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "eTe_LS = (y - A @ xhat_LS).T @ (y - A @ xhat_LS)\n", - "eTe_BLU = (y - A @ xhat_BLU).T @ inv_Sigma_Y @ (y - A @ xhat_BLU)\n", - "\n", - "print(f'Weighted squared norm of residuals with LS estimation: {eTe_LS:.3f}')\n", - "print(f'Weighted squared norm of residuals with BLU estimation: {eTe_BLU:.3f}')\n", - "\n", - "plt.figure()\n", - "plt.rc('font', size=14)\n", - "plt.plot(times, y, 'kx', label='observations')\n", - "plt.plot(times, A @ xhat_LS, color='r', label='LS')\n", - "plt.plot(times, A @ xhat_BLU, color='b', label='BLU')\n", - "plt.xlim(-0.2, (number_of_observations - 1) + 0.2)\n", - "plt.xlabel('time [months]')\n", - "plt.ylabel('height [meters]')\n", - "plt.legend(loc='best');" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 3.1:</b> \n", - "<ul>\n", - " <li>Explain the difference between the fitted models.</li>\n", - " <li>Can we see from this figure which model fits better (without information about the stochastic model)?</li>\n", - "</ul>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "_Write your answer here._" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 4. Confidence bounds\n", - "In the code below you need to calculate the confidence bounds, e.g., ```CI_yhat_BLU``` is a vector with the values $k\\cdot\\sigma_{\\hat{y}_i}$ for BLUE. This will then be used to plot the confidence intervals:\n", - "$$\n", - "\\hat{y}_i \\pm k\\cdot\\sigma_{\\hat{y}_i}\n", - "$$\n", - "\n", - "Recall that $k$ can be calculated from $P(Z < k) = 1-\\frac{1}{2}\\alpha$. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Task 4.1}$\n", - "\n", - "Complete the code below to calculate the 98% confidence intervals of both the observations $y$ <b>and</b> the adjusted observations $\\hat{y}$.\n", - " \n", - "Use <code>norm.ppf</code> to compute $k_{98}$. Also try different percentages.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "yhat_LS = YOUR_CODE_HERE\n", - "Sigma_Yhat_LS = YOUR_CODE_HERE\n", - "yhat_BLU = YOUR_CODE_HERE\n", - "Sigma_Yhat_BLU = YOUR_CODE_HERE\n", - "\n", - "alpha = YOUR_CODE_HERE\n", - "k98 = YOUR_CODE_HERE\n", - "\n", - "CI_y_LS = k98\n", - "\n", - "CI_y = YOUR_CODE_HERE\n", - "CI_yhat_LS = YOUR_CODE_HERE\n", - "CI_yhat_BLU = YOUR_CODE_HERE" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can directly run the code below to create the plots." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.figure(figsize = (10,4))\n", - "plt.rc('font', size=14)\n", - "plt.subplot(121)\n", - "plt.plot(times, y, 'kx', label='observations')\n", - "plt.plot(times, yhat_LS, color='r', label='LS')\n", - "plt.plot(times, yhat_LS + CI_yhat_LS, 'r:', label=f'{100*(1-alpha):.1f}% conf.')\n", - "plt.plot(times, yhat_LS - CI_yhat_LS, 'r:')\n", - "plt.xlabel('time [months]')\n", - "plt.ylabel('height [meters]')\n", - "plt.legend(loc='best')\n", - "plt.subplot(122)\n", - "plt.plot(times, y, 'kx', label='observations')\n", - "plt.errorbar(times, y, yerr = CI_y, fmt='', capsize=5, linestyle='', color='blue', alpha=0.6)\n", - "plt.plot(times, yhat_BLU, color='b', label='BLU')\n", - "plt.plot(times, yhat_BLU + CI_yhat_BLU, 'b:', label=f'{100*(1-alpha):.1f}% conf.')\n", - "plt.plot(times, yhat_BLU - CI_yhat_BLU, 'b:')\n", - "plt.xlim(-0.2, (number_of_observations - 1) + 0.2)\n", - "plt.xlabel('time [months]')\n", - "plt.legend(loc='best');" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 4.2:</b> \n", - "Discuss the shape of the confidence bounds. Do you think the model (linear trend + annual signal) is a good choice?\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "_Write your answer here._" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 4.3:</b> \n", - "What is the BLU-estimated melting rate and the amplitude of the annual signal and their 98% confidence interval? Hint: extract the estimated values and standard deviations from <code>xhat_BLU</code> and <code>std_xhat_BLU</code>, respectively.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "rate =YOUR_CODE_HERE\n", - "CI_rate = YOUR_CODE_HERE\n", - "\n", - "amplitude = YOUR_CODE_HERE\n", - "CI_amplitude = YOUR_CODE_HERE\n", - "\n", - "print(f'The melting rate is {rate:.3f} ± {CI_rate:.3f} m/month (98% confidence level)')\n", - "print(f'The amplitude of the annual signal is {amplitude:.3f} ± {CI_amplitude:.3f} m (98% confidence level)')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 4.4:</b> \n", - "Can we conclude the glacier is melting due to climate change?\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "_Write your answer here._" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" />\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" />\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2024 <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">MUDE</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">CC BY 4.0 License</a>." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.4" - }, - "latex_envs": { - "LaTeX_envs_menu_present": true, - "autoclose": false, - "autocomplete": true, - "bibliofile": "biblio.bib", - "cite_by": "apalike", - "current_citInitial": 1, - "eqLabelWithNumbers": true, - "eqNumInitial": 1, - "hotkeys": { - "equation": "Ctrl-E", - "itemize": "Ctrl-I" - }, - "labels_anchors": false, - "latex_user_defs": false, - "report_style_numbering": false, - "user_envs_cfg": false - }, - "vscode": { - "interpreter": { - "hash": "cf78f3d1bc82cb39ac7a1165ed20acb9158792c8f97b380f92edad57bf927ea3" - } - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/synced_files/students/Week_1_3/WS_1_3_Moving_Ice.md b/synced_files/students/Week_1_3/WS_1_3_Moving_Ice.md deleted file mode 100644 index 3186b261cc60216e0ba9fba350ef86d564cad517..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_1_3/WS_1_3_Moving_Ice.md +++ /dev/null @@ -1,358 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -# Workshop 2: Is it Melting? - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px; height: auto; margin: 0" /> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px; height: auto; margin: 0" /> -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.3. Wednesday, Sep 18, 2024.* - - -In this notebook you will fit a model to a time series of height observations of a point on a glacier, to assess whether it is melting. - -**Learning objectives:** -- apply least-squares (LS) and best linear unbiased (BLU) estimation -- evaluate the precision of the estimated parameters -- discuss the differences between least-squares and best linear unbiased estimation - - -You have 12 monthly measurements of the height of a point on a glacier. The measurements are obtained from a satellite laser altimeter. The observations are given in the code below. - -We will fit a model assuming a linear trend (constant velocity) to account for the melting, plus an annual signal due to the seasonal impact on ice. Formulating a generalized form of this model is part of your task below. Note, however, that the periodic signal can be implemented in many ways. For this assignment you can assume that the periodic term is implemented as follows: - -$$ -\cos(2 \pi t / 12 + \phi) -$$ - -where $\phi$ is the phase angle, which we will assume is 0 for this workshop and will leave out of the model formulation in order to keep our model linear (i.e., leave it out of the A-matrix). - -The precision (1 $\sigma$) of the first six observations is 0.7 meter, the last six observations have a precision of 2 meter due to a change in the settings of the instrument. All observations are mutually independent. - -```python -import numpy as np -from scipy.stats import norm -import matplotlib.pyplot as plt - - -# this will print all float arrays with 3 decimal places -float_formatter = "{:.3f}".format -np.set_printoptions(formatter={'float_kind':float_formatter}) - - -``` - -## Part 1: Observation model - -First we will construct the observation model, based on the following information that is provided: times of observations, observed heights and number of observations. - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Task 1.1}:$ - -Complete the definition of the observation time array <code>times</code> and define the other variables such that the print statements correctly describe the design matrix <code>A</code>. -</p> -</div> - -```python -y = [59.82, 57.20, 59.09, 59.49, 59.68, 59.34, 60.95, 59.34, 55.38, 54.33, 48.71, 48.47] - -times = YOUR_CODE_HERE -number_of_observations = YOUR_CODE_HERE -number_of_parameters = YOUR_CODE_HERE -print(f'Dimensions of the design matrix A:') -print(f' {YOUR_CODE_HERE} rows') -print(f' {YOUR_CODE_HERE} columns') -``` - -Next, we need to assemble the design matrix in Python. Rather than enter each value manually, we have a few tricks to make this easier. Here is an example Python cell that illustrates how one-dimensional arrays (i.e., columns or rows) can be assembled into a matrix in two ways: -1. As diagonal elements, and -2. As parallel elements (columns, in this case) - -Note also the use of `np.ones()` to quickly make a row or column of any size with the same values in each element. - -```python -column_1 = np.array([33333, 0, 0]) -column_2 = 99999*np.ones(3) - -example_1 = np.diagflat([column_1, column_2]) -example_2 = np.column_stack((column_1, column_2)) - -print(example_1, '\n\n', example_2) - -``` - -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>See documentation on <a href="https://numpy.org/doc/stable/reference/generated/numpy.diagflat.html#numpy.diagflat" target="_blank">np.diagflat</a> and <a href="https://numpy.org/doc/stable/reference/generated/numpy.column_stack.html" target="_blank">np.column_stack</a> if you would like to understand more about these Numpy methods.</p></div> - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Task 1.2}:$ - -Complete the $\mathrm{A}$-matrix (design matrix) and covariance matrix $\Sigma_Y$ (stochastic model) as a linear trend with an annual signal. The <code>assert</code> statement is used to confirm that the dimensions of your design matrix are correct (an error will occur if not). -</p> -</div> - -```python -A = YOUR_CODE_HERE -Sigma_Y = YOUR_CODE_HERE - -assert A.shape == (number_of_observations, number_of_parameters) -``` - -## 2. Least-squares and Best linear unbiased (BLU) estimation - -The BLU estimator is a *linear* and *unbiased* estimator, which provides the *best* precision, where: - -- linear estimation: $\hat{X}$ is a linear function of the observables $Y$, -- unbiased estimation: $\mathbb{E}(\hat{X})=\mathrm{x}$, -- best precision: sum of variances, $\sum_i \sigma_{\hat{x}_i}^2$, is minimized. - -The solution $\hat{X}$ is obtained as: -$$ -\hat{X} = \left(\mathrm{A}^T\Sigma_Y^{-1} \mathrm{A} \right)^{-1} \mathrm{A}^T\Sigma_Y^{-1}Y -$$ -Note that here we are looking at the *estimator*, which is random, since it is expressed as a function of the observable vector $Y$. Once we have a realization $y$ of $Y$, the estimate $\hat{\mathrm{x}}$ can be computed. - -It can be shown that the covariance matrix of $\hat{X}$ is given by: -$$ -\Sigma_{\hat{X}} = \left(\mathrm{A}^T\Sigma_Y^{-1} \mathrm{A} \right)^{-1} -$$ - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Task 2.1}$ - -Apply least-squares, and best linear unbiased estimation to estimate $\mathrm{x}$. The code cell below outlines how you should compute the inverse of $\Sigma_Y$. Compute the least squares estimates then the best linear unbiased estimate. -</p> -</div> - - -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>Remember that the <code>@</code> operator (matmul operator) can be used to easily carry out matrix multiplication for Numpy arrays. The transpose method of an array, <code>my_array.T</code>, is also useful.</p></div> - -```python -inv_Sigma_Y = np.linalg.inv(Sigma_Y) - -xhat_LS = YOUR_CODE_HERE -xhat_BLU = YOUR_CODE_HERE - -print('LS estimates in [m], [m/month], [m], resp.:\t', xhat_LS) -print('BLU estimates in [m], [m/month], [m], resp.:\t', xhat_BLU) -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.2:</b> -The covariance matrix of least-squares can be obtained as well by applying the covariance propagation law. -Calculate the covariance matrix and vector with standard deviations of both the least-squares and BLU estimates. What is the precision of the estimated parameters? The diagonal of a matrix can be extracted with <a href="https://numpy.org/doc/stable/reference/generated/numpy.diagonal.html#numpy.diagonal" target="_blank">np.diagonal</a>. -</p> -</div> - - -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p><em>Hint: define an intermediate variable first to collect some of the repetitive matrix terms.</em></p></div> - -```python -LT = YOUR_CODE_HERE -Sigma_xhat_LS = LT YOUR_CODE_HERE -std_xhat_LS = YOUR_CODE_HERE - - -Sigma_xhat_BLU = YOUR_CODE_HERE -std_xhat_BLU = YOUR_CODE_HERE - -print(f'Precision of LS estimates in [m], [m/month], [m], resp.:', std_xhat_LS) -print(f'Precision of BLU estimates in [m], [m/month], [m], resp.:', std_xhat_BLU) -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.3:</b> -We are mostly interested in the melting rate. Discuss the estimated melting rate with respect to its precision. -</p> -</div> - - -_Write your answer here._ - - -## 3. Residuals and plot with observations and fitted models. - -Run the code below (no changes needed) to calculate the weighted squared norm of residuals with both estimation methods, and create plots of the observations and fitted models. - -```python -eTe_LS = (y - A @ xhat_LS).T @ (y - A @ xhat_LS) -eTe_BLU = (y - A @ xhat_BLU).T @ inv_Sigma_Y @ (y - A @ xhat_BLU) - -print(f'Weighted squared norm of residuals with LS estimation: {eTe_LS:.3f}') -print(f'Weighted squared norm of residuals with BLU estimation: {eTe_BLU:.3f}') - -plt.figure() -plt.rc('font', size=14) -plt.plot(times, y, 'kx', label='observations') -plt.plot(times, A @ xhat_LS, color='r', label='LS') -plt.plot(times, A @ xhat_BLU, color='b', label='BLU') -plt.xlim(-0.2, (number_of_observations - 1) + 0.2) -plt.xlabel('time [months]') -plt.ylabel('height [meters]') -plt.legend(loc='best'); -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 3.1:</b> -<ul> - <li>Explain the difference between the fitted models.</li> - <li>Can we see from this figure which model fits better (without information about the stochastic model)?</li> -</ul> -</p> -</div> - - -_Write your answer here._ - - -## 4. Confidence bounds -In the code below you need to calculate the confidence bounds, e.g., ```CI_yhat_BLU``` is a vector with the values $k\cdot\sigma_{\hat{y}_i}$ for BLUE. This will then be used to plot the confidence intervals: -$$ -\hat{y}_i \pm k\cdot\sigma_{\hat{y}_i} -$$ - -Recall that $k$ can be calculated from $P(Z < k) = 1-\frac{1}{2}\alpha$. - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Task 4.1}$ - -Complete the code below to calculate the 98% confidence intervals of both the observations $y$ <b>and</b> the adjusted observations $\hat{y}$. - -Use <code>norm.ppf</code> to compute $k_{98}$. Also try different percentages. -</p> -</div> - -```python -yhat_LS = YOUR_CODE_HERE -Sigma_Yhat_LS = YOUR_CODE_HERE -yhat_BLU = YOUR_CODE_HERE -Sigma_Yhat_BLU = YOUR_CODE_HERE - -alpha = YOUR_CODE_HERE -k98 = YOUR_CODE_HERE - -CI_y_LS = k98 - -CI_y = YOUR_CODE_HERE -CI_yhat_LS = YOUR_CODE_HERE -CI_yhat_BLU = YOUR_CODE_HERE -``` - -You can directly run the code below to create the plots. - -```python -plt.figure(figsize = (10,4)) -plt.rc('font', size=14) -plt.subplot(121) -plt.plot(times, y, 'kx', label='observations') -plt.plot(times, yhat_LS, color='r', label='LS') -plt.plot(times, yhat_LS + CI_yhat_LS, 'r:', label=f'{100*(1-alpha):.1f}% conf.') -plt.plot(times, yhat_LS - CI_yhat_LS, 'r:') -plt.xlabel('time [months]') -plt.ylabel('height [meters]') -plt.legend(loc='best') -plt.subplot(122) -plt.plot(times, y, 'kx', label='observations') -plt.errorbar(times, y, yerr = CI_y, fmt='', capsize=5, linestyle='', color='blue', alpha=0.6) -plt.plot(times, yhat_BLU, color='b', label='BLU') -plt.plot(times, yhat_BLU + CI_yhat_BLU, 'b:', label=f'{100*(1-alpha):.1f}% conf.') -plt.plot(times, yhat_BLU - CI_yhat_BLU, 'b:') -plt.xlim(-0.2, (number_of_observations - 1) + 0.2) -plt.xlabel('time [months]') -plt.legend(loc='best'); -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 4.2:</b> -Discuss the shape of the confidence bounds. Do you think the model (linear trend + annual signal) is a good choice? -</p> -</div> - - -_Write your answer here._ - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 4.3:</b> -What is the BLU-estimated melting rate and the amplitude of the annual signal and their 98% confidence interval? Hint: extract the estimated values and standard deviations from <code>xhat_BLU</code> and <code>std_xhat_BLU</code>, respectively. -</p> -</div> - -```python -rate =YOUR_CODE_HERE -CI_rate = YOUR_CODE_HERE - -amplitude = YOUR_CODE_HERE -CI_amplitude = YOUR_CODE_HERE - -print(f'The melting rate is {rate:.3f} ± {CI_rate:.3f} m/month (98% confidence level)') -print(f'The amplitude of the annual signal is {amplitude:.3f} ± {CI_amplitude:.3f} m (98% confidence level)') -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 4.4:</b> -Can we conclude the glacier is melting due to climate change? -</p> -</div> - - -_Write your answer here._ - - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Week_1_3/WS_1_3_Moving_Ice.py b/synced_files/students/Week_1_3/WS_1_3_Moving_Ice.py deleted file mode 100644 index 359c399880a46894a46fc03aa15407e865245d7a..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_1_3/WS_1_3_Moving_Ice.py +++ /dev/null @@ -1,359 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: Python 3 (ipykernel) -# language: python -# name: python3 -# --- - -# %% [markdown] -# # Workshop 2: Is it Melting? -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px; height: auto; margin: 0" /> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px; height: auto; margin: 0" /> -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.3. Wednesday, Sep 18, 2024.* - -# %% [markdown] -# In this notebook you will fit a model to a time series of height observations of a point on a glacier, to assess whether it is melting. -# -# **Learning objectives:** -# - apply least-squares (LS) and best linear unbiased (BLU) estimation -# - evaluate the precision of the estimated parameters -# - discuss the differences between least-squares and best linear unbiased estimation - -# %% [markdown] -# You have 12 monthly measurements of the height of a point on a glacier. The measurements are obtained from a satellite laser altimeter. The observations are given in the code below. -# -# We will fit a model assuming a linear trend (constant velocity) to account for the melting, plus an annual signal due to the seasonal impact on ice. Formulating a generalized form of this model is part of your task below. Note, however, that the periodic signal can be implemented in many ways. For this assignment you can assume that the periodic term is implemented as follows: -# -# $$ -# \cos(2 \pi t / 12 + \phi) -# $$ -# -# where $\phi$ is the phase angle, which we will assume is 0 for this workshop and will leave out of the model formulation in order to keep our model linear (i.e., leave it out of the A-matrix). -# -# The precision (1 $\sigma$) of the first six observations is 0.7 meter, the last six observations have a precision of 2 meter due to a change in the settings of the instrument. All observations are mutually independent. - -# %% -import numpy as np -from scipy.stats import norm -import matplotlib.pyplot as plt - - -# this will print all float arrays with 3 decimal places -float_formatter = "{:.3f}".format -np.set_printoptions(formatter={'float_kind':float_formatter}) - - - -# %% [markdown] -# ## Part 1: Observation model -# -# First we will construct the observation model, based on the following information that is provided: times of observations, observed heights and number of observations. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Task 1.1}:$ -# -# Complete the definition of the observation time array <code>times</code> and define the other variables such that the print statements correctly describe the design matrix <code>A</code>. -# </p> -# </div> - -# %% -y = [59.82, 57.20, 59.09, 59.49, 59.68, 59.34, 60.95, 59.34, 55.38, 54.33, 48.71, 48.47] - -times = YOUR_CODE_HERE -number_of_observations = YOUR_CODE_HERE -number_of_parameters = YOUR_CODE_HERE -print(f'Dimensions of the design matrix A:') -print(f' {YOUR_CODE_HERE} rows') -print(f' {YOUR_CODE_HERE} columns') - -# %% [markdown] -# Next, we need to assemble the design matrix in Python. Rather than enter each value manually, we have a few tricks to make this easier. Here is an example Python cell that illustrates how one-dimensional arrays (i.e., columns or rows) can be assembled into a matrix in two ways: -# 1. As diagonal elements, and -# 2. As parallel elements (columns, in this case) -# -# Note also the use of `np.ones()` to quickly make a row or column of any size with the same values in each element. - -# %% -column_1 = np.array([33333, 0, 0]) -column_2 = 99999*np.ones(3) - -example_1 = np.diagflat([column_1, column_2]) -example_2 = np.column_stack((column_1, column_2)) - -print(example_1, '\n\n', example_2) - - -# %% [markdown] -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>See documentation on <a href="https://numpy.org/doc/stable/reference/generated/numpy.diagflat.html#numpy.diagflat" target="_blank">np.diagflat</a> and <a href="https://numpy.org/doc/stable/reference/generated/numpy.column_stack.html" target="_blank">np.column_stack</a> if you would like to understand more about these Numpy methods.</p></div> - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Task 1.2}:$ -# -# Complete the $\mathrm{A}$-matrix (design matrix) and covariance matrix $\Sigma_Y$ (stochastic model) as a linear trend with an annual signal. The <code>assert</code> statement is used to confirm that the dimensions of your design matrix are correct (an error will occur if not). -# </p> -# </div> - -# %% -A = YOUR_CODE_HERE -Sigma_Y = YOUR_CODE_HERE - -assert A.shape == (number_of_observations, number_of_parameters) - -# %% [markdown] -# ## 2. Least-squares and Best linear unbiased (BLU) estimation -# -# The BLU estimator is a *linear* and *unbiased* estimator, which provides the *best* precision, where: -# -# - linear estimation: $\hat{X}$ is a linear function of the observables $Y$, -# - unbiased estimation: $\mathbb{E}(\hat{X})=\mathrm{x}$, -# - best precision: sum of variances, $\sum_i \sigma_{\hat{x}_i}^2$, is minimized. -# -# The solution $\hat{X}$ is obtained as: -# $$ -# \hat{X} = \left(\mathrm{A}^T\Sigma_Y^{-1} \mathrm{A} \right)^{-1} \mathrm{A}^T\Sigma_Y^{-1}Y -# $$ -# Note that here we are looking at the *estimator*, which is random, since it is expressed as a function of the observable vector $Y$. Once we have a realization $y$ of $Y$, the estimate $\hat{\mathrm{x}}$ can be computed. -# -# It can be shown that the covariance matrix of $\hat{X}$ is given by: -# $$ -# \Sigma_{\hat{X}} = \left(\mathrm{A}^T\Sigma_Y^{-1} \mathrm{A} \right)^{-1} -# $$ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Task 2.1}$ -# -# Apply least-squares, and best linear unbiased estimation to estimate $\mathrm{x}$. The code cell below outlines how you should compute the inverse of $\Sigma_Y$. Compute the least squares estimates then the best linear unbiased estimate. -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>Remember that the <code>@</code> operator (matmul operator) can be used to easily carry out matrix multiplication for Numpy arrays. The transpose method of an array, <code>my_array.T</code>, is also useful.</p></div> - -# %% -inv_Sigma_Y = np.linalg.inv(Sigma_Y) - -xhat_LS = YOUR_CODE_HERE -xhat_BLU = YOUR_CODE_HERE - -print('LS estimates in [m], [m/month], [m], resp.:\t', xhat_LS) -print('BLU estimates in [m], [m/month], [m], resp.:\t', xhat_BLU) - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.2:</b> -# The covariance matrix of least-squares can be obtained as well by applying the covariance propagation law. -# Calculate the covariance matrix and vector with standard deviations of both the least-squares and BLU estimates. What is the precision of the estimated parameters? The diagonal of a matrix can be extracted with <a href="https://numpy.org/doc/stable/reference/generated/numpy.diagonal.html#numpy.diagonal" target="_blank">np.diagonal</a>. -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p><em>Hint: define an intermediate variable first to collect some of the repetitive matrix terms.</em></p></div> - -# %% -LT = YOUR_CODE_HERE -Sigma_xhat_LS = LT YOUR_CODE_HERE -std_xhat_LS = YOUR_CODE_HERE - - -Sigma_xhat_BLU = YOUR_CODE_HERE -std_xhat_BLU = YOUR_CODE_HERE - -print(f'Precision of LS estimates in [m], [m/month], [m], resp.:', std_xhat_LS) -print(f'Precision of BLU estimates in [m], [m/month], [m], resp.:', std_xhat_BLU) - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.3:</b> -# We are mostly interested in the melting rate. Discuss the estimated melting rate with respect to its precision. -# </p> -# </div> - -# %% [markdown] -# _Write your answer here._ - -# %% [markdown] -# ## 3. Residuals and plot with observations and fitted models. -# -# Run the code below (no changes needed) to calculate the weighted squared norm of residuals with both estimation methods, and create plots of the observations and fitted models. - -# %% -eTe_LS = (y - A @ xhat_LS).T @ (y - A @ xhat_LS) -eTe_BLU = (y - A @ xhat_BLU).T @ inv_Sigma_Y @ (y - A @ xhat_BLU) - -print(f'Weighted squared norm of residuals with LS estimation: {eTe_LS:.3f}') -print(f'Weighted squared norm of residuals with BLU estimation: {eTe_BLU:.3f}') - -plt.figure() -plt.rc('font', size=14) -plt.plot(times, y, 'kx', label='observations') -plt.plot(times, A @ xhat_LS, color='r', label='LS') -plt.plot(times, A @ xhat_BLU, color='b', label='BLU') -plt.xlim(-0.2, (number_of_observations - 1) + 0.2) -plt.xlabel('time [months]') -plt.ylabel('height [meters]') -plt.legend(loc='best'); - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 3.1:</b> -# <ul> -# <li>Explain the difference between the fitted models.</li> -# <li>Can we see from this figure which model fits better (without information about the stochastic model)?</li> -# </ul> -# </p> -# </div> - -# %% [markdown] -# _Write your answer here._ - -# %% [markdown] -# ## 4. Confidence bounds -# In the code below you need to calculate the confidence bounds, e.g., ```CI_yhat_BLU``` is a vector with the values $k\cdot\sigma_{\hat{y}_i}$ for BLUE. This will then be used to plot the confidence intervals: -# $$ -# \hat{y}_i \pm k\cdot\sigma_{\hat{y}_i} -# $$ -# -# Recall that $k$ can be calculated from $P(Z < k) = 1-\frac{1}{2}\alpha$. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Task 4.1}$ -# -# Complete the code below to calculate the 98% confidence intervals of both the observations $y$ <b>and</b> the adjusted observations $\hat{y}$. -# -# Use <code>norm.ppf</code> to compute $k_{98}$. Also try different percentages. -# </p> -# </div> - -# %% -yhat_LS = YOUR_CODE_HERE -Sigma_Yhat_LS = YOUR_CODE_HERE -yhat_BLU = YOUR_CODE_HERE -Sigma_Yhat_BLU = YOUR_CODE_HERE - -alpha = YOUR_CODE_HERE -k98 = YOUR_CODE_HERE - -CI_y_LS = k98 - -CI_y = YOUR_CODE_HERE -CI_yhat_LS = YOUR_CODE_HERE -CI_yhat_BLU = YOUR_CODE_HERE - -# %% [markdown] -# You can directly run the code below to create the plots. - -# %% -plt.figure(figsize = (10,4)) -plt.rc('font', size=14) -plt.subplot(121) -plt.plot(times, y, 'kx', label='observations') -plt.plot(times, yhat_LS, color='r', label='LS') -plt.plot(times, yhat_LS + CI_yhat_LS, 'r:', label=f'{100*(1-alpha):.1f}% conf.') -plt.plot(times, yhat_LS - CI_yhat_LS, 'r:') -plt.xlabel('time [months]') -plt.ylabel('height [meters]') -plt.legend(loc='best') -plt.subplot(122) -plt.plot(times, y, 'kx', label='observations') -plt.errorbar(times, y, yerr = CI_y, fmt='', capsize=5, linestyle='', color='blue', alpha=0.6) -plt.plot(times, yhat_BLU, color='b', label='BLU') -plt.plot(times, yhat_BLU + CI_yhat_BLU, 'b:', label=f'{100*(1-alpha):.1f}% conf.') -plt.plot(times, yhat_BLU - CI_yhat_BLU, 'b:') -plt.xlim(-0.2, (number_of_observations - 1) + 0.2) -plt.xlabel('time [months]') -plt.legend(loc='best'); - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 4.2:</b> -# Discuss the shape of the confidence bounds. Do you think the model (linear trend + annual signal) is a good choice? -# </p> -# </div> - -# %% [markdown] -# _Write your answer here._ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 4.3:</b> -# What is the BLU-estimated melting rate and the amplitude of the annual signal and their 98% confidence interval? Hint: extract the estimated values and standard deviations from <code>xhat_BLU</code> and <code>std_xhat_BLU</code>, respectively. -# </p> -# </div> - -# %% -rate =YOUR_CODE_HERE -CI_rate = YOUR_CODE_HERE - -amplitude = YOUR_CODE_HERE -CI_amplitude = YOUR_CODE_HERE - -print(f'The melting rate is {rate:.3f} ± {CI_rate:.3f} m/month (98% confidence level)') -print(f'The amplitude of the annual signal is {amplitude:.3f} ± {CI_amplitude:.3f} m (98% confidence level)') - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 4.4:</b> -# Can we conclude the glacier is melting due to climate change? -# </p> -# </div> - -# %% [markdown] -# _Write your answer here._ - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Week_1_5/WS_1_5_dont_integr_hate.ipynb b/synced_files/students/Week_1_5/WS_1_5_dont_integr_hate.ipynb deleted file mode 100644 index d1a5c97f31d85310a5d15b314f59a45b64775307..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_1_5/WS_1_5_dont_integr_hate.ipynb +++ /dev/null @@ -1,778 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "6cf87eaa-cae9-436c-86f5-b64181df5850", - "metadata": {}, - "source": [ - "# Workshop 5: Exploring Numerical Summing Schemes\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 90px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px\" />\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px\" />\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.5, Wednesday, Oct 4, 2024.*" - ] - }, - { - "cell_type": "markdown", - "id": "82cfc0b4", - "metadata": {}, - "source": [ - "## Problem definition: Numerical Integration\n", - "\n", - "Integration can be used to solve differential equations and to calculate relevant quantities in diverse engineering and scientific problems. When analyzing experiments or numerical models results, a desired physical quantity may be expressed as an integral of measured/model quantities. Sometimes the analytical integration is known, then this is the most accurate and fastest solution, certainly better than computing it numerically. However, it is common that the analytic solution is unknown, then numerical integration is the way to go. \n", - "\n", - "\n", - "You will use a function with a known integral to evaluate how precise numerical integration can be. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "caebff09-a533-40aa-9115-985c78e45693", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "from scipy.interpolate import make_interp_spline\n", - "\n", - "\n", - "plt.rcParams['figure.figsize'] = (15, 5) # Set the width and height of plots in inches\n", - "plt.rcParams.update({'font.size': 13}) # Change this value to your desired font size" - ] - }, - { - "cell_type": "markdown", - "id": "a6773319", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "352f1493", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1:</b> \n", - "\n", - "Calculate and evaluate the following integral by hand: \n", - "\n", - "$$I=\\int_a^{b} f\\left(x\\right)\\mathrm{d}x = \\int_0^{3\\pi} \\left(20 \\cos(x)+3x^2\\right)\\mathrm{d}x.$$\n", - "\n", - "The result will be later used to explore how diverse numerical integration techniques work and their accuracy. \n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "fea89e84", - "metadata": {}, - "source": [ - "**Function definition**\n", - "\n", - "Let's define the python function \n", - "\n", - "\n", - "$$f\\left(x\\right) = \\left(20 \\cos x+3x^2\\right)$$ " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "98e6e3b6", - "metadata": {}, - "outputs": [], - "source": [ - "# Define the function to be later integrated\n", - "def f(x):\n", - " return 20*np.cos(x)+3*x**2" - ] - }, - { - "cell_type": "markdown", - "id": "cd6b9447", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2:</b> \n", - "\n", - "Below, call the function f written above to evaluate it at x=0. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "de1759f8", - "metadata": {}, - "outputs": [], - "source": [ - "f_at_x_equal_0 = YOUR_CODE_HERE\n", - "\n", - "print(\"f evaluated at x=0 is:\" , f_at_x_equal_0)" - ] - }, - { - "cell_type": "markdown", - "id": "f3bbdf8c", - "metadata": {}, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>NOTE:</b> Calling f(x) is equivalent to evaluating it! \n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "1c3d671e", - "metadata": {}, - "source": [ - "**Define an x vector to evaluate the function**\n", - "\n", - "The function `f(x)` exists in \"all space\". However, the integration is bounded to the limits `a to b`, $I=\\int_a^{b} f\\left(x\\right)\\mathrm{d}x = \\int_0^{3\\pi} \\left(20 \\cos(x)+3x^2\\right)\\mathrm{d}x$. \n", - "\n", - "<br><br>\n", - "Use those limits to create an x array using `linspace(a,b,n)`, where `a` is the limit to the left, `b` is the limit to the right and `n` is the number of points. Below you see the case with 5 points.\n", - "\n", - "<img src=\"linspace.jpg\" style=\"height:100px\" />\n" - ] - }, - { - "cell_type": "markdown", - "id": "add4309b", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 3:</b> \n", - "\n", - "Define the intervals `a,b` and the number of points needed to have a subinterval length $\\Delta x=\\pi$. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4b85d2a4", - "metadata": {}, - "outputs": [], - "source": [ - "a = YOUR_CODE_HERE\n", - "b = YOUR_CODE_HERE\n", - "number_of_points = YOUR_CODE_HERE\n", - "\n", - "x_values = np.linspace(YOUR_CODE_HERE)\n", - "dx = x_values[1]-x_values[0]\n", - "\n", - "print(\"x = \",x_values)\n", - "\n", - "\n", - "\n", - "# test dx value\n", - "assert abs(dx - np.pi)<1e-5, \"Oops! dx is not equal to pi. Please check your values for a, b and number of points.\"" - ] - }, - { - "cell_type": "markdown", - "id": "ec5511fb", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 4:</b> \n", - "\n", - "How do the number of points and number of subintervals relate? Write a brief answer below.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "098d751a", - "metadata": {}, - "source": [ - "**answer**: " - ] - }, - { - "cell_type": "markdown", - "id": "1049c443", - "metadata": {}, - "source": [ - "**Visualize a \"continuous\" function and list comprehension**\n", - "\n", - "For visualization purposes in the rest of the notebook, `f(x)` is here evaluated with high resolution. A \"list comprehension\" method is used for this purpose. **Understanding \"list comprehensions\" is essential to solve the rest of the notebook**.\n" - ] - }, - { - "cell_type": "markdown", - "id": "d17856b3", - "metadata": {}, - "source": [ - "**Visualize a \"continuous\" function and list comprehension**\n", - "\n", - "For visualization purposes in the rest of the notebook, `f(x)` is here evaluated with high resolution. A \"list comprehension\" method is used for this purpose, which is a special feature of the Python programming language (you learned about it in the PA!).\n" - ] - }, - { - "cell_type": "markdown", - "id": "12e2ea3d", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 5:</b> \n", - "\n", - "Three equivalent solutions to define <code>f_high_resolution</code> are shown below. The first one loops <code>x_high_resolution</code> and assigns its values to x, which is then used to evaluate f. \n", - "\n", - "The second one creates an index list based on the number of points contained in <code>x_high_resolution</code>, then loops it to evaluate f at each element of <code>x_high_resolution</code>.\n", - "\n", - "The third simply uses a function to evaluate the values.\n", - "\n", - "Which method do you find easier to read/write?\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "84f395cb", - "metadata": {}, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>NOTE:</b> although list comprehensions may look more cumbersome here, it is important tool to learn, as in more complex code it can help make the algorithm easier to read and write. In terms of computation time, list comprehensions are faster than \"regular\" for loops (both are native Python features), However, the third approach is actually the fastest in terms of numerical computation time, because Numpy ndarrays (not native Python) are optimized for efficient computation.\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "65878405", - "metadata": {}, - "outputs": [], - "source": [ - "# To plot a smooth graph of the function\n", - "x_high_resolution = np.linspace(a, b, 50)\n", - "\n", - "f_high_resolution = [ f(x) for x in x_high_resolution ] #first solution\n", - "\n", - "f_high_resolution = [ f(x_high_resolution[i]) for i in range(len(x_high_resolution))] #second solution\n", - "\n", - "\n", - "# Plotting\n", - "plt.plot(x_high_resolution, f_high_resolution, '+', markersize='12', color='black')\n", - "plt.plot(x_high_resolution, f_high_resolution, 'b')\n", - "plt.legend(['Points evaluated','Continuous function representation'])\n", - "plt.title('Function for approximation')\n", - "plt.xlabel('x')\n", - "plt.ylabel('$f(x)$');" - ] - }, - { - "cell_type": "markdown", - "id": "a9ef5459-2ffb-4bde-830c-646264c3648a", - "metadata": {}, - "source": [ - "<b>The Left Riemann Sum</b>\n", - "\n", - "This method approximates an integral by summing the area of rectangles defined with left points of the function:\n", - "\n", - "$$I_{_{left}} \\approx \\sum_{i=0}^{n-1} f(x_i)\\Delta x$$\n", - "\n", - "From now on, you will use ten points to define the function.\n", - "<br><br>\n", - "\n", - "Let's look at the implementation of the Left Riemann sum following the same methods described in task 5. The differences are that (i) the index of the vector x ignores the last point, (ii) the multiplication by $\\Delta x$ and (iii) the sum of the vector. Thus the result is not an array but a single number. \n", - "<br><br>\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "80eb6362", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 6:</b> \n", - "\n", - "Scrutinize the correct implementations below. Why is it necessary to ignore the last point in x_values? What would happen if you include it? \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d3a75fe0-017b-4e8a-b729-68412a492854", - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "x_values = np.linspace(a, b, 10) \n", - "dx = x_values[1]-x_values[0]\n", - "\n", - "# Left Riemann summation: 1st option\n", - "I_left_riemann = sum( [f(x)*dx for x in x_values[:-1]] ) #method 1\n", - "print(f\"Left Riemann Sum: {I_left_riemann: 0.3f}\")\n", - "\n", - "# Left Riemann summation: 2nd option\n", - "I_left_riemann = sum( [ f(x_values[i])*dx for i in range(len(x_values)-1) ] ) #method 2\n", - "print(f\"Left Riemann Sum: {I_left_riemann: 0.3f}\")" - ] - }, - { - "cell_type": "markdown", - "id": "409b0530", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 7:</b> \n", - "\n", - "Scrutinize the correct implementation below to visualize the bar plot (plt.bar) and location of the points (plt.plot with '*', in the line code below plt.bar) that define the height of each rectangle. \n", - "<br>\n", - "<br>\n", - "Tip: The bar plot requires one less element than the total number of points defining the function. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0c09dc12", - "metadata": {}, - "outputs": [], - "source": [ - "# Visualization\n", - "# Plot the rectangles and left corners of the elements in the riemann sum\n", - "plt.bar(x_values[:-1],[f(x) for x in x_values[:-1]], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25)\n", - "plt.plot(x_values[:-1],[f(x) for x in x_values[:-1]], '*', markersize='16', color='red')\n", - "\n", - "#Plot \"continuous\" function\n", - "plt.plot(x_high_resolution, f_high_resolution, 'b')\n", - "plt.title('Left Riemann Sum')\n", - "plt.xlabel('x')\n", - "plt.ylabel('$f(x)$');" - ] - }, - { - "cell_type": "markdown", - "id": "8906e8ab-9aa5-45db-a683-cd40a6729575", - "metadata": {}, - "source": [ - "**The Right Riemann Method**\n", - "\n", - "Similar to the left Riemann sum, this method is also algebraically simple to implement, and can be better suited to some situations, depending on the type of function you are trying to approximate. In this case, the subintervals are defined using the right-hand endpoints from the function and is represented by \n", - "\n", - "$$I_{_{right}} \\approx \\sum_{i=1}^n f(x_i)\\Delta x$$\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "0bbf4b11", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 8:</b> \n", - "\n", - "Complete the code cell below for the right Riemman method.. \n", - "\n", - "Tip: Consult the Left Riemann implementation above as a guide.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3073db6e-430c-4f17-ad88-a4f2892a55f1", - "metadata": {}, - "outputs": [], - "source": [ - "I_right_riemann = sum( [YOUR_CODE_HERE for x in YOUR_CODE_HERE] ) \n", - "\n", - "print(f\"Right Riemann Sum: {I_right_riemann: 0.3f}\")" - ] - }, - { - "cell_type": "markdown", - "id": "0cf7e125", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 9:</b> \n", - "\n", - "Complete the code cell below to visualize the right Riemman method.\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c510d26b", - "metadata": {}, - "outputs": [], - "source": [ - "# Right Riemann sum visualization\n", - "plt.bar(x_values[YOUR_CODE_HERE],[f(x) for x in x_values[YOUR_CODE_HERE]],\n", - " width=YOUR_CODE_HERE, alpha=0.5, align='edge',\n", - " edgecolor='black', linewidth=0.25)\n", - "plt.plot(x_values[YOUR_CODE_HERE],[f(x) for x in x_values[YOUR_CODE_HERE]],\n", - " '*', markersize='16', color='red')\n", - "#Plot \"continuous\" function\n", - "plt.plot(x_high_resolution, f_high_resolution, 'b')\n", - "plt.title('Right Riemann Sum')\n", - "plt.xlabel('x')\n", - "plt.ylabel('$f(x)$');" - ] - }, - { - "cell_type": "markdown", - "id": "24d26cbb-ab8f-435f-8238-0c22c0fce833", - "metadata": {}, - "source": [ - "**Midpoint Method Approximation**\n", - "\n", - "For a function defined with constant steps (uniform $\\Delta x$), the midpoint method approximates the integral taking the midpoint of the rectangle and splitting the width of the rectangle at this point. \n", - "\n", - "$$I_{_{mid}} \\approx \\sum_{i=0}^{n-1} f\\left(\\frac{x_i+x_{i+1}}{2}\\right)\\Delta x $$\n" - ] - }, - { - "cell_type": "markdown", - "id": "13d1d689", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 10:</b> \n", - "\n", - "Complete the code cell below to implement the midpoint sum below.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7ed26ad5-d2cb-450e-873d-5b21a596cedb", - "metadata": {}, - "outputs": [], - "source": [ - "I_midpoint = sum([f(YOUR_CODE_HERE)*dx for i in range(YOUR_CODE_HERE)])\n", - "print(f\"Midpoint Sum: {I_midpoint: 0.3e}\")\n", - "\n", - "I_midpoint = sum([f(x_at_the_middle)*dx for x_at_the_middle in YOUR_CODE_HERE ])\n", - "print(f\"Midpoint Sum: {I_midpoint: 0.3e}\")" - ] - }, - { - "cell_type": "markdown", - "id": "e685d8c3", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 11:</b> \n", - "\n", - "Complete the code cell below to visualize the midpoint method.\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "370672eb", - "metadata": {}, - "outputs": [], - "source": [ - "# Midpoint sum visualization\n", - "plt.bar(x_values[YOUR_CODE_HERE],[f(x_at_the_middle) for x_at_the_middle in YOUR_CODE_HERE ], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25)\n", - "plt.plot(x_values[YOUR_CODE_HERE],[f(x_at_the_middle) for x_at_the_middle in YOUR_CODE_HERE],'*',markersize='16', color='red')\n", - "#Plot \"continuous\" function\n", - "plt.plot(x_high_resolution, f_high_resolution, 'b')\n", - "plt.title('Midpoint Sum')\n", - "plt.xlabel('x')\n", - "plt.ylabel('$f(x)$');" - ] - }, - { - "cell_type": "markdown", - "id": "fcf6f8bc-5554-4309-81ce-0433fa947e34", - "metadata": {}, - "source": [ - "**Trapezoidal Rule**\n", - "\n", - "This method requires two evaluations of the function $f$ for each 'rectangle', at its left and right corners. In fact, it does not represent a 'rectangle anymore' but a trapezoid. For a 1D case, it is a rectangle with a triangle on top. \n", - "\n", - "$$I_{_{trapezoid}} \\approx \\sum_{i=0}^{n-1}\\frac{f(x_i)+f(x_{i+1})}{2}\\Delta x $$" - ] - }, - { - "cell_type": "markdown", - "id": "74bb23af", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 12:</b> \n", - "\n", - "Complete the following code to implement the trapezoidal rule for the sum. \n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b6e68930-f1d8-4d7e-8162-8cd59f985be0", - "metadata": {}, - "outputs": [], - "source": [ - "I_trapezoidal = sum([YOUR_CODE_HERE for i in range(len(x_values)-1)]) \n", - "print(f\"Trapezoidal Sum: {I_trapezoidal: 0.5e}\")" - ] - }, - { - "cell_type": "markdown", - "id": "5a3a195c", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 13:</b> \n", - "\n", - "To visualize the trapezoidal method a plt.bar is not used rather plt_fill_between. Revise the code cell below.\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "36cddace", - "metadata": {}, - "outputs": [], - "source": [ - "# Trapezoidal sum\n", - "for i in range(len(x_values)-1):\n", - " plt.fill_between([x_values[i], x_values[i+1]], \n", - " [f(x_values[i]), f(x_values[i+1])], \n", - " alpha=0.5)\n", - "\n", - "#Plot \"continuous\" function\n", - "plt.plot(x_high_resolution, f_high_resolution, 'b')\n", - "plt.title('Trapezoidal Sum')\n", - "plt.xlabel('x')\n", - "plt.ylabel('$f(x)$');\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "14295e08-e9db-4735-927d-715989b62b81", - "metadata": {}, - "source": [ - "**Absolute errors in integral**" - ] - }, - { - "cell_type": "markdown", - "id": "d6b0720c", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 14:</b> \n", - "\n", - "Compute the absolute errors of each method. Are they similar to your expectatations? (i.e. corresponding to the orders of magnitude).\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "582e66ed-2016-4a84-a5f4-6d01d49671dc", - "metadata": {}, - "outputs": [], - "source": [ - "# Calculate absolute errors\n", - "left_riemann_error = YOUR_CODE_HERE\n", - "right_riemann_error = YOUR_CODE_HERE\n", - "midpoint_error = YOUR_CODE_HERE\n", - "trapezoidal_error = YOUR_CODE_HERE\n", - "\n", - "# Print the results\n", - "print(f\"Left Riemann Error: {left_riemann_error: 0.3e}\")\n", - "print(f\"Right Riemann Error: {right_riemann_error: 0.3e}\")\n", - "print(f\"Midpoint Error: {midpoint_error: 0.3e}\")\n", - "print(f\"Trapezoidal Error: {trapezoidal_error: 0.3e}\")\n" - ] - }, - { - "cell_type": "markdown", - "id": "ddc2f16f-7065-4829-aafc-91c95cc93aaf", - "metadata": {}, - "source": [ - "**Simpson's Rule**\n", - "\n", - "Simpson's rule is a method that uses a quadratic approximation over an interval that allows the top bound of the area 'rectangle' to be defined by a polynomial. In general, it can be a better approximation for curved, but mathematically smooth functions. It also has the requirement that subintervals must be an even number, so this is something to be aware of when using it in practise. As a sum, it is defined as \n", - "\n", - "$$\\int^{b}_{a}f(x)\\mathrm{d}x\\approx \\sum_{i=1}^{n/2}\\frac{1}{3}(f(x_{2i-2})+4f(x_{2i-1})+f(x_{2i}))\\Delta x$$\n", - "\n", - "where $n$ must be an *even integer*.\n", - "\n", - " " - ] - }, - { - "cell_type": "markdown", - "id": "e0ed72e0-ced6-467c-8e01-a1b602a3613d", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Challenge</b>\n", - "\n", - "Take what you have seen in the other numerical implementation codes and implement Simpson's Rule for the same integral! A redefinition of x_values is done with 9 points instead of 10 as an uneven number of points is required to apply Simpson's Rule. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ae169f8e-2d5a-4449-8c53-c8ca399af184", - "metadata": {}, - "outputs": [], - "source": [ - "# Define Simpson's Rule here\n", - "x_values = np.linspace(YOUR_CODE_HERE)\n", - "dx = YOUR_CODE_HERE \n", - " \n", - "simpson_integral = sum([ YOUR_CODE_HERE ]) \n", - "\n", - "# Calculate the absolute error\n", - "simpson_error = YOUR_CODE_HERE\n", - "\n", - "# Print the result and error\n", - "print(f\"Simpson's Rule Integral: {simpson_integral: 0.5e}\")\n", - "print(f\"Simpson's Rule Absolute Error: {simpson_error: 0.5e}\")\n" - ] - }, - { - "cell_type": "markdown", - "id": "8ffe7a1f", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 15:</b> \n", - " \n", - " \n", - "Refine the number of points using the integration by left riemann until reaching a similar accuracy as for the trapezoidal rule. How much finer was your grid?\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "793cb6e5", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "23b8f21d", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc-sa/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\"/>\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\"/>\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2023 <a rel=\"MUDE Team\" href=\"https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=65595\">MUDE Teaching Team</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc-sa/4.0/\">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.6" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/synced_files/students/Week_1_5/WS_1_5_dont_integr_hate.md b/synced_files/students/Week_1_5/WS_1_5_dont_integr_hate.md deleted file mode 100644 index d757042067637017720023d66930276f7e558180..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_1_5/WS_1_5_dont_integr_hate.md +++ /dev/null @@ -1,497 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -# Workshop 5: Exploring Numerical Summing Schemes - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 90px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.5, Wednesday, Oct 4, 2024.* - -<!-- #region --> -## Problem definition: Numerical Integration - -Integration can be used to solve differential equations and to calculate relevant quantities in diverse engineering and scientific problems. When analyzing experiments or numerical models results, a desired physical quantity may be expressed as an integral of measured/model quantities. Sometimes the analytical integration is known, then this is the most accurate and fastest solution, certainly better than computing it numerically. However, it is common that the analytic solution is unknown, then numerical integration is the way to go. - - -You will use a function with a known integral to evaluate how precise numerical integration can be. -<!-- #endregion --> - -```python -import numpy as np -import matplotlib.pyplot as plt -from scipy.interpolate import make_interp_spline - - -plt.rcParams['figure.figsize'] = (15, 5) # Set the width and height of plots in inches -plt.rcParams.update({'font.size': 13}) # Change this value to your desired font size -``` - - - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 1:</b> - -Calculate and evaluate the following integral by hand: - -$$I=\int_a^{b} f\left(x\right)\mathrm{d}x = \int_0^{3\pi} \left(20 \cos(x)+3x^2\right)\mathrm{d}x.$$ - -The result will be later used to explore how diverse numerical integration techniques work and their accuracy. - -</p> -</div> - -<!-- #region --> -**Function definition** - -Let's define the python function - - -$$f\left(x\right) = \left(20 \cos x+3x^2\right)$$ -<!-- #endregion --> - -```python -# Define the function to be later integrated -def f(x): - return 20*np.cos(x)+3*x**2 -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 2:</b> - -Below, call the function f written above to evaluate it at x=0. -</p> -</div> - -```python -f_at_x_equal_0 = YOUR_CODE_HERE - -print("f evaluated at x=0 is:" , f_at_x_equal_0) -``` - -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>NOTE:</b> Calling f(x) is equivalent to evaluating it! - -</p> -</div> - - -**Define an x vector to evaluate the function** - -The function `f(x)` exists in "all space". However, the integration is bounded to the limits `a to b`, $I=\int_a^{b} f\left(x\right)\mathrm{d}x = \int_0^{3\pi} \left(20 \cos(x)+3x^2\right)\mathrm{d}x$. - -<br><br> -Use those limits to create an x array using `linspace(a,b,n)`, where `a` is the limit to the left, `b` is the limit to the right and `n` is the number of points. Below you see the case with 5 points. - -<img src="linspace.jpg" style="height:100px" /> - - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 3:</b> - -Define the intervals `a,b` and the number of points needed to have a subinterval length $\Delta x=\pi$. -</p> -</div> - -```python -a = YOUR_CODE_HERE -b = YOUR_CODE_HERE -number_of_points = YOUR_CODE_HERE - -x_values = np.linspace(YOUR_CODE_HERE) -dx = x_values[1]-x_values[0] - -print("x = ",x_values) - - - -# test dx value -assert abs(dx - np.pi)<1e-5, "Oops! dx is not equal to pi. Please check your values for a, b and number of points." -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 4:</b> - -How do the number of points and number of subintervals relate? Write a brief answer below. -</p> -</div> - - -**answer**: - - -**Visualize a "continuous" function and list comprehension** - -For visualization purposes in the rest of the notebook, `f(x)` is here evaluated with high resolution. A "list comprehension" method is used for this purpose. **Understanding "list comprehensions" is essential to solve the rest of the notebook**. - - - -**Visualize a "continuous" function and list comprehension** - -For visualization purposes in the rest of the notebook, `f(x)` is here evaluated with high resolution. A "list comprehension" method is used for this purpose, which is a special feature of the Python programming language (you learned about it in the PA!). - - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 5:</b> - -Three equivalent solutions to define <code>f_high_resolution</code> are shown below. The first one loops <code>x_high_resolution</code> and assigns its values to x, which is then used to evaluate f. - -The second one creates an index list based on the number of points contained in <code>x_high_resolution</code>, then loops it to evaluate f at each element of <code>x_high_resolution</code>. - -The third simply uses a function to evaluate the values. - -Which method do you find easier to read/write? -</p> -</div> - - -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>NOTE:</b> although list comprehensions may look more cumbersome here, it is important tool to learn, as in more complex code it can help make the algorithm easier to read and write. In terms of computation time, list comprehensions are faster than "regular" for loops (both are native Python features), However, the third approach is actually the fastest in terms of numerical computation time, because Numpy ndarrays (not native Python) are optimized for efficient computation. - -</p> -</div> - -```python -# To plot a smooth graph of the function -x_high_resolution = np.linspace(a, b, 50) - -f_high_resolution = [ f(x) for x in x_high_resolution ] #first solution - -f_high_resolution = [ f(x_high_resolution[i]) for i in range(len(x_high_resolution))] #second solution - - -# Plotting -plt.plot(x_high_resolution, f_high_resolution, '+', markersize='12', color='black') -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.legend(['Points evaluated','Continuous function representation']) -plt.title('Function for approximation') -plt.xlabel('x') -plt.ylabel('$f(x)$'); -``` - -<b>The Left Riemann Sum</b> - -This method approximates an integral by summing the area of rectangles defined with left points of the function: - -$$I_{_{left}} \approx \sum_{i=0}^{n-1} f(x_i)\Delta x$$ - -From now on, you will use ten points to define the function. -<br><br> - -Let's look at the implementation of the Left Riemann sum following the same methods described in task 5. The differences are that (i) the index of the vector x ignores the last point, (ii) the multiplication by $\Delta x$ and (iii) the sum of the vector. Thus the result is not an array but a single number. -<br><br> - - - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 6:</b> - -Scrutinize the correct implementations below. Why is it necessary to ignore the last point in x_values? What would happen if you include it? -</p> -</div> - -```python - -x_values = np.linspace(a, b, 10) -dx = x_values[1]-x_values[0] - -# Left Riemann summation: 1st option -I_left_riemann = sum( [f(x)*dx for x in x_values[:-1]] ) #method 1 -print(f"Left Riemann Sum: {I_left_riemann: 0.3f}") - -# Left Riemann summation: 2nd option -I_left_riemann = sum( [ f(x_values[i])*dx for i in range(len(x_values)-1) ] ) #method 2 -print(f"Left Riemann Sum: {I_left_riemann: 0.3f}") -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 7:</b> - -Scrutinize the correct implementation below to visualize the bar plot (plt.bar) and location of the points (plt.plot with '*', in the line code below plt.bar) that define the height of each rectangle. -<br> -<br> -Tip: The bar plot requires one less element than the total number of points defining the function. -</p> -</div> - -```python -# Visualization -# Plot the rectangles and left corners of the elements in the riemann sum -plt.bar(x_values[:-1],[f(x) for x in x_values[:-1]], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25) -plt.plot(x_values[:-1],[f(x) for x in x_values[:-1]], '*', markersize='16', color='red') - -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Left Riemann Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); -``` - -**The Right Riemann Method** - -Similar to the left Riemann sum, this method is also algebraically simple to implement, and can be better suited to some situations, depending on the type of function you are trying to approximate. In this case, the subintervals are defined using the right-hand endpoints from the function and is represented by - -$$I_{_{right}} \approx \sum_{i=1}^n f(x_i)\Delta x$$ - - - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 8:</b> - -Complete the code cell below for the right Riemman method.. - -Tip: Consult the Left Riemann implementation above as a guide. -</p> -</div> - -```python -I_right_riemann = sum( [YOUR_CODE_HERE for x in YOUR_CODE_HERE] ) - -print(f"Right Riemann Sum: {I_right_riemann: 0.3f}") -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 9:</b> - -Complete the code cell below to visualize the right Riemman method. - -</p> -</div> - -```python -# Right Riemann sum visualization -plt.bar(x_values[YOUR_CODE_HERE],[f(x) for x in x_values[YOUR_CODE_HERE]], - width=YOUR_CODE_HERE, alpha=0.5, align='edge', - edgecolor='black', linewidth=0.25) -plt.plot(x_values[YOUR_CODE_HERE],[f(x) for x in x_values[YOUR_CODE_HERE]], - '*', markersize='16', color='red') -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Right Riemann Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); -``` - -**Midpoint Method Approximation** - -For a function defined with constant steps (uniform $\Delta x$), the midpoint method approximates the integral taking the midpoint of the rectangle and splitting the width of the rectangle at this point. - -$$I_{_{mid}} \approx \sum_{i=0}^{n-1} f\left(\frac{x_i+x_{i+1}}{2}\right)\Delta x $$ - - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 10:</b> - -Complete the code cell below to implement the midpoint sum below. -</p> -</div> - -```python -I_midpoint = sum([f(YOUR_CODE_HERE)*dx for i in range(YOUR_CODE_HERE)]) -print(f"Midpoint Sum: {I_midpoint: 0.3e}") - -I_midpoint = sum([f(x_at_the_middle)*dx for x_at_the_middle in YOUR_CODE_HERE ]) -print(f"Midpoint Sum: {I_midpoint: 0.3e}") -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 11:</b> - -Complete the code cell below to visualize the midpoint method. - -</p> -</div> - -```python -# Midpoint sum visualization -plt.bar(x_values[YOUR_CODE_HERE],[f(x_at_the_middle) for x_at_the_middle in YOUR_CODE_HERE ], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25) -plt.plot(x_values[YOUR_CODE_HERE],[f(x_at_the_middle) for x_at_the_middle in YOUR_CODE_HERE],'*',markersize='16', color='red') -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Midpoint Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); -``` - -**Trapezoidal Rule** - -This method requires two evaluations of the function $f$ for each 'rectangle', at its left and right corners. In fact, it does not represent a 'rectangle anymore' but a trapezoid. For a 1D case, it is a rectangle with a triangle on top. - -$$I_{_{trapezoid}} \approx \sum_{i=0}^{n-1}\frac{f(x_i)+f(x_{i+1})}{2}\Delta x $$ - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 12:</b> - -Complete the following code to implement the trapezoidal rule for the sum. - -</p> -</div> - -```python -I_trapezoidal = sum([YOUR_CODE_HERE for i in range(len(x_values)-1)]) -print(f"Trapezoidal Sum: {I_trapezoidal: 0.5e}") -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 13:</b> - -To visualize the trapezoidal method a plt.bar is not used rather plt_fill_between. Revise the code cell below. - -</p> -</div> - -```python -# Trapezoidal sum -for i in range(len(x_values)-1): - plt.fill_between([x_values[i], x_values[i+1]], - [f(x_values[i]), f(x_values[i+1])], - alpha=0.5) - -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Trapezoidal Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - - -``` - -**Absolute errors in integral** - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 14:</b> - -Compute the absolute errors of each method. Are they similar to your expectatations? (i.e. corresponding to the orders of magnitude). - -</p> -</div> - -```python -# Calculate absolute errors -left_riemann_error = YOUR_CODE_HERE -right_riemann_error = YOUR_CODE_HERE -midpoint_error = YOUR_CODE_HERE -trapezoidal_error = YOUR_CODE_HERE - -# Print the results -print(f"Left Riemann Error: {left_riemann_error: 0.3e}") -print(f"Right Riemann Error: {right_riemann_error: 0.3e}") -print(f"Midpoint Error: {midpoint_error: 0.3e}") -print(f"Trapezoidal Error: {trapezoidal_error: 0.3e}") - -``` - -**Simpson's Rule** - -Simpson's rule is a method that uses a quadratic approximation over an interval that allows the top bound of the area 'rectangle' to be defined by a polynomial. In general, it can be a better approximation for curved, but mathematically smooth functions. It also has the requirement that subintervals must be an even number, so this is something to be aware of when using it in practise. As a sum, it is defined as - -$$\int^{b}_{a}f(x)\mathrm{d}x\approx \sum_{i=1}^{n/2}\frac{1}{3}(f(x_{2i-2})+4f(x_{2i-1})+f(x_{2i}))\Delta x$$ - -where $n$ must be an *even integer*. - - - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Challenge</b> - -Take what you have seen in the other numerical implementation codes and implement Simpson's Rule for the same integral! A redefinition of x_values is done with 9 points instead of 10 as an uneven number of points is required to apply Simpson's Rule. -</p> -</div> - -```python -# Define Simpson's Rule here -x_values = np.linspace(YOUR_CODE_HERE) -dx = YOUR_CODE_HERE - -simpson_integral = sum([ YOUR_CODE_HERE ]) - -# Calculate the absolute error -simpson_error = YOUR_CODE_HERE - -# Print the result and error -print(f"Simpson's Rule Integral: {simpson_integral: 0.5e}") -print(f"Simpson's Rule Absolute Error: {simpson_error: 0.5e}") - -``` - -<!-- #region --> -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 15:</b> - - -Refine the number of points using the integration by left riemann until reaching a similar accuracy as for the trapezoidal rule. How much finer was your grid? - -</p> -</div> -<!-- #endregion --> - - - - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png"/> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png"/> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2023 <a rel="MUDE Team" href="https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=65595">MUDE Teaching Team</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>. diff --git a/synced_files/students/Week_1_5/WS_1_5_dont_integr_hate.py b/synced_files/students/Week_1_5/WS_1_5_dont_integr_hate.py deleted file mode 100644 index 3a9cae8d11fcdec1af30e467e273330d2ca567b6..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_1_5/WS_1_5_dont_integr_hate.py +++ /dev/null @@ -1,497 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: Python 3 (ipykernel) -# language: python -# name: python3 -# --- - -# %% [markdown] -# # Workshop 5: Exploring Numerical Summing Schemes -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 90px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.5, Wednesday, Oct 4, 2024.* - -# %% [markdown] -# ## Problem definition: Numerical Integration -# -# Integration can be used to solve differential equations and to calculate relevant quantities in diverse engineering and scientific problems. When analyzing experiments or numerical models results, a desired physical quantity may be expressed as an integral of measured/model quantities. Sometimes the analytical integration is known, then this is the most accurate and fastest solution, certainly better than computing it numerically. However, it is common that the analytic solution is unknown, then numerical integration is the way to go. -# -# -# You will use a function with a known integral to evaluate how precise numerical integration can be. - -# %% -import numpy as np -import matplotlib.pyplot as plt -from scipy.interpolate import make_interp_spline - - -plt.rcParams['figure.figsize'] = (15, 5) # Set the width and height of plots in inches -plt.rcParams.update({'font.size': 13}) # Change this value to your desired font size - - -# %% [markdown] -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 1:</b> -# -# Calculate and evaluate the following integral by hand: -# -# $$I=\int_a^{b} f\left(x\right)\mathrm{d}x = \int_0^{3\pi} \left(20 \cos(x)+3x^2\right)\mathrm{d}x.$$ -# -# The result will be later used to explore how diverse numerical integration techniques work and their accuracy. -# -# </p> -# </div> - -# %% [markdown] -# **Function definition** -# -# Let's define the python function -# -# -# $$f\left(x\right) = \left(20 \cos x+3x^2\right)$$ - -# %% -# Define the function to be later integrated -def f(x): - return 20*np.cos(x)+3*x**2 - - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 2:</b> -# -# Below, call the function f written above to evaluate it at x=0. -# </p> -# </div> - -# %% -f_at_x_equal_0 = YOUR_CODE_HERE - -print("f evaluated at x=0 is:" , f_at_x_equal_0) - -# %% [markdown] -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>NOTE:</b> Calling f(x) is equivalent to evaluating it! -# -# </p> -# </div> - -# %% [markdown] -# **Define an x vector to evaluate the function** -# -# The function `f(x)` exists in "all space". However, the integration is bounded to the limits `a to b`, $I=\int_a^{b} f\left(x\right)\mathrm{d}x = \int_0^{3\pi} \left(20 \cos(x)+3x^2\right)\mathrm{d}x$. -# -# <br><br> -# Use those limits to create an x array using `linspace(a,b,n)`, where `a` is the limit to the left, `b` is the limit to the right and `n` is the number of points. Below you see the case with 5 points. -# -# <img src="linspace.jpg" style="height:100px" /> -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 3:</b> -# -# Define the intervals `a,b` and the number of points needed to have a subinterval length $\Delta x=\pi$. -# </p> -# </div> - -# %% -a = YOUR_CODE_HERE -b = YOUR_CODE_HERE -number_of_points = YOUR_CODE_HERE - -x_values = np.linspace(YOUR_CODE_HERE) -dx = x_values[1]-x_values[0] - -print("x = ",x_values) - - - -# test dx value -assert abs(dx - np.pi)<1e-5, "Oops! dx is not equal to pi. Please check your values for a, b and number of points." - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 4:</b> -# -# How do the number of points and number of subintervals relate? Write a brief answer below. -# </p> -# </div> - -# %% [markdown] -# **answer**: - -# %% [markdown] -# **Visualize a "continuous" function and list comprehension** -# -# For visualization purposes in the rest of the notebook, `f(x)` is here evaluated with high resolution. A "list comprehension" method is used for this purpose. **Understanding "list comprehensions" is essential to solve the rest of the notebook**. -# - -# %% [markdown] -# **Visualize a "continuous" function and list comprehension** -# -# For visualization purposes in the rest of the notebook, `f(x)` is here evaluated with high resolution. A "list comprehension" method is used for this purpose, which is a special feature of the Python programming language (you learned about it in the PA!). -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 5:</b> -# -# Three equivalent solutions to define <code>f_high_resolution</code> are shown below. The first one loops <code>x_high_resolution</code> and assigns its values to x, which is then used to evaluate f. -# -# The second one creates an index list based on the number of points contained in <code>x_high_resolution</code>, then loops it to evaluate f at each element of <code>x_high_resolution</code>. -# -# The third simply uses a function to evaluate the values. -# -# Which method do you find easier to read/write? -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>NOTE:</b> although list comprehensions may look more cumbersome here, it is important tool to learn, as in more complex code it can help make the algorithm easier to read and write. In terms of computation time, list comprehensions are faster than "regular" for loops (both are native Python features), However, the third approach is actually the fastest in terms of numerical computation time, because Numpy ndarrays (not native Python) are optimized for efficient computation. -# -# </p> -# </div> - -# %% -# To plot a smooth graph of the function -x_high_resolution = np.linspace(a, b, 50) - -f_high_resolution = [ f(x) for x in x_high_resolution ] #first solution - -f_high_resolution = [ f(x_high_resolution[i]) for i in range(len(x_high_resolution))] #second solution - - -# Plotting -plt.plot(x_high_resolution, f_high_resolution, '+', markersize='12', color='black') -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.legend(['Points evaluated','Continuous function representation']) -plt.title('Function for approximation') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - -# %% [markdown] -# <b>The Left Riemann Sum</b> -# -# This method approximates an integral by summing the area of rectangles defined with left points of the function: -# -# $$I_{_{left}} \approx \sum_{i=0}^{n-1} f(x_i)\Delta x$$ -# -# From now on, you will use ten points to define the function. -# <br><br> -# -# Let's look at the implementation of the Left Riemann sum following the same methods described in task 5. The differences are that (i) the index of the vector x ignores the last point, (ii) the multiplication by $\Delta x$ and (iii) the sum of the vector. Thus the result is not an array but a single number. -# <br><br> -# -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 6:</b> -# -# Scrutinize the correct implementations below. Why is it necessary to ignore the last point in x_values? What would happen if you include it? -# </p> -# </div> - -# %% - -x_values = np.linspace(a, b, 10) -dx = x_values[1]-x_values[0] - -# Left Riemann summation: 1st option -I_left_riemann = sum( [f(x)*dx for x in x_values[:-1]] ) #method 1 -print(f"Left Riemann Sum: {I_left_riemann: 0.3f}") - -# Left Riemann summation: 2nd option -I_left_riemann = sum( [ f(x_values[i])*dx for i in range(len(x_values)-1) ] ) #method 2 -print(f"Left Riemann Sum: {I_left_riemann: 0.3f}") - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 7:</b> -# -# Scrutinize the correct implementation below to visualize the bar plot (plt.bar) and location of the points (plt.plot with '*', in the line code below plt.bar) that define the height of each rectangle. -# <br> -# <br> -# Tip: The bar plot requires one less element than the total number of points defining the function. -# </p> -# </div> - -# %% -# Visualization -# Plot the rectangles and left corners of the elements in the riemann sum -plt.bar(x_values[:-1],[f(x) for x in x_values[:-1]], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25) -plt.plot(x_values[:-1],[f(x) for x in x_values[:-1]], '*', markersize='16', color='red') - -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Left Riemann Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - -# %% [markdown] -# **The Right Riemann Method** -# -# Similar to the left Riemann sum, this method is also algebraically simple to implement, and can be better suited to some situations, depending on the type of function you are trying to approximate. In this case, the subintervals are defined using the right-hand endpoints from the function and is represented by -# -# $$I_{_{right}} \approx \sum_{i=1}^n f(x_i)\Delta x$$ -# -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 8:</b> -# -# Complete the code cell below for the right Riemman method.. -# -# Tip: Consult the Left Riemann implementation above as a guide. -# </p> -# </div> - -# %% -I_right_riemann = sum( [YOUR_CODE_HERE for x in YOUR_CODE_HERE] ) - -print(f"Right Riemann Sum: {I_right_riemann: 0.3f}") - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 9:</b> -# -# Complete the code cell below to visualize the right Riemman method. -# -# </p> -# </div> - -# %% -# Right Riemann sum visualization -plt.bar(x_values[YOUR_CODE_HERE],[f(x) for x in x_values[YOUR_CODE_HERE]], - width=YOUR_CODE_HERE, alpha=0.5, align='edge', - edgecolor='black', linewidth=0.25) -plt.plot(x_values[YOUR_CODE_HERE],[f(x) for x in x_values[YOUR_CODE_HERE]], - '*', markersize='16', color='red') -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Right Riemann Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - -# %% [markdown] -# **Midpoint Method Approximation** -# -# For a function defined with constant steps (uniform $\Delta x$), the midpoint method approximates the integral taking the midpoint of the rectangle and splitting the width of the rectangle at this point. -# -# $$I_{_{mid}} \approx \sum_{i=0}^{n-1} f\left(\frac{x_i+x_{i+1}}{2}\right)\Delta x $$ -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 10:</b> -# -# Complete the code cell below to implement the midpoint sum below. -# </p> -# </div> - -# %% -I_midpoint = sum([f(YOUR_CODE_HERE)*dx for i in range(YOUR_CODE_HERE)]) -print(f"Midpoint Sum: {I_midpoint: 0.3e}") - -I_midpoint = sum([f(x_at_the_middle)*dx for x_at_the_middle in YOUR_CODE_HERE ]) -print(f"Midpoint Sum: {I_midpoint: 0.3e}") - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 11:</b> -# -# Complete the code cell below to visualize the midpoint method. -# -# </p> -# </div> - -# %% -# Midpoint sum visualization -plt.bar(x_values[YOUR_CODE_HERE],[f(x_at_the_middle) for x_at_the_middle in YOUR_CODE_HERE ], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25) -plt.plot(x_values[YOUR_CODE_HERE],[f(x_at_the_middle) for x_at_the_middle in YOUR_CODE_HERE],'*',markersize='16', color='red') -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Midpoint Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - -# %% [markdown] -# **Trapezoidal Rule** -# -# This method requires two evaluations of the function $f$ for each 'rectangle', at its left and right corners. In fact, it does not represent a 'rectangle anymore' but a trapezoid. For a 1D case, it is a rectangle with a triangle on top. -# -# $$I_{_{trapezoid}} \approx \sum_{i=0}^{n-1}\frac{f(x_i)+f(x_{i+1})}{2}\Delta x $$ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 12:</b> -# -# Complete the following code to implement the trapezoidal rule for the sum. -# -# </p> -# </div> - -# %% -I_trapezoidal = sum([YOUR_CODE_HERE for i in range(len(x_values)-1)]) -print(f"Trapezoidal Sum: {I_trapezoidal: 0.5e}") - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 13:</b> -# -# To visualize the trapezoidal method a plt.bar is not used rather plt_fill_between. Revise the code cell below. -# -# </p> -# </div> - -# %% -# Trapezoidal sum -for i in range(len(x_values)-1): - plt.fill_between([x_values[i], x_values[i+1]], - [f(x_values[i]), f(x_values[i+1])], - alpha=0.5) - -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Trapezoidal Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - - - -# %% [markdown] -# **Absolute errors in integral** - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 14:</b> -# -# Compute the absolute errors of each method. Are they similar to your expectatations? (i.e. corresponding to the orders of magnitude). -# -# </p> -# </div> - -# %% -# Calculate absolute errors -left_riemann_error = YOUR_CODE_HERE -right_riemann_error = YOUR_CODE_HERE -midpoint_error = YOUR_CODE_HERE -trapezoidal_error = YOUR_CODE_HERE - -# Print the results -print(f"Left Riemann Error: {left_riemann_error: 0.3e}") -print(f"Right Riemann Error: {right_riemann_error: 0.3e}") -print(f"Midpoint Error: {midpoint_error: 0.3e}") -print(f"Trapezoidal Error: {trapezoidal_error: 0.3e}") - - -# %% [markdown] -# **Simpson's Rule** -# -# Simpson's rule is a method that uses a quadratic approximation over an interval that allows the top bound of the area 'rectangle' to be defined by a polynomial. In general, it can be a better approximation for curved, but mathematically smooth functions. It also has the requirement that subintervals must be an even number, so this is something to be aware of when using it in practise. As a sum, it is defined as -# -# $$\int^{b}_{a}f(x)\mathrm{d}x\approx \sum_{i=1}^{n/2}\frac{1}{3}(f(x_{2i-2})+4f(x_{2i-1})+f(x_{2i}))\Delta x$$ -# -# where $n$ must be an *even integer*. -# -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Challenge</b> -# -# Take what you have seen in the other numerical implementation codes and implement Simpson's Rule for the same integral! A redefinition of x_values is done with 9 points instead of 10 as an uneven number of points is required to apply Simpson's Rule. -# </p> -# </div> - -# %% -# Define Simpson's Rule here -x_values = np.linspace(YOUR_CODE_HERE) -dx = YOUR_CODE_HERE - -simpson_integral = sum([ YOUR_CODE_HERE ]) - -# Calculate the absolute error -simpson_error = YOUR_CODE_HERE - -# Print the result and error -print(f"Simpson's Rule Integral: {simpson_integral: 0.5e}") -print(f"Simpson's Rule Absolute Error: {simpson_error: 0.5e}") - - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 15:</b> -# -# -# Refine the number of points using the integration by left riemann until reaching a similar accuracy as for the trapezoidal rule. How much finer was your grid? -# -# </p> -# </div> - -# %% [markdown] -# - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png"/> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png"/> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2023 <a rel="MUDE Team" href="https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=65595">MUDE Teaching Team</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>. diff --git a/synced_files/students/Week_1_6/WS_1_6_time_to_c_ode.ipynb b/synced_files/students/Week_1_6/WS_1_6_time_to_c_ode.ipynb deleted file mode 100644 index e2c18d9c1476bd3b0250199b3125ea8c44444931..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_1_6/WS_1_6_time_to_c_ode.ipynb +++ /dev/null @@ -1,861 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "1d48ad6c", - "metadata": { - "id": "9adbf457-797f-45b7-8f8b-0e46e0e2f5ff" - }, - "source": [ - "# WS 1.6: Understanding Ordinary Differential Equation\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px\" />\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px\" />\n", - "\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.6. For: 9th October, 2024.*" - ] - }, - { - "cell_type": "markdown", - "id": "366ef404", - "metadata": {}, - "source": [ - "## Overview\n", - "\n", - "\n", - "This assignment is aimed to develop an understanding of the **Ordinary Differential Equation (ODE)**. There will be two sections about cooling and heating scenerios, corresponding to the first-order and the second-order ODEs. Please go through the text that follows and perform all steps outlined therein.\n", - "\n", - "## Part 1: First-order ODE\n", - "\n", - "In the study of heat transfer, **Newton's law of cooling** is a physical law which states that the rate of heat loss of a body is directly proportional to the difference in the temperatures between the body and its environment. It can be expressed in the form of ODE, as below:\n", - "\n", - "$$\\frac{dT}{dt}=-k(T - T_s)$$\n", - "\n", - "where $T$ is the temperature of the object at time $t$, $T_s$ is the temperature of the surrounding and assumed to be constant, and $k$ is the constant that characterizes the ability of the object to exchange the\n", - "heat energy (unit 1/s), which depends on the specific material properties.\n", - "\n", - "\n", - "Now, Let's consider an object with the initial temperature of 50°C in a surrounding environment with constant temperature at 20°C. The constant of heat exchange between the object and the environment is 0.5 $s^{-1}$.\n" - ] - }, - { - "cell_type": "markdown", - "id": "73781a3c", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.1:</b>\n", - " \n", - "Suppose the considered period of time is long enough (bring it to steady state), what will be the final temperature of the object? \n", - " \n", - "**Write your answer in the following markdown cell.**\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "3081d88d", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "06320ed9", - "metadata": {}, - "source": [ - "Next, let's evaluate the temperature of the object by checking it at a series of time points." - ] - }, - { - "cell_type": "markdown", - "id": "18cbde20", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.2:</b>\n", - "\n", - "Write the algebraic representation of the ODE using Explicit Euler.\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "bec070a5", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "579a9440", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3:</b>\n", - "\n", - "Compute the temperature evolution in the next 60 seconds.\n", - "\n", - "**Please complete the missing parts of the code in each step below, which is divided into 5 substeps (a through e).**\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "88b861bc", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3a:</b> \n", - "\n", - "The time step of 5 seconds is constant. Discretize the time points, the solution vector $T$ and define the initial condition.\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b44aa057", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "\n", - "dt =YOUR_CODE_HERE \n", - "t_end =YOUR_CODE_HERE \n", - "Ts = 20 # [C] \n", - "k = 0.5 # [s^-1]\n", - "\n", - "t = YOUR_CODE_HERE\n", - "n = YOUR_CODE_HERE\n", - "T = YOUR_CODE_HERE\n", - "T[0] = YOUR_CODE_HERE\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "4586d4b6", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3b:</b> \n", - "\n", - "Implement your time discretization and find the solution from $t=0$ until $t=60$ sec. \n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0bf8247e", - "metadata": {}, - "outputs": [], - "source": [ - "for i in range(n-1):\n", - " T[i+1] = YOUR_CODE_HERE\n", - " \n", - "plt.plot(t, T, 'o-')\n", - "plt.xlabel('t (s)')\n", - "plt.ylabel('T (deg)')\n", - "plt.grid()" - ] - }, - { - "cell_type": "markdown", - "id": "ffb4547f", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3c:</b>\n", - "\n", - "Try different time steps to check the stability of the calculation. At which value the solution is stable?\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "59bcbb0a", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "8a907a09", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3d:</b>\n", - "\n", - "Obtain the mathematical expression that proves your stability criteria.\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "eb00c9ab", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "1ff1e4fe", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3e:</b>\n", - "\n", - "Now, discretize the equation using Implicit (Backward) Euler. Can you find a time step that makes the problem unstable?\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "18c73272", - "metadata": {}, - "outputs": [], - "source": [ - "dt = YOUR_CODE_HERE \n", - "t_end = 60 \n", - "Ts = 20 # [C] \n", - "k = 0.5 # [s^-1]\n", - "\n", - "t = YOUR_CODE_HERE\n", - "n = YOUR_CODE_HERE\n", - "T = YOUR_CODE_HERE\n", - "T[0] = YOUR_CODE_HERE\n", - "\n", - "for i in range(n-1):\n", - " T[i+1] = YOUR_CODE_HERE \n", - " \n", - "plt.plot(t, T, 'o-')\n", - "plt.xlabel('t (s)')\n", - "plt.ylabel('T (deg)')\n", - "plt.grid()" - ] - }, - { - "cell_type": "markdown", - "id": "2109f010", - "metadata": {}, - "source": [ - "## Part 2: Second-order ODE\n", - "\n", - "The following 1D equation describes the steady state solution of the temperature along a pin that sticks out of a furnace. The rest of the pin is exposed to the ambient. \n", - "\n", - "$$\n", - "\\frac{d^2T}{dx^2} -\\alpha(T-T_s)=0\n", - "$$\n", - "\n", - "The ambient temperature is $T_s= 30^o$ C and the temperature at the wall is $250^o$ C. The length of the pin is 0.1m. Your grid should have a spatial step of 0.02 m. Finally, $\\alpha=500$." - ] - }, - { - "cell_type": "markdown", - "id": "5bf9639d", - "metadata": {}, - "source": [ - "\n", - "The solution includes the steps:\n", - "1. Use the Taylor series to obtain an approximation for the derivatives;\n", - "2. Discretize the equation;\n", - "3. Define parameters and grid;\n", - "4. Provide boundary conditions;\n", - "5. Build matrix with solution $AT=b$\n", - "6. Solve the matrix" - ] - }, - { - "cell_type": "markdown", - "id": "babd0424", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.1:</b>\n", - "\n", - "This task has three parts: a) discretize the analytic expression into a system of equations using central differences, b) write the system of equations by hand (e.g., the matrices), and c) implement the discretized system of equations in a code cell.\n", - "\n", - "<em>Parts 2.1b and 2.1c do not need to be completed in order; in fact, it may be useful to go back and forth between the two in order to understand the problem.</em> \n", - " \n" - ] - }, - { - "cell_type": "markdown", - "id": "1f70b8e9", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.1a:</b>\n", - "\n", - "Discretize the analytic expression into a system of equations for a grid with 6 points using central differences.\n", - "\n", - "<em>Write your answer by hand using paper/tablet and include the image below.</em>\n", - " \n" - ] - }, - { - "cell_type": "markdown", - "id": "81a5f165", - "metadata": {}, - "source": [ - "_Your answer here._" - ] - }, - { - "cell_type": "markdown", - "id": "c513ff65", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.1b:</b>\n", - "\n", - "Write the system of equations by hand for a grid with 6 points. In other words, construct the matrix A and vectors T and b.\n", - "\n", - "<em>Write your answer by hand using paper/tablet and include the image below.</em>\n", - " \n" - ] - }, - { - "cell_type": "markdown", - "id": "cb9ff085", - "metadata": {}, - "source": [ - "_Your answer here._" - ] - }, - { - "cell_type": "markdown", - "id": "fae61d18", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.1c:</b>\n", - "\n", - "Implement the discretized system of equations in a code cell.\n", - "\n", - "<em>We have already done this for you! Your task is to read the cell and make sure you understand how the matrices are implemented. Reading the code should help you formulate the matrices in Task 2.1b.</em>\n", - " \n" - ] - }, - { - "cell_type": "markdown", - "id": "89fd190c", - "metadata": {}, - "source": [ - "_Add your image here._" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "53fb4f99", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np \n", - "import matplotlib.pyplot as plt\n", - "\n", - "Ts = 30\n", - "alpha = 500\n", - "dx=0.02\n", - "\n", - "# grid creation\n", - "x = np.arange(0,0.1+dx,dx)\n", - "T = np.zeros(x.shape)\n", - "n=len(x)\n", - "\n", - "# boundary conditions\n", - "T[0] = 250\n", - "T[-1] = Ts\n", - "\n", - "# Building matrix A\n", - "matrix_element = -(2+dx**2*alpha)\n", - "A = np.zeros((len(x)-2,len(x)-2))\n", - "np.fill_diagonal(A, matrix_element)\n", - "A[np.arange(n-3), np.arange(1, n-2)] = 1 # Upper diagonal\n", - "A[np.arange(1, n-2), np.arange(n-3)] = 1 # Lower diagonal\n", - "print(A.shape)\n", - "# Building vector b\n", - "b_element = -dx**2*alpha*Ts\n", - "b = np.zeros(len(x)-2) + b_element\n", - "b[0] = b[0] - T[0]\n", - "b[-1] = b[-1] - T[-1]\n", - "\n", - "# Solving the system\n", - "T[1:-1] = np.linalg.solve(A,b)\n", - "\n", - "plt.plot(x,T,'*',label='Estimated solution')\n", - "plt.xlabel('x')\n", - "plt.ylabel('T')\n", - "plt.title('Estimated solution using Central Difference method')\n", - "plt.legend()\n", - "plt.show()\n", - "\n", - "print(f'The estimated temperature at the nodes are: {[f\"{temp:.2f}\" for temp in T]} [C]')" - ] - }, - { - "cell_type": "markdown", - "id": "fab32745", - "metadata": {}, - "source": [ - "\n", - "\n", - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.2:</b>\n", - "\n", - "This task will adapt the problem from 2.1 to incorporate Neumann boundary conditions in three steps: a) writing the new matrix by hand, b) adapting the code from 2.1c, c) reflecting on what this represents physically.\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "97594dc4", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.2a:</b>\n", - "\n", - "Write the system of equations by hand for a grid with 6 points, incorporating the Neumann condition.\n", - "\n", - "Approximate the Neuman boundary $\\frac{dT}{dx}=0$ by using the Backward difference for first order differential equation of first order accuracy.\n", - "\n", - "<em>Write your answer by hand using paper/tablet and include the image below.</em>\n", - " \n" - ] - }, - { - "cell_type": "markdown", - "id": "82e00391", - "metadata": {}, - "source": [ - "_Your answer here._" - ] - }, - { - "cell_type": "markdown", - "id": "5dbe120c", - "metadata": {}, - "source": [ - "\n", - "\n", - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.2b:</b>\n", - "\n", - "Now adapt the code from Task 2.1c and revise it to incorporate the Neumann boundary condition.\n", - "\n", - "<em>Copy and past the code from 2.1c below, then modify it.</em>\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ac2255d4", - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE" - ] - }, - { - "cell_type": "markdown", - "id": "cf1cd521", - "metadata": {}, - "source": [ - "\n", - "\n", - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.2c:</b>\n", - "\n", - "Reflect on the difference between the problem solved in Task 2.1 in comparison to 2.2. How are we changing the physics of the problem being solved by changing the boundary condition? What does this mean in reality for the temperature distribution in the bar over time?\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "891da8f3", - "metadata": {}, - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cfcd00f9", - "metadata": {}, - "outputs": [], - "source": [ - "Ts = 30\n", - "alpha = 500\n", - "dx=0.02\n", - " \n", - "# grid creation\n", - "x = np.arange(0,0.1+dx,dx)\n", - "T = np.zeros(x.shape)\n", - "n=len(x)\n", - " \n", - "# boundary conditions\n", - "T[0] = 250\n", - " \n", - " \n", - "# Building matrix A\n", - "matrix_element = -(2+dx**2*alpha)\n", - "A = np.zeros((len(x)-2,len(x)-2))\n", - "np.fill_diagonal(A, matrix_element)\n", - "A[np.arange(n-3), np.arange(1, n-2)] = 1 # Upper diagonal\n", - "A[np.arange(1, n-2), np.arange(n-3)] = 1 # Lower diagonal\n", - "print(A.shape)\n", - "A[-1,-1] = -(1+dx**2*alpha) #the matrix changes\n", - " \n", - "# Building vector b\n", - "b_element = -dx**2*alpha*Ts\n", - "b = np.zeros(len(x)-2) + b_element\n", - "b[0] = b[0] - T[0]\n", - "b[-1] = b[-1] #the vector b also changes\n", - " \n", - "# Solving the system\n", - "\n", - "T[1:-1] = np.linalg.solve(A,b)\n", - "T[-1] = T[-2] \n", - "\n", - "plt.plot(x,T,'*',label='Estimated solution')\n", - "plt.xlabel('x')\n", - "plt.ylabel('T')\n", - "plt.title('Estimated solution using Central Difference method')\n", - "plt.legend()\n", - "plt.show()\n", - " \n", - "print(f'The estimated temperature at the nodes are: {[f\"{temp:.2f}\" for temp in T]} [C]')" - ] - }, - { - "cell_type": "markdown", - "id": "57632792", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.3:</b>\n", - "\n", - "Just as we did in Task 2.1, this task has three parts: a) discretize the analytic expression into a system of equations using <b>forward differences</b>, b) write the system of equations by hand (e.g., the matrices), and c) implement the discretized system of equations in a code cell.\n", - "\n", - "Here we focus on <b>Dirichlet</b> conditions again.\n", - "</div> \n" - ] - }, - { - "cell_type": "markdown", - "id": "2d4b9fb9", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.3a:</b>\n", - "\n", - "Discretize the analytic expression into a system of equations for a grid with 6 points using <b>forward differences</b>.\n", - "\n", - "<em>Write your answer by hand using paper/tablet and include the image below.</em>\n", - " \n" - ] - }, - { - "cell_type": "markdown", - "id": "1c5ec2f2", - "metadata": {}, - "source": [ - "_Your answer here._" - ] - }, - { - "cell_type": "markdown", - "id": "361f1638", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.3b:</b>\n", - "\n", - "Write the system of equations by hand for a grid with 6 points. In other words, construct the matrix A and vectors T and b.\n", - "\n", - "<em>Write your answer by hand using paper/tablet and include the image below.</em>\n", - " \n" - ] - }, - { - "cell_type": "markdown", - "id": "047a38d3", - "metadata": {}, - "source": [ - "_Your answer here._" - ] - }, - { - "cell_type": "markdown", - "id": "3996b611", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.3c:</b>\n", - "\n", - "Implement the discretized system of equations in a code cell.\n", - "\n", - "<b>This time we did not do it for you!</b> Copy the code from Task 2.1c and revise it to solve the system of equations using <b>Forward Differences</b>. Keep the Dirichlet conditions.\n", - " \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1e783d3e", - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE" - ] - }, - { - "cell_type": "markdown", - "id": "bac6bb0f", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.4:</b>\n", - "\n", - "How much finer does your grid has to be in the forward difference implementation to get a similar value at x = 0.02 as in the central difference implementation? Vary your dx.\n", - "\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "dd2ead47", - "metadata": {}, - "source": [ - "_Your answer here._" - ] - }, - { - "cell_type": "markdown", - "id": "031dca37", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Bonus Task</b> \n", - " \n", - "The matrix inversion using numpy is one way to solve the system, another is the <code>gauss_jordan</code> method, written below, and another one is the sparse matrix-based method in the cell afterwards. Here, we will just have a brief comparison to see how these solvers perform when the matrix is large. Change <code>dx</code> to 0.0002 of the original code that solves the second degree ODE and test the time it takes by each method.\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5f7cdec7", - "metadata": {}, - "outputs": [], - "source": [ - "def gauss_jordan(A, b):\n", - " \"\"\"\n", - " Solves the system of linear equations Ax = b using Gauss-Jordan elimination.\n", - " \n", - " Parameters:\n", - " A (numpy.ndarray): Coefficient matrix (n x n).\n", - " b (numpy.ndarray): Right-hand side vector (n).\n", - " \n", - " Returns:\n", - " numpy.ndarray: Solution vector (x) if the system has a unique solution.\n", - " \"\"\"\n", - " # Form the augmented matrix [A | b]\n", - " A = np.array(A, dtype=float)\n", - " b = np.array(b, dtype=float)\n", - " aug_matrix = np.hstack([A, b.reshape(-1, 1)])\n", - " \n", - " n = len(b) # Number of rows (or variables)\n", - " \n", - " for i in range(n):\n", - " # Partial pivoting to handle zero diagonal elements (optional, but more robust)\n", - " max_row = np.argmax(np.abs(aug_matrix[i:, i])) + i\n", - " if aug_matrix[max_row, i] == 0:\n", - " raise ValueError(\"The matrix is singular and cannot be solved.\")\n", - " if max_row != i:\n", - " aug_matrix[[i, max_row]] = aug_matrix[[max_row, i]]\n", - " \n", - " # Make the diagonal element 1\n", - " aug_matrix[i] = aug_matrix[i] / aug_matrix[i, i]\n", - " \n", - " # Make all other elements in the current column 0\n", - " for j in range(n):\n", - " if j != i:\n", - " aug_matrix[j] -= aug_matrix[j, i] * aug_matrix[i]\n", - " \n", - " # Extract the solution (last column of the augmented matrix)\n", - " return aug_matrix[:, -1]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fbd32c69", - "metadata": {}, - "outputs": [], - "source": [ - "import time\n", - "from scipy.sparse import csc_matrix\n", - "from scipy.sparse.linalg import spsolve\n", - "\n", - "# Inverted matrix solution\n", - "start_time = time.time()\n", - "A_inv = np.linalg.inv(A)\n", - "T[1:-1] = A_inv @ b\n", - "time_used_0 = time.time() - start_time\n", - "print(f\"The time used by direct matrix inversion solution is {time_used_0: 0.3e} sec\")\n", - "assert np.allclose(np.dot(A, T[1:-1]), b), \"Oops! The calculation is wrong..\"\n", - "\n", - "\n", - "# Gauss-jordan solution\n", - "start_time = time.time()\n", - "u1 = gauss_jordan(A, b)\n", - "time_used_1 = time.time() - start_time\n", - "print(f\"The time used by Gauss-jordan solution is {time_used_1: 0.3e} sec\")\n", - "#Check if the solution is correct:\n", - "assert np.allclose(np.dot(A, u1), b), \"Oops! The calculation is wrong..\"\n", - "\n", - "# Solution by a sparse matrix solver \n", - "start_time = time.time()\n", - "A_sparse = csc_matrix(A)# Convert A to a compressed sparse column (CSC) matrix\n", - "u2 = spsolve(A_sparse, b)\n", - "time_used_2 = time.time() - start_time\n", - "print(f\"The time used by the sparse matrix solver is {time_used_2: 0.3e} sec\")\n", - "#Check if the solution is correct:\n", - "assert np.allclose(np.dot(A, u2), b), \"Oops! The calculation is wrong..\"" - ] - }, - { - "cell_type": "markdown", - "id": "2921b3f2", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc-sa/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\"/>\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\"/>\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2023 <a rel=\"MUDE Team\" href=\"https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=65595\">MUDE Teaching Team</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc-sa/4.0/\">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "mude-base", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.4" - }, - "latex_envs": { - "LaTeX_envs_menu_present": true, - "autoclose": false, - "autocomplete": true, - "bibliofile": "biblio.bib", - "cite_by": "apalike", - "current_citInitial": 1, - "eqLabelWithNumbers": true, - "eqNumInitial": 1, - "hotkeys": { - "equation": "Ctrl-E", - "itemize": "Ctrl-I" - }, - "labels_anchors": false, - "latex_user_defs": false, - "report_style_numbering": false, - "user_envs_cfg": false - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/synced_files/students/Week_1_6/WS_1_6_time_to_c_ode.md b/synced_files/students/Week_1_6/WS_1_6_time_to_c_ode.md deleted file mode 100644 index 9a693687184a0fa895af202d674f9384a145d90d..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_1_6/WS_1_6_time_to_c_ode.md +++ /dev/null @@ -1,586 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: mude-base - language: python - name: python3 ---- - -<!-- #region id="9adbf457-797f-45b7-8f8b-0e46e0e2f5ff" --> -# WS 1.6: Understanding Ordinary Differential Equation - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> - -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.6. For: 9th October, 2024.* -<!-- #endregion --> - -<!-- #region --> -## Overview - - -This assignment is aimed to develop an understanding of the **Ordinary Differential Equation (ODE)**. There will be two sections about cooling and heating scenerios, corresponding to the first-order and the second-order ODEs. Please go through the text that follows and perform all steps outlined therein. - -## Part 1: First-order ODE - -In the study of heat transfer, **Newton's law of cooling** is a physical law which states that the rate of heat loss of a body is directly proportional to the difference in the temperatures between the body and its environment. It can be expressed in the form of ODE, as below: - -$$\frac{dT}{dt}=-k(T - T_s)$$ - -where $T$ is the temperature of the object at time $t$, $T_s$ is the temperature of the surrounding and assumed to be constant, and $k$ is the constant that characterizes the ability of the object to exchange the -heat energy (unit 1/s), which depends on the specific material properties. - - -Now, Let's consider an object with the initial temperature of 50°C in a surrounding environment with constant temperature at 20°C. The constant of heat exchange between the object and the environment is 0.5 $s^{-1}$. - -<!-- #endregion --> - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.1:</b> - -Suppose the considered period of time is long enough (bring it to steady state), what will be the final temperature of the object? - -**Write your answer in the following markdown cell.** - -</p> -</div> - - - - - -Next, let's evaluate the temperature of the object by checking it at a series of time points. - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.2:</b> - -Write the algebraic representation of the ODE using Explicit Euler. - -</p> -</div> - - - - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3:</b> - -Compute the temperature evolution in the next 60 seconds. - -**Please complete the missing parts of the code in each step below, which is divided into 5 substeps (a through e).** - -</p> -</div> - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3a:</b> - -The time step of 5 seconds is constant. Discretize the time points, the solution vector $T$ and define the initial condition. - -</p> -</div> - -```python -import numpy as np -import matplotlib.pyplot as plt - -dt =YOUR_CODE_HERE -t_end =YOUR_CODE_HERE -Ts = 20 # [C] -k = 0.5 # [s^-1] - -t = YOUR_CODE_HERE -n = YOUR_CODE_HERE -T = YOUR_CODE_HERE -T[0] = YOUR_CODE_HERE - - -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3b:</b> - -Implement your time discretization and find the solution from $t=0$ until $t=60$ sec. - -</p> -</div> - -```python -for i in range(n-1): - T[i+1] = YOUR_CODE_HERE - -plt.plot(t, T, 'o-') -plt.xlabel('t (s)') -plt.ylabel('T (deg)') -plt.grid() -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3c:</b> - -Try different time steps to check the stability of the calculation. At which value the solution is stable? - -</p> -</div> - - - - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3d:</b> - -Obtain the mathematical expression that proves your stability criteria. - -</p> -</div> - - - - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3e:</b> - -Now, discretize the equation using Implicit (Backward) Euler. Can you find a time step that makes the problem unstable? - -</p> -</div> - -```python -dt = YOUR_CODE_HERE -t_end = 60 -Ts = 20 # [C] -k = 0.5 # [s^-1] - -t = YOUR_CODE_HERE -n = YOUR_CODE_HERE -T = YOUR_CODE_HERE -T[0] = YOUR_CODE_HERE - -for i in range(n-1): - T[i+1] = YOUR_CODE_HERE - -plt.plot(t, T, 'o-') -plt.xlabel('t (s)') -plt.ylabel('T (deg)') -plt.grid() -``` - -## Part 2: Second-order ODE - -The following 1D equation describes the steady state solution of the temperature along a pin that sticks out of a furnace. The rest of the pin is exposed to the ambient. - -$$ -\frac{d^2T}{dx^2} -\alpha(T-T_s)=0 -$$ - -The ambient temperature is $T_s= 30^o$ C and the temperature at the wall is $250^o$ C. The length of the pin is 0.1m. Your grid should have a spatial step of 0.02 m. Finally, $\alpha=500$. - - - -The solution includes the steps: -1. Use the Taylor series to obtain an approximation for the derivatives; -2. Discretize the equation; -3. Define parameters and grid; -4. Provide boundary conditions; -5. Build matrix with solution $AT=b$ -6. Solve the matrix - - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.1:</b> - -This task has three parts: a) discretize the analytic expression into a system of equations using central differences, b) write the system of equations by hand (e.g., the matrices), and c) implement the discretized system of equations in a code cell. - -<em>Parts 2.1b and 2.1c do not need to be completed in order; in fact, it may be useful to go back and forth between the two in order to understand the problem.</em> - - - - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.1a:</b> - -Discretize the analytic expression into a system of equations for a grid with 6 points using central differences. - -<em>Write your answer by hand using paper/tablet and include the image below.</em> - - - - -_Your answer here._ - - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.1b:</b> - -Write the system of equations by hand for a grid with 6 points. In other words, construct the matrix A and vectors T and b. - -<em>Write your answer by hand using paper/tablet and include the image below.</em> - - - - -_Your answer here._ - - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.1c:</b> - -Implement the discretized system of equations in a code cell. - -<em>We have already done this for you! Your task is to read the cell and make sure you understand how the matrices are implemented. Reading the code should help you formulate the matrices in Task 2.1b.</em> - - - - -_Add your image here._ - -```python -import numpy as np -import matplotlib.pyplot as plt - -Ts = 30 -alpha = 500 -dx=0.02 - -# grid creation -x = np.arange(0,0.1+dx,dx) -T = np.zeros(x.shape) -n=len(x) - -# boundary conditions -T[0] = 250 -T[-1] = Ts - -# Building matrix A -matrix_element = -(2+dx**2*alpha) -A = np.zeros((len(x)-2,len(x)-2)) -np.fill_diagonal(A, matrix_element) -A[np.arange(n-3), np.arange(1, n-2)] = 1 # Upper diagonal -A[np.arange(1, n-2), np.arange(n-3)] = 1 # Lower diagonal -print(A.shape) -# Building vector b -b_element = -dx**2*alpha*Ts -b = np.zeros(len(x)-2) + b_element -b[0] = b[0] - T[0] -b[-1] = b[-1] - T[-1] - -# Solving the system -T[1:-1] = np.linalg.solve(A,b) - -plt.plot(x,T,'*',label='Estimated solution') -plt.xlabel('x') -plt.ylabel('T') -plt.title('Estimated solution using Central Difference method') -plt.legend() -plt.show() - -print(f'The estimated temperature at the nodes are: {[f"{temp:.2f}" for temp in T]} [C]') -``` - -<!-- #region --> - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.2:</b> - -This task will adapt the problem from 2.1 to incorporate Neumann boundary conditions in three steps: a) writing the new matrix by hand, b) adapting the code from 2.1c, c) reflecting on what this represents physically. - -</p> -</div> -<!-- #endregion --> - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.2a:</b> - -Write the system of equations by hand for a grid with 6 points, incorporating the Neumann condition. - -Approximate the Neuman boundary $\frac{dT}{dx}=0$ by using the Backward difference for first order differential equation of first order accuracy. - -<em>Write your answer by hand using paper/tablet and include the image below.</em> - - - - -_Your answer here._ - -<!-- #region --> - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.2b:</b> - -Now adapt the code from Task 2.1c and revise it to incorporate the Neumann boundary condition. - -<em>Copy and past the code from 2.1c below, then modify it.</em> - -</p> -</div> -<!-- #endregion --> - -```python -YOUR_CODE_HERE -``` - -<!-- #region --> - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.2c:</b> - -Reflect on the difference between the problem solved in Task 2.1 in comparison to 2.2. How are we changing the physics of the problem being solved by changing the boundary condition? What does this mean in reality for the temperature distribution in the bar over time? - -</p> -</div> -<!-- #endregion --> - - - -```python -Ts = 30 -alpha = 500 -dx=0.02 - -# grid creation -x = np.arange(0,0.1+dx,dx) -T = np.zeros(x.shape) -n=len(x) - -# boundary conditions -T[0] = 250 - - -# Building matrix A -matrix_element = -(2+dx**2*alpha) -A = np.zeros((len(x)-2,len(x)-2)) -np.fill_diagonal(A, matrix_element) -A[np.arange(n-3), np.arange(1, n-2)] = 1 # Upper diagonal -A[np.arange(1, n-2), np.arange(n-3)] = 1 # Lower diagonal -print(A.shape) -A[-1,-1] = -(1+dx**2*alpha) #the matrix changes - -# Building vector b -b_element = -dx**2*alpha*Ts -b = np.zeros(len(x)-2) + b_element -b[0] = b[0] - T[0] -b[-1] = b[-1] #the vector b also changes - -# Solving the system - -T[1:-1] = np.linalg.solve(A,b) -T[-1] = T[-2] - -plt.plot(x,T,'*',label='Estimated solution') -plt.xlabel('x') -plt.ylabel('T') -plt.title('Estimated solution using Central Difference method') -plt.legend() -plt.show() - -print(f'The estimated temperature at the nodes are: {[f"{temp:.2f}" for temp in T]} [C]') -``` - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.3:</b> - -Just as we did in Task 2.1, this task has three parts: a) discretize the analytic expression into a system of equations using <b>forward differences</b>, b) write the system of equations by hand (e.g., the matrices), and c) implement the discretized system of equations in a code cell. - -Here we focus on <b>Dirichlet</b> conditions again. -</div> - - - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.3a:</b> - -Discretize the analytic expression into a system of equations for a grid with 6 points using <b>forward differences</b>. - -<em>Write your answer by hand using paper/tablet and include the image below.</em> - - - - -_Your answer here._ - - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.3b:</b> - -Write the system of equations by hand for a grid with 6 points. In other words, construct the matrix A and vectors T and b. - -<em>Write your answer by hand using paper/tablet and include the image below.</em> - - - - -_Your answer here._ - - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.3c:</b> - -Implement the discretized system of equations in a code cell. - -<b>This time we did not do it for you!</b> Copy the code from Task 2.1c and revise it to solve the system of equations using <b>Forward Differences</b>. Keep the Dirichlet conditions. - - - -```python -YOUR_CODE_HERE -``` - -<!-- #region --> -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.4:</b> - -How much finer does your grid has to be in the forward difference implementation to get a similar value at x = 0.02 as in the central difference implementation? Vary your dx. - - -</p> -</div> -<!-- #endregion --> - -_Your answer here._ - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Bonus Task</b> - -The matrix inversion using numpy is one way to solve the system, another is the <code>gauss_jordan</code> method, written below, and another one is the sparse matrix-based method in the cell afterwards. Here, we will just have a brief comparison to see how these solvers perform when the matrix is large. Change <code>dx</code> to 0.0002 of the original code that solves the second degree ODE and test the time it takes by each method. - -</p> -</div> - -```python -def gauss_jordan(A, b): - """ - Solves the system of linear equations Ax = b using Gauss-Jordan elimination. - - Parameters: - A (numpy.ndarray): Coefficient matrix (n x n). - b (numpy.ndarray): Right-hand side vector (n). - - Returns: - numpy.ndarray: Solution vector (x) if the system has a unique solution. - """ - # Form the augmented matrix [A | b] - A = np.array(A, dtype=float) - b = np.array(b, dtype=float) - aug_matrix = np.hstack([A, b.reshape(-1, 1)]) - - n = len(b) # Number of rows (or variables) - - for i in range(n): - # Partial pivoting to handle zero diagonal elements (optional, but more robust) - max_row = np.argmax(np.abs(aug_matrix[i:, i])) + i - if aug_matrix[max_row, i] == 0: - raise ValueError("The matrix is singular and cannot be solved.") - if max_row != i: - aug_matrix[[i, max_row]] = aug_matrix[[max_row, i]] - - # Make the diagonal element 1 - aug_matrix[i] = aug_matrix[i] / aug_matrix[i, i] - - # Make all other elements in the current column 0 - for j in range(n): - if j != i: - aug_matrix[j] -= aug_matrix[j, i] * aug_matrix[i] - - # Extract the solution (last column of the augmented matrix) - return aug_matrix[:, -1] -``` - -```python -import time -from scipy.sparse import csc_matrix -from scipy.sparse.linalg import spsolve - -# Inverted matrix solution -start_time = time.time() -A_inv = np.linalg.inv(A) -T[1:-1] = A_inv @ b -time_used_0 = time.time() - start_time -print(f"The time used by direct matrix inversion solution is {time_used_0: 0.3e} sec") -assert np.allclose(np.dot(A, T[1:-1]), b), "Oops! The calculation is wrong.." - - -# Gauss-jordan solution -start_time = time.time() -u1 = gauss_jordan(A, b) -time_used_1 = time.time() - start_time -print(f"The time used by Gauss-jordan solution is {time_used_1: 0.3e} sec") -#Check if the solution is correct: -assert np.allclose(np.dot(A, u1), b), "Oops! The calculation is wrong.." - -# Solution by a sparse matrix solver -start_time = time.time() -A_sparse = csc_matrix(A)# Convert A to a compressed sparse column (CSC) matrix -u2 = spsolve(A_sparse, b) -time_used_2 = time.time() - start_time -print(f"The time used by the sparse matrix solver is {time_used_2: 0.3e} sec") -#Check if the solution is correct: -assert np.allclose(np.dot(A, u2), b), "Oops! The calculation is wrong.." -``` - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png"/> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png"/> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2023 <a rel="MUDE Team" href="https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=65595">MUDE Teaching Team</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>. diff --git a/synced_files/students/Week_1_6/WS_1_6_time_to_c_ode.py b/synced_files/students/Week_1_6/WS_1_6_time_to_c_ode.py deleted file mode 100644 index d057f05ea93d762304329617da61037001aedeb3..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_1_6/WS_1_6_time_to_c_ode.py +++ /dev/null @@ -1,582 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: mude-base -# language: python -# name: python3 -# --- - -# %% [markdown] id="9adbf457-797f-45b7-8f8b-0e46e0e2f5ff" -# # WS 1.6: Understanding Ordinary Differential Equation -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -# -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.6. For: 9th October, 2024.* - -# %% [markdown] -# ## Overview -# -# -# This assignment is aimed to develop an understanding of the **Ordinary Differential Equation (ODE)**. There will be two sections about cooling and heating scenerios, corresponding to the first-order and the second-order ODEs. Please go through the text that follows and perform all steps outlined therein. -# -# ## Part 1: First-order ODE -# -# In the study of heat transfer, **Newton's law of cooling** is a physical law which states that the rate of heat loss of a body is directly proportional to the difference in the temperatures between the body and its environment. It can be expressed in the form of ODE, as below: -# -# $$\frac{dT}{dt}=-k(T - T_s)$$ -# -# where $T$ is the temperature of the object at time $t$, $T_s$ is the temperature of the surrounding and assumed to be constant, and $k$ is the constant that characterizes the ability of the object to exchange the -# heat energy (unit 1/s), which depends on the specific material properties. -# -# -# Now, Let's consider an object with the initial temperature of 50°C in a surrounding environment with constant temperature at 20°C. The constant of heat exchange between the object and the environment is 0.5 $s^{-1}$. -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.1:</b> -# -# Suppose the considered period of time is long enough (bring it to steady state), what will be the final temperature of the object? -# -# **Write your answer in the following markdown cell.** -# -# </p> -# </div> - -# %% [markdown] -# - -# %% [markdown] -# Next, let's evaluate the temperature of the object by checking it at a series of time points. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.2:</b> -# -# Write the algebraic representation of the ODE using Explicit Euler. -# -# </p> -# </div> - -# %% [markdown] -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3:</b> -# -# Compute the temperature evolution in the next 60 seconds. -# -# **Please complete the missing parts of the code in each step below, which is divided into 5 substeps (a through e).** -# -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3a:</b> -# -# The time step of 5 seconds is constant. Discretize the time points, the solution vector $T$ and define the initial condition. -# -# </p> -# </div> - -# %% -import numpy as np -import matplotlib.pyplot as plt - -dt =YOUR_CODE_HERE -t_end =YOUR_CODE_HERE -Ts = 20 # [C] -k = 0.5 # [s^-1] - -t = YOUR_CODE_HERE -n = YOUR_CODE_HERE -T = YOUR_CODE_HERE -T[0] = YOUR_CODE_HERE - - - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3b:</b> -# -# Implement your time discretization and find the solution from $t=0$ until $t=60$ sec. -# -# </p> -# </div> - -# %% -for i in range(n-1): - T[i+1] = YOUR_CODE_HERE - -plt.plot(t, T, 'o-') -plt.xlabel('t (s)') -plt.ylabel('T (deg)') -plt.grid() - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3c:</b> -# -# Try different time steps to check the stability of the calculation. At which value the solution is stable? -# -# </p> -# </div> - -# %% [markdown] -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3d:</b> -# -# Obtain the mathematical expression that proves your stability criteria. -# -# </p> -# </div> - -# %% [markdown] -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3e:</b> -# -# Now, discretize the equation using Implicit (Backward) Euler. Can you find a time step that makes the problem unstable? -# -# </p> -# </div> - -# %% -dt = YOUR_CODE_HERE -t_end = 60 -Ts = 20 # [C] -k = 0.5 # [s^-1] - -t = YOUR_CODE_HERE -n = YOUR_CODE_HERE -T = YOUR_CODE_HERE -T[0] = YOUR_CODE_HERE - -for i in range(n-1): - T[i+1] = YOUR_CODE_HERE - -plt.plot(t, T, 'o-') -plt.xlabel('t (s)') -plt.ylabel('T (deg)') -plt.grid() - -# %% [markdown] -# ## Part 2: Second-order ODE -# -# The following 1D equation describes the steady state solution of the temperature along a pin that sticks out of a furnace. The rest of the pin is exposed to the ambient. -# -# $$ -# \frac{d^2T}{dx^2} -\alpha(T-T_s)=0 -# $$ -# -# The ambient temperature is $T_s= 30^o$ C and the temperature at the wall is $250^o$ C. The length of the pin is 0.1m. Your grid should have a spatial step of 0.02 m. Finally, $\alpha=500$. - -# %% [markdown] -# -# The solution includes the steps: -# 1. Use the Taylor series to obtain an approximation for the derivatives; -# 2. Discretize the equation; -# 3. Define parameters and grid; -# 4. Provide boundary conditions; -# 5. Build matrix with solution $AT=b$ -# 6. Solve the matrix - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.1:</b> -# -# This task has three parts: a) discretize the analytic expression into a system of equations using central differences, b) write the system of equations by hand (e.g., the matrices), and c) implement the discretized system of equations in a code cell. -# -# <em>Parts 2.1b and 2.1c do not need to be completed in order; in fact, it may be useful to go back and forth between the two in order to understand the problem.</em> -# -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.1a:</b> -# -# Discretize the analytic expression into a system of equations for a grid with 6 points using central differences. -# -# <em>Write your answer by hand using paper/tablet and include the image below.</em> -# -# - -# %% [markdown] -# _Your answer here._ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.1b:</b> -# -# Write the system of equations by hand for a grid with 6 points. In other words, construct the matrix A and vectors T and b. -# -# <em>Write your answer by hand using paper/tablet and include the image below.</em> -# -# - -# %% [markdown] -# _Your answer here._ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.1c:</b> -# -# Implement the discretized system of equations in a code cell. -# -# <em>We have already done this for you! Your task is to read the cell and make sure you understand how the matrices are implemented. Reading the code should help you formulate the matrices in Task 2.1b.</em> -# -# - -# %% [markdown] -# _Add your image here._ - -# %% -import numpy as np -import matplotlib.pyplot as plt - -Ts = 30 -alpha = 500 -dx=0.02 - -# grid creation -x = np.arange(0,0.1+dx,dx) -T = np.zeros(x.shape) -n=len(x) - -# boundary conditions -T[0] = 250 -T[-1] = Ts - -# Building matrix A -matrix_element = -(2+dx**2*alpha) -A = np.zeros((len(x)-2,len(x)-2)) -np.fill_diagonal(A, matrix_element) -A[np.arange(n-3), np.arange(1, n-2)] = 1 # Upper diagonal -A[np.arange(1, n-2), np.arange(n-3)] = 1 # Lower diagonal -print(A.shape) -# Building vector b -b_element = -dx**2*alpha*Ts -b = np.zeros(len(x)-2) + b_element -b[0] = b[0] - T[0] -b[-1] = b[-1] - T[-1] - -# Solving the system -T[1:-1] = np.linalg.solve(A,b) - -plt.plot(x,T,'*',label='Estimated solution') -plt.xlabel('x') -plt.ylabel('T') -plt.title('Estimated solution using Central Difference method') -plt.legend() -plt.show() - -print(f'The estimated temperature at the nodes are: {[f"{temp:.2f}" for temp in T]} [C]') - -# %% [markdown] -# -# -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.2:</b> -# -# This task will adapt the problem from 2.1 to incorporate Neumann boundary conditions in three steps: a) writing the new matrix by hand, b) adapting the code from 2.1c, c) reflecting on what this represents physically. -# -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.2a:</b> -# -# Write the system of equations by hand for a grid with 6 points, incorporating the Neumann condition. -# -# Approximate the Neuman boundary $\frac{dT}{dx}=0$ by using the Backward difference for first order differential equation of first order accuracy. -# -# <em>Write your answer by hand using paper/tablet and include the image below.</em> -# -# - -# %% [markdown] -# _Your answer here._ - -# %% [markdown] -# -# -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.2b:</b> -# -# Now adapt the code from Task 2.1c and revise it to incorporate the Neumann boundary condition. -# -# <em>Copy and past the code from 2.1c below, then modify it.</em> -# -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# %% [markdown] -# -# -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.2c:</b> -# -# Reflect on the difference between the problem solved in Task 2.1 in comparison to 2.2. How are we changing the physics of the problem being solved by changing the boundary condition? What does this mean in reality for the temperature distribution in the bar over time? -# -# </p> -# </div> - -# %% [markdown] -# - -# %% -Ts = 30 -alpha = 500 -dx=0.02 - -# grid creation -x = np.arange(0,0.1+dx,dx) -T = np.zeros(x.shape) -n=len(x) - -# boundary conditions -T[0] = 250 - - -# Building matrix A -matrix_element = -(2+dx**2*alpha) -A = np.zeros((len(x)-2,len(x)-2)) -np.fill_diagonal(A, matrix_element) -A[np.arange(n-3), np.arange(1, n-2)] = 1 # Upper diagonal -A[np.arange(1, n-2), np.arange(n-3)] = 1 # Lower diagonal -print(A.shape) -A[-1,-1] = -(1+dx**2*alpha) #the matrix changes - -# Building vector b -b_element = -dx**2*alpha*Ts -b = np.zeros(len(x)-2) + b_element -b[0] = b[0] - T[0] -b[-1] = b[-1] #the vector b also changes - -# Solving the system - -T[1:-1] = np.linalg.solve(A,b) -T[-1] = T[-2] - -plt.plot(x,T,'*',label='Estimated solution') -plt.xlabel('x') -plt.ylabel('T') -plt.title('Estimated solution using Central Difference method') -plt.legend() -plt.show() - -print(f'The estimated temperature at the nodes are: {[f"{temp:.2f}" for temp in T]} [C]') - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.3:</b> -# -# Just as we did in Task 2.1, this task has three parts: a) discretize the analytic expression into a system of equations using <b>forward differences</b>, b) write the system of equations by hand (e.g., the matrices), and c) implement the discretized system of equations in a code cell. -# -# Here we focus on <b>Dirichlet</b> conditions again. -# </div> -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.3a:</b> -# -# Discretize the analytic expression into a system of equations for a grid with 6 points using <b>forward differences</b>. -# -# <em>Write your answer by hand using paper/tablet and include the image below.</em> -# -# - -# %% [markdown] -# _Your answer here._ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.3b:</b> -# -# Write the system of equations by hand for a grid with 6 points. In other words, construct the matrix A and vectors T and b. -# -# <em>Write your answer by hand using paper/tablet and include the image below.</em> -# -# - -# %% [markdown] -# _Your answer here._ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.3c:</b> -# -# Implement the discretized system of equations in a code cell. -# -# <b>This time we did not do it for you!</b> Copy the code from Task 2.1c and revise it to solve the system of equations using <b>Forward Differences</b>. Keep the Dirichlet conditions. -# -# - -# %% -YOUR_CODE_HERE - - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.4:</b> -# -# How much finer does your grid has to be in the forward difference implementation to get a similar value at x = 0.02 as in the central difference implementation? Vary your dx. -# -# -# </p> -# </div> - -# %% [markdown] -# _Your answer here._ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Bonus Task</b> -# -# The matrix inversion using numpy is one way to solve the system, another is the <code>gauss_jordan</code> method, written below, and another one is the sparse matrix-based method in the cell afterwards. Here, we will just have a brief comparison to see how these solvers perform when the matrix is large. Change <code>dx</code> to 0.0002 of the original code that solves the second degree ODE and test the time it takes by each method. -# -# </p> -# </div> - -# %% -def gauss_jordan(A, b): - """ - Solves the system of linear equations Ax = b using Gauss-Jordan elimination. - - Parameters: - A (numpy.ndarray): Coefficient matrix (n x n). - b (numpy.ndarray): Right-hand side vector (n). - - Returns: - numpy.ndarray: Solution vector (x) if the system has a unique solution. - """ - # Form the augmented matrix [A | b] - A = np.array(A, dtype=float) - b = np.array(b, dtype=float) - aug_matrix = np.hstack([A, b.reshape(-1, 1)]) - - n = len(b) # Number of rows (or variables) - - for i in range(n): - # Partial pivoting to handle zero diagonal elements (optional, but more robust) - max_row = np.argmax(np.abs(aug_matrix[i:, i])) + i - if aug_matrix[max_row, i] == 0: - raise ValueError("The matrix is singular and cannot be solved.") - if max_row != i: - aug_matrix[[i, max_row]] = aug_matrix[[max_row, i]] - - # Make the diagonal element 1 - aug_matrix[i] = aug_matrix[i] / aug_matrix[i, i] - - # Make all other elements in the current column 0 - for j in range(n): - if j != i: - aug_matrix[j] -= aug_matrix[j, i] * aug_matrix[i] - - # Extract the solution (last column of the augmented matrix) - return aug_matrix[:, -1] - - -# %% -import time -from scipy.sparse import csc_matrix -from scipy.sparse.linalg import spsolve - -# Inverted matrix solution -start_time = time.time() -A_inv = np.linalg.inv(A) -T[1:-1] = A_inv @ b -time_used_0 = time.time() - start_time -print(f"The time used by direct matrix inversion solution is {time_used_0: 0.3e} sec") -assert np.allclose(np.dot(A, T[1:-1]), b), "Oops! The calculation is wrong.." - - -# Gauss-jordan solution -start_time = time.time() -u1 = gauss_jordan(A, b) -time_used_1 = time.time() - start_time -print(f"The time used by Gauss-jordan solution is {time_used_1: 0.3e} sec") -#Check if the solution is correct: -assert np.allclose(np.dot(A, u1), b), "Oops! The calculation is wrong.." - -# Solution by a sparse matrix solver -start_time = time.time() -A_sparse = csc_matrix(A)# Convert A to a compressed sparse column (CSC) matrix -u2 = spsolve(A_sparse, b) -time_used_2 = time.time() - start_time -print(f"The time used by the sparse matrix solver is {time_used_2: 0.3e} sec") -#Check if the solution is correct: -assert np.allclose(np.dot(A, u2), b), "Oops! The calculation is wrong.." - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png"/> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png"/> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2023 <a rel="MUDE Team" href="https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=65595">MUDE Teaching Team</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>. diff --git a/synced_files/students/Week_2_1/WS_2_1_wiggle.ipynb b/synced_files/students/Week_2_1/WS_2_1_wiggle.ipynb deleted file mode 100644 index 6a47eab8d06705aadef56443b50403ff24da7723..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_2_1/WS_2_1_wiggle.ipynb +++ /dev/null @@ -1,2422 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "191924ba", - "metadata": { - "tags": [] - }, - "source": [ - "# WS 2.1: Wiggles\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 90px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px\" />\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px\" />\n", - "</h1>\n", - "<h2 style=\"height: 25px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 2.1, Wednesday November 13, 2024.*" - ] - }, - { - "cell_type": "markdown", - "id": "9c255856", - "metadata": {}, - "source": [ - "## Overview:\n", - "\n", - "In this workshop the advection problem from the textbook is treated first in 1D and then in 2D. R\n", - "\n", - "$$\n", - "\\frac{\\partial \\phi}{\\partial t} + c\\frac{\\partial \\phi}{\\partial x} = 0\n", - "$$\n", - "\n", - "There are two main objectives:\n", - "1. Understand the advection problem itself (how the quantity of interest is transported by the velocity field)\n", - "2. Explore characteristics of the numerical analysis schemes employed, in particular: numerical diffusion and FVM stability\n", - "\n", - "To do this we will do the following:\n", - "- Implement the central difference and upwind schemes in space for FVM and Forward Euler in time\n", - "- Apply a boundary condition such that the quantity of interest repeatedly travels through the plot window (this helps us visualize the process!)\n", - "- Evaluate stability of central difference and upwind schemes in combination with Forward Euler in time\n", - "- Use the CFL to understand numerical stability\n", - "\n", - "Programming requirements: you will need to fill in a few missing pieces of the functions, but mostly you will change the values of a few Python variables to evaluate different aspects of the problem.\n", - "\n", - "\n", - "The following Python variables will be defined to set up the problem:\n", - "```\n", - "p0 = initial value of our \"pulse\" (the quantity of interest, phi) [-]\n", - "c = speed of the velocity field [m/s]\n", - "L = length of the domain [m]\n", - "Nx = number of volumes in the direction x\n", - "T = duration of the simulation (maximum time) [s]\n", - "Nt = number of time steps\n", - "```\n", - "\n", - "There are also two flag variables: 1) `central` will allow you to switch between central and backward spatial discretization schemes, and 2) `square` changes the pulse from a square to a smooth bell curve (default for both is `True`; don't worry about it until instructed to change it).\n", - "\n", - "For the 2D case, `c`, `L`, `Nx` are extended as follows:\n", - "```\n", - "c --> cx, cy\n", - "L --> Lx, Ly\n", - "Nx -> Nx, Ny\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "4679ea87-f250-4d30-a678-eb10f78d1058", - "metadata": { - "tags": [] - }, - "source": [ - "## Part 1: Implement Central Averaging\n", - "\n", - "We are going to implement the central averaging scheme as derived in the textbook; however, **instead of implementing the system of equations in a matrix formulation**, we will _loop over each of the finite volumes in the system,_ one at a time.\n", - "\n", - "Because we will want to watch the \"pulse\" travel over a long period of time, we will take advantage of the reverse-indexing of Python (i.e., the fact that an index `a[-3]`, for example, will access the third item from the end of the array or list). When taking the volumes to the left of the first volume in direction $x$, we can use the values of $phi$ from the \"last\" volumes in $x$ (the end of the array). All we need to do is shift the index for $phi_i$ such that we avoid a situation where `i+1` \"breaks\" the loop (because the maximum index is `i`). In other words, only volumes with index `i` or smaller should be used (e.g., instead of `i-1`, `i`, and `i+1`, use `i-2`, `i-1` and `i`.\n", - "\n", - "_Note: remmeber that the term \"central difference\" was used in the finite difference method; we use the term \"central averaging\" here, or \"linear interpolation,\" as used in the book, to indicate that the finite volume method is interpolating across the volume (using the boundaries/faces)._" - ] - }, - { - "cell_type": "markdown", - "id": "18306064-69a2-4513-967e-992f1f88c9da", - "metadata": {}, - "source": [ - "\n", - "<div style=\"background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.1:</b>\n", - "\n", - "Write by hand for FMV the <code>advection_1D</code> equation, compute the convective fluxes of $\\phi$ at the surfaces using a linear interpolation (central averaging). Then apply Forward Euler in time to the resulting ODE. Make sure you use the right indexing (maximum index should be <code>i</code>).\n", - "\n", - "$$\n", - "\\frac{\\partial \\phi}{\\partial t} + c\\frac{\\partial \\phi}{\\partial x} = 0\n", - "$$\n", - " \n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "4539029d", - "metadata": {}, - "source": [ - "\n", - "<div style=\"background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.2:</b>\n", - "\n", - "<b>Read.</b> Read the code to understand the problem that has been set up for you. Check the arguments and return values; the docstrings are purposefully ommitted so you can focus on the code. You might as well re-read the instructions above one more time, as well (let's be honest, you probably just skimmed over it anyway...)\n", - " \n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "60dbc953", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pylab as plt\n", - "%matplotlib inline\n", - "from ipywidgets import interact, fixed, widgets\n", - "import matplotlib.pyplot as plt\n", - "from mpl_toolkits.mplot3d import Axes3D" - ] - }, - { - "cell_type": "markdown", - "id": "4822b0ad", - "metadata": {}, - "source": [ - "\n", - "<div style=\"background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3:</b>\n", - "\n", - "Implement the scheme in the function <code>advection_1D</code>. Make sure you use the right indexing (maximum index should be <code>i</code>).\n", - " \n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "65abc948-f674-48b8-a752-2ae714525bb9", - "metadata": {}, - "source": [ - "Complete the functions to solve the 1D problem. A plotting function has already been defined, which will be used to check your initial conditions and visualize time steps in the solution." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "65376af7-30e6-43e6-9109-b809ad4c5d56", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "def initialize_1D(p0, L, Nx, T, Nt, square=True):\n", - " \"\"\"Initialize 1D advection simulation.\n", - "\n", - " Arguments are defined elsewhere, except one keyword argument\n", - " defines the shape of the initial condition.\n", - "\n", - " square : bool\n", - " - specifies a square pulse if True\n", - " - specifies a Gaussian shape if False\n", - " \"\"\"\n", - "\n", - " dx = L/Nx\n", - " dt = T/Nt\n", - " \n", - " x = np.linspace(dx/2, L - dx/2, Nx)\n", - "\n", - " \n", - " if square:\n", - " p_init = np.zeros(Nx)\n", - " p_init[int(.5/dx):int(1/dx + 1)] = p0\n", - " else:\n", - " p_init = np.exp(-((x-1.0)/0.5**2)**2)\n", - "\n", - " p_all = np.zeros((Nt+1, Nx))\n", - " p_all[0] = p_init\n", - " return x, p_all\n", - "\n", - "def advection_1D(p, dx, dt, c, Nx, central=True):\n", - " \"\"\"Solve the advection problem.\"\"\"\n", - " p_new = np.zeros(Nx)\n", - " for i in range(0, Nx):\n", - " if central:\n", - " pass # add central averaging + FE scheme here (remove pass)\n", - " else:\n", - " pass # add upwind + FE scheme here (remove pass)\n", - " return p_new\n", - " \n", - "def run_simulation_1D(p0, c, L, Nx, T, Nt, dx, dt,\n", - " central=True, square=True):\n", - " \"\"\"Run sumulation by evaluating each time step.\"\"\"\n", - "\n", - " x, p_all = initialize_1D(p0, L, Nx, T, Nt, square=square)\n", - " \n", - " for t in range(Nt):\n", - " p = advection_1D(p_all[t], dx, dt, c, Nx, central=central)\n", - " p_all[t + 1] = p\n", - " \n", - " return x, p_all\n", - " \n", - "def plot_1D(x, p, step=0):\n", - " \"\"\"Plot phi(x, t) at a given time step.\"\"\"\n", - " fig = plt.figure()\n", - " ax = plt.axes(xlim=(0, round(x.max())),\n", - " ylim=(0, int(np.ceil(p[0].max())) + 1)) \n", - " ax.plot(x, p[step], marker='.')\n", - " plt.xlabel('$x$ [m]')\n", - " plt.ylabel('Amplitude, $phi$ [$-$]')\n", - " plt.title('Advection in 1D')\n", - " plt.show()\n", - " \n", - "def plot_1D_all():\n", - " \"\"\"Create animation of phi(x, t) for all t.\"\"\"\n", - " check_variables_1D()\n", - " \n", - " play = widgets.Play(min=0, max=Nt-1, step=1, value=0,\n", - " interval=100, disabled=False)\n", - " slider = widgets.IntSlider(min=0, max=Nt-1, step=1, value=0)\n", - " widgets.jslink((play, 'value'), (slider, 'value'))\n", - " \n", - " interact(plot_1D, x=fixed(x), p=fixed(p_all), step=play)\n", - "\n", - " return widgets.HBox([slider])\n", - " \n", - "def check_variables_1D():\n", - " \"\"\"Print current variable values.\n", - " \n", - " Students define CFL.\n", - " \"\"\"\n", - " print('Current variables values:')\n", - " print(f' p0 [---]: {p0:0.2f}')\n", - " print(f' c [m/s]: {c:0.2f}')\n", - " print(f' L [ m ]: {L:0.1f}')\n", - " print(f' Nx [---]: {Nx:0.1f}')\n", - " print(f' T [ s ]: {T:0.1f}')\n", - " print(f' Nt [---]: {Nt:0.1f}')\n", - " print(f' dx [ m ]: {dx:0.2e}')\n", - " print(f' dt [ s ]: {dt:0.2e}')\n", - " print(f'Using central difference?: {central}')\n", - " print(f'Using square init. cond.?: {square}')\n", - " calculated_CFL = None\n", - " if calculated_CFL is None:\n", - " print('CFL not calculated yet.')\n", - " else:\n", - " print(f'CFL: {calculated_CFL:.2e}')" - ] - }, - { - "cell_type": "markdown", - "id": "feabdadd-ad60-4eea-a34a-2e8d32cf62d6", - "metadata": { - "tags": [] - }, - "source": [ - "Variables are set below, then you should use the functions provided, for example, `check_variables_1D`, prior to running a simulation to make sure you are solving the problem you think you are!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bad7e23c", - "metadata": {}, - "outputs": [], - "source": [ - "p0 = 2.0\n", - "c = 5.0\n", - "\n", - "L = 2.0\n", - "Nx = 100\n", - "T = 40\n", - "Nt = 10000\n", - "\n", - "dx = L/Nx\n", - "dt = T/Nt\n", - "\n", - "central = True\n", - "square = True" - ] - }, - { - "cell_type": "markdown", - "id": "a01bac48-407f-4c35-8475-a73035190fff", - "metadata": {}, - "source": [ - "_You can ignore any warning that result from running the code below._" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "48a174cf-79c1-4598-b438-5a139abd68af", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "check_variables_1D()\n", - "x, p_all = run_simulation_1D(p0, c, L, Nx, T, Nt, dx, dt, central, square)" - ] - }, - { - "cell_type": "markdown", - "id": "d00aa044-e55b-4339-9e70-6455aaad4a2c", - "metadata": {}, - "source": [ - "Use the plotting function to check your initial values. It should look like a \"box\" shape somwhere in the $x$ domain with velocity $c$ m/s." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bc849eb8-4c49-4691-b7f8-35985527aca4", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "plot_1D(x, p_all)" - ] - }, - { - "cell_type": "markdown", - "id": "f46abdd9-1c87-46a7-8994-e8e35346ce7a", - "metadata": {}, - "source": [ - "Visualize. At the very beginning, you should see the wave moving from the left to right. What happens afterwards?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "06742685-1f3c-43d1-8657-86a0d324b79f", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "plot_1D_all()" - ] - }, - { - "cell_type": "markdown", - "id": "62204ce3-0e2f-4641-9615-3cc1d1fe4a24", - "metadata": {}, - "source": [ - "## Part 2: Central Difference issues!\n", - "\n", - "The discretization is unstable (regardless of the time step used), largely due to weighting equally the influence by adjacent volumes in the fluxes. The hyperbolic nature of the equation implies that more weight should be given to the upstream/upwind $\\phi$ values.\n", - "\n", - "You might think that the initial abrupt edges of the square wave are responsible for the instability. You can test this by replacing the square pulse with a smooth one." - ] - }, - { - "cell_type": "markdown", - "id": "31ffff81-abad-4a53-bffb-caf24459a993", - "metadata": {}, - "source": [ - "\n", - "<div style=\"background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2:</b>\n", - "Run the 1D simulation again using a smooth pulse. You can do this by changing the value of `square` from `True` to `False`. Does the simulation work?\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8672fa59-e451-4271-8d12-470b8c42df67", - "metadata": {}, - "outputs": [], - "source": [ - "square=False\n", - "x, p_all = run_simulation_1D(p0, c, L, Nx, T, Nt, dx, dt, central, square)\n", - "plot_1D_all()" - ] - }, - { - "cell_type": "markdown", - "id": "bd6bf070-db79-4e76-a44d-e9f187263975", - "metadata": {}, - "source": [ - "## Task 3: Upwind scheme\n", - "\n", - "More weight can be given to the upwind cells by choosing $\\phi$ values for the East face $\\phi_i$, and for the West face, use $\\phi_{i-1}$. This holds true for positive flow directions. For negative flow directions, you should choose $\\phi$ values for the East face $\\phi_{i-1}$, and for the West face, use $\\phi_{i}$. Note that this is less accurate than the central diffence approach but it will ensure stability." - ] - }, - { - "cell_type": "markdown", - "id": "f9ede995-1b14-453f-9bf2-69d84734f458", - "metadata": {}, - "source": [ - "\n", - "<div style=\"background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 3.1:</b>\n", - "\n", - "Derive the upwind scheme and apply Forward Euler to the resulting ODE. Then implement it in the function <code>advection_1D</code>. Re-run the analysis after setting the <code>central</code> flag to <code>False</code>.\n", - " \n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1860025d-3c94-4fb7-ac2e-72c8b60578e0", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# re-define key variables and use run_simulation_1D() and plot_1D_all()" - ] - }, - { - "cell_type": "markdown", - "id": "4d58d9a5", - "metadata": {}, - "source": [ - "\n", - "<div style=\"background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 3.2:</b>\n", - "\n", - "In the previous task you should have seen that the method is unstable. Experiment with different time step $\\Delta t$ to see if you can find a limit above/below which the method is stable. Write down your $\\Delta t$ values and whether or not they were stable, as we will reflect on them later.\n", - " \n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bf1691ea", - "metadata": {}, - "outputs": [], - "source": [ - "# you can change variable values and rerun the analysis here." - ] - }, - { - "cell_type": "markdown", - "id": "92b93620", - "metadata": {}, - "source": [ - "_Write your time stepts here, along with the result:_\n", - "\n", - "| $\\Delta t$ | stable or unstable? |\n", - "| :---: | :---: |\n", - "| | |" - ] - }, - { - "cell_type": "markdown", - "id": "c96ba55d-733b-4de6-9b5a-101a520031ee", - "metadata": { - "tags": [] - }, - "source": [ - "## Part 4: False Diffusion\n", - "\n", - "In the previous tasks, we saw how upwinding can be an effective way to handle the type of PDE we are studying (in this case hyperbolic). Now, we will consider _another_ aspect of stability: that of the time integration scheme.\n", - "\n", - "Let’s play with the code. In convective kinematics a von Neumann analysis on the advection equation suggests that the following must hold for stability:\n", - "$$\n", - "CFL = \\frac{c \\Delta t}{\\Delta x} \\leq 1\n", - "$$\n", - " \n", - "$CFL$ is the Courant–Friedrichs–Lewy condtion, a dimensionless quantity that relates the speed of information leaves a finite volume, relating speed to the ratio of time step duration and cell length. The ratio can provide us an indication of the inherent stability of explicit schemes. \n" - ] - }, - { - "cell_type": "markdown", - "id": "0704a3fd", - "metadata": {}, - "source": [ - "\n", - "<div style=\"background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 4.1:</b>\n", - "If you have not already done so, modify the function above to calculate the CFL and run the function <code>check_variables_1D()</code> to check the values. Evaluate the CFL for the time steps you tried in Task 3.2 and write them below, along with the statement of whether or not the scheme was stable.\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "ebfceb93", - "metadata": {}, - "source": [ - "_Write your CFL values here, along with the result:_\n", - "\n", - "| CFL | $\\Delta t$ | stable or unstable? |\n", - "| :---: | :---: | :---: |\n", - "| | | |" - ] - }, - { - "cell_type": "markdown", - "id": "bcde4e4b", - "metadata": {}, - "source": [ - "\n", - "<div style=\"background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 4.2:</b>\n", - "\n", - "Now use the CFL to compute the time step $\\Delta t$ that defines the boundary between the stable and unstable region. Then re-run the analysis for this value, as well as a value that is slightly above and below that threshold $\\Delta t$.\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "faf77fd1-0c67-4452-88d4-51dcc88768dc", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# re-define key variables and use run_simulation_1D() and plot_1D_all()" - ] - }, - { - "cell_type": "markdown", - "id": "f1549927", - "metadata": {}, - "source": [ - "### So you think everything is stable and perfect, right?\n", - "\n", - "Based on the previous task, it looks like we have a good handle on this problem, and are able to use the CFL to set up a reliable numerical scheme for all sorts of complex problems---right?!\n", - "\n", - "**WRONG!**\n", - "\n", - "Remember, in this problem we are dealing with single \"wave\" propagating at a _constant_ speed. In practice we apply numerical schemes to more complex methods. For example, most problems consider _variable_ speed/velocity in more than one dimension. When this is the case, the problem cannot be described by a single CFL value! As a rule of thumb, a modeller would then choose a conservative CFL value, determined by the largest expected flow velocities (in the case of a regular mesh).\n", - "\n", - "Let's apply this concept by using a CFL condition of 0.8 to visualize the impact on the numerical solution. " - ] - }, - { - "cell_type": "markdown", - "id": "9f952992", - "metadata": {}, - "source": [ - "\n", - "<div style=\"background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 4.3:</b>\n", - "\n", - "Find $\\Delta t$ such that CFL is 0.8 and re-run the analysis. What do you observe?\n", - "\n", - "<em>Make sure you look at the complete solution, not just the first few steps.</em>\n", - " \n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8d2ad587", - "metadata": {}, - "outputs": [], - "source": [ - "# re-define key variables and use run_simulation_1D() and plot_1D_all()" - ] - }, - { - "cell_type": "markdown", - "id": "1858199e", - "metadata": {}, - "source": [ - "\n", - "<div style=\"background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 4.4:</b>\n", - "\n", - "Describe what you observe in the result of the previous task and state (yes/no) whether or not this should be expected, given the PDE we are solving. Explain your answer in a couple sentences.\n", - " \n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "26ef0f7a", - "metadata": {}, - "source": [ - "_Write your answer here._" - ] - }, - { - "cell_type": "markdown", - "id": "df03203d-587e-4b8b-9beb-ba41013005f9", - "metadata": {}, - "source": [ - "## Part 5: 2D Implementation in Python" - ] - }, - { - "cell_type": "markdown", - "id": "20bf88e0", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 5.1:</b>\n", - "Apply FVM by hand to the 2D advection equation. The volumes are rectangular. This is a good example of an exam problem.\n", - "\n", - "$$\n", - "\\frac{\\partial \\phi}{\\partial t} + c_x\\frac{\\partial \\phi}{\\partial x} + c_y\\frac{\\partial \\phi}{\\partial y} = 0\n", - "$$\n", - "\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "7c763a84", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 5.2:</b>\n", - "The code is set up in a very similar way to the 1D case above. Use it to explore how the advection problem works in 2D! In particular, see if you observe the effect called \"numerical diffusion\" --- when the numerical scheme causes the square pulse to \"diffuse\" into a bell shaped surface. Even though only the advection term was implmented!\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "a5b165dc-cb40-482c-ae11-75d99f0c233f", - "metadata": { - "id": "0491cc69" - }, - "source": [ - "<div style=\"background-color:#facb8e; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - " <p>\n", - " The initial values of the variables below will result in numerical instability. See if you can fix it!\n", - " </p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3353a233", - "metadata": {}, - "outputs": [], - "source": [ - "p0 = 2.0\n", - "cx = 5.0\n", - "cy = 5.0\n", - "\n", - "Lx = 2.0\n", - "Nx = 100\n", - "Ly = 2.0\n", - "Ny = 100\n", - "T = 40\n", - "Nt = 900\n", - "\n", - "dx = Lx/Nx\n", - "dy = Ly/Ny\n", - "dt = T/Nt\n", - "\n", - "central = True" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "be2b163b-811d-498d-82e9-a6b56327efcd", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "def initialize_2D(p0, Lx, Nx, Ly, Ny, T, Nt):\n", - " x = np.linspace(dx/2, Lx - dx/2, Nx)\n", - " y = np.linspace(dy/2, Ly - dx/2, Ny)\n", - " X, Y = np.meshgrid(x, y)\n", - " \n", - " # Initialise domain: cubic pulse with p0 between 0.5 and 1\n", - " p_init = np.zeros((Nx, Ny))\n", - " p_init[int(0.5/dx):int(1/dx + 1), int(0.5/dy):int(1/dy + 1)] = p0\n", - "\n", - " p_all = np.zeros((Nt + 1, Nx, Ny))\n", - " p_all[0] = p_init\n", - " return X, Y, p_all\n", - "\n", - "def advection_2D(p, cx, cy, Nx, Ny, dx, dy, dt, central=True):\n", - "\n", - " p_new = np.ones((Nx,Ny))\n", - "\n", - " for i in range(0, Nx):\n", - " for j in range(0, Ny):\n", - " if central:\n", - " p_new[i-1,j-1] = (p[i-1,j-1]\n", - " - 0.5*(cx*dt/dx)*(p[i,j-1] - p[i-2,j-1])\n", - " - 0.5*(cy*dt/dy)*(p[i-1,j] - p[i-1,j-2]))\n", - " else:\n", - " p_new[i, j] = (p[i, j] - (cx*dt/dx)*(p[i, j] - p[i - 1, j]) \n", - " - (cy*dt/dy)*(p[i, j] - p[i, j - 1]))\n", - " return p_new\n", - " \n", - "def run_simulation_2D(p0, cx, cy, Lx, Nx, Ly, Ny,\n", - " T, Nt, dx, dy, dt, central=True):\n", - " \n", - " X, Y, p_all = initialize_2D(p0, Lx, Nx, Ly, Ny, T, Nt)\n", - " \n", - " for t in range(Nt):\n", - " p = advection_2D(p_all[t], cx, cy, Nx, Ny,\n", - " dx, dy, dt, central=central)\n", - " p_all[t + 1] = p\n", - " \n", - " return X, Y, p_all\n", - "\n", - "def plot_2D(p, X, Y, step=0):\n", - " 'Create 2D plot, X and Y are formatted as meshgrid.'''\n", - " fig = plt.figure(figsize=(11, 7), dpi=100)\n", - " ax = fig.add_subplot(111, projection='3d')\n", - " ax.set_xlabel('x [m]')\n", - " ax.set_ylabel('y [m]')\n", - " ax.set_zlabel('$\\phi$ [-]') \n", - " ax.set_title('Advection in 2D')\n", - " surf = ax.plot_surface(X, Y, p[step],\n", - " cmap='Blues', rstride=2, cstride=2)\n", - " fig.colorbar(surf, shrink=0.5, aspect=5)\n", - " plt.show()\n", - "\n", - "def plot_2D_all():\n", - " check_variables_2D()\n", - " \n", - " play = widgets.Play(min=0, max=Nt-1, step=1, value=0,\n", - " interval=100, disabled=False)\n", - " slider = widgets.IntSlider(min=0, max=Nt-1,\n", - " step=1, value=0)\n", - " widgets.jslink((play, 'value'), (slider, 'value'))\n", - " \n", - " interact(plot_2D,\n", - " p=fixed(p_all),\n", - " X=fixed(X),\n", - " Y=fixed(Y),\n", - " step=play)\n", - "\n", - " return widgets.HBox([slider])\n", - "\n", - "def check_variables_2D():\n", - " print('Current variables values:')\n", - " print(f' p0 [---]: {p0:0.2f}')\n", - " print(f' cx [m/s]: {cx:0.2f}')\n", - " print(f' cy [m/s]: {cy:0.2f}')\n", - " print(f' Lx [ m ]: {Lx:0.1f}')\n", - " print(f' Nx [---]: {Nx:0.1f}')\n", - " print(f' Ly [ m ]: {Ly:0.1f}')\n", - " print(f' Ny [---]: {Ny:0.1f}')\n", - " print(f' T [ s ]: {T:0.1f}')\n", - " print(f' Nt [---]: {Nt:0.1f}')\n", - " print(f' dx [ m ]: {dx:0.2e}')\n", - " print(f' dy [ m ]: {dy:0.2e}')\n", - " print(f' dt [ s ]: {dt:0.2e}')\n", - " print(f'Using central difference?: {central}')\n", - " print(f'Solution shape p_all[t_i]: ({Nx}, {Ny})')\n", - " print(f'Total time steps in p_all: {Nt+1}')\n", - " print(f'CFL, direction x: {cx*dt/dx:.2e}')\n", - " print(f'CFL, direction y: {cy*dt/dy:.2e}')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cbf8c749-4c91-4ec2-8849-99e9e7652f2e", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "T = 1\n", - "Nt = 1000\n", - "dt = T/Nt\n", - "check_variables_2D()\n", - "X, Y, p_all = initialize_2D(p0, Lx, Nx, Ly, Ny, T, Nt)\n", - "plot_2D(p_all, X, Y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "94e5c840-0373-451f-af12-2ac58138cc5e", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "X, Y, p_all = run_simulation_2D(p0, cx, cy, Lx, Nx, Ly, Ny, T, Nt, dx, dy, dt, central)\n", - "plot_2D_all()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "96aec400-4cc3-412d-863d-9be6c2462f54", - "metadata": {}, - "outputs": [], - "source": [ - "X, Y, p_all = run_simulation_2D(p0, cx, cy, Lx, Nx, Ly, Ny, T, Nt, dx, dy, dt, central=False)\n", - "plot_2D_all()" - ] - }, - { - "cell_type": "markdown", - "id": "57fe2849", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" />\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" />\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2024 <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">MUDE</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">CC BY 4.0 License</a>." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "mude-base", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.4" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": { - "06adb370e96f452097b2c8463159fb01": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "07ad0b7f06b5448d9c863b4780bca156": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "0eb606f0a9954582867598d517186a3b": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "PlayModel", - "state": { - "description": "step", - "layout": "IPY_MODEL_7b82db75ecac48e4a2dcafb91efd0ceb", - "max": 9999, - "style": "IPY_MODEL_bef5f3447c7e456494a7b32035bb4a95", - "value": 1745 - } - }, - "0f0919d6a29146829871df260aee51e3": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "0fea6efd37c34272b7810500b9f57936": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "SliderStyleModel", - "state": { - "description_width": "" - } - }, - "125b800d4d24473da373e19942c91be2": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "LinkModel", - "state": { - "source": [ - "IPY_MODEL_26c50a763abf447a877b6559f17238f0", - "value" - ], - "target": [ - "IPY_MODEL_ab42f5e7066d4545a393d75c1da9db9f", - "value" - ] - } - }, - "1299ef12a7b24dd3a017ec4086f1ed18": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "LinkModel", - "state": { - "source": [ - "IPY_MODEL_cf5b1b468eb84dc28fb66e3a798aa74c", - "value" - ], - "target": [ - "IPY_MODEL_3b12673e4734457a866e96b10e0b731d", - "value" - ] - } - }, - "13aba5ea04d74b40b4da582ea5ad51fa": { - "model_module": "@jupyter-widgets/output", - "model_module_version": "1.0.0", - "model_name": "OutputModel", - "state": { - "layout": "IPY_MODEL_9367ffcacba049b8bfd6b6a3090c510b", - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkoAAAHHCAYAAABA5XcCAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABAq0lEQVR4nO3de3wU1f3/8feSbC6AicolBLkIlEYBQQhUAnKxKBa8Ya1iWxDw8hUvUIj8ULzUola0KF65lJaL2opUI4pfUeFbCZcKWiAoKlK1QBATMbQkiJpskvn9gTPJkgywm0nYmXk9H499PNyzZ2fPuMzJZ8858zkBwzAMAQAAoIZGJ7oBAAAAsYpACQAAwAaBEgAAgA0CJQAAABsESgAAADYIlAAAAGwQKAEAANggUAIAALBBoAQAAGCDQAnwiSeffFKBQEDdunWL6H2LFy9WIBDQrl276qdhx2nFihX63e9+V+trp59+usaOHdug7ZGk3NxcBQIB5ebmOnbM9evX6/rrr1dmZqYSExNt/9/v2rVLgUDAegSDQTVr1kx9+vTR5MmT9dFHHznWJsDPCJQAn1i4cKEk6aOPPtK77757glsTuRUrVmj69Om1vrZs2TLdc889DdwiqVevXtqwYYN69erl2DH//ve/6//+7//Url079evX75j1J0yYoA0bNmjNmjV67rnnNGLECC1fvlw9evTQzJkzHWsX4FcESoAPbNq0Se+//74uuugiSdKCBQtOcIuc1bNnT3Xq1KnBPzclJUV9+/ZVSkqKY8e85557tGvXLi1btsz6vo6mXbt26tu3r/r166fhw4frrrvu0ocffqgLLrhAU6dO1RtvvOFY2wA/IlACfMAMjB566CH169dPL7zwgr799tsa9TZu3Kj+/fsrKSlJrVu31rRp0xQKhcLqjBgxQu3bt1dlZWWN959zzjlhoyuGYWjOnDk6++yzlZycrFNOOUW/+MUv9O9//7vGe998800NGTJEqampaty4sc4880zNmDFDkjR27FjNnj1bksKmm8wpqdqm3vLz8zVq1Ci1bNlSiYmJOvPMM/Xoo4+GtducvnrkkUc0a9YsdejQQU2bNlVWVpY2btx4zP+vtU29jR07Vk2bNtVnn32m4cOHq2nTpmrbtq1uu+02lZaWHvOYjRrVvVtOTk7WggULFAwGGVUC6ohACfC47777TkuWLFGfPn3UrVs3XXvttTp48KBefPHFsHoff/yxhgwZogMHDmjx4sWaN2+e8vLy9MADD4TVu/baa5Wfn6+33347rPyTTz7Re++9p3HjxlllN954oyZNmqTzzz9fr7zyiubMmaOPPvpI/fr101dffWXVW7BggYYPH67KykrNmzdPr732miZOnKgvvvhC0uFRll/84heSpA0bNliP9PT0Ws/566+/Vr9+/bRy5Urdf//9Wr58uc4//3xNmTJFt956a436s2fP1qpVq/T444/rr3/9qw4dOqThw4eruLg4gv/TVUKhkC699FINGTJEr776qq699lo99thjevjhh6M6XjRat26tzMxMvfPOOyovL2+wzwU8xwDgac8++6whyZg3b55hGIZx8OBBo2nTpsaAAQPC6o0cOdJITk42CgsLrbLy8nLjjDPOMCQZO3fuNAzDMEKhkJGWlmb86le/Cnv/1KlTjYSEBKOoqMgwDMPYsGGDIcl49NFHw+rt2bPHSE5ONqZOnWq1JyUlxTj33HONyspK2/O45ZZbDLsuq3379saYMWOs53fccYchyXj33XfD6t10001GIBAwduzYYRiGYezcudOQZJx11llGeXm5Ve+9994zJBlLliyxbY9hGMbq1asNScbq1autsjFjxhiSjL/97W9hdYcPH25kZGQc9XhHmjlzZtj/++rMts+cOdP2/SNHjjQkGV999VVEnwugCiNKgMctWLBAycnJuvrqqyVJTZs21ZVXXql169bp008/teqtXr1aQ4YMUVpamlUWFxenkSNHhh0vPj5eo0aN0ssvv2yNuFRUVOi5557TZZddpmbNmkmS/vd//1eBQECjRo1SeXm59WjVqpV69OhhTVe98847Kikp0c0336xAIODIOb/99tvq0qWLfvKTn4SVjx07VoZh1BgNu+iiixQXF2c97969uyRp9+7dUX1+IBDQJZdcElbWvXv3qI8XLcMwGvTzAC8iUAI87LPPPtPatWt10UUXyTAMHThwQAcOHLCmscw74SRp//79atWqVY1j1FZ27bXX6vvvv9cLL7wgSXrrrbdUUFAQNu321VdfyTAMpaWlKRgMhj02btyooqIiSYenySSpTZs2jp33/v37a52Wa926tfV6dWZwZ0pMTJR0eNoyGo0bN1ZSUlKNY37//fdRHS9au3fvVmJiok499dQG/VzAS+JPdAMA1J+FCxfKMAy99NJLeumll2q8/swzz+iBBx5QXFycmjVrpsLCwhp1aiszR2sWLVqkG2+8UYsWLVLr1q01dOhQq07z5s0VCAS0bt06K/Cozixr0aKFJFnrkZzQrFkzFRQU1Cj/8ssvrbZ53d69e7V582YNGjRI8fF09UC0GFECPKqiokLPPPOMOnXqpNWrV9d43HbbbSooKLBuHz/vvPP097//PWyRdUVFhZYuXVrr8ceNG6d3331X69ev12uvvaYxY8aETV9dfPHFMgxDe/fuVe/evWs8zjrrLElSv379lJqaqnnz5h11qiiSUZ4hQ4bo448/1pYtW8LKn332WQUCAZ133nnHPIabfffdd7r++utVXl6uqVOnnujmAK7GzwzAo9544w19+eWXevjhhzV48OAar3fr1k1PP/20FixYoIsvvlh33323li9frp/+9Kf67W9/q8aNG2v27Nk6dOhQrcf/5S9/qezsbP3yl79UaWlpjdvz+/fvr//5n//RuHHjtGnTJg0cOFBNmjRRQUGB1q9fr7POOks33XSTmjZtqkcffVTXX3+9zj//fN1www1KS0vTZ599pvfff19PP/20JFmB1cMPP6xhw4YpLi5O3bt3V0JCQo22TZ48Wc8++6wuuugi3XfffWrfvr1ef/11zZkzRzfddJN+/OMf1+1/bj36+uuvtWbNGknStm3bJB3+Llu0aKEWLVpo0KBBYfXz8/O1ceNGVVZWqri4WHl5eVq4cKF2796tRx99NGyUD0AUTuBCcgD1aMSIEUZCQoKxb98+2zpXX321ER8fb93p9o9//MPo27evkZiYaLRq1cr4f//v/xnz58+3vfPqV7/6lSHJ6N+/v+1nLFy40DjnnHOMJk2aGMnJyUanTp2Ma665xti0aVNYvRUrVhiDBg0ymjRpYjRu3Njo0qWL8fDDD1uvl5aWGtdff73RokULIxAIhLXpyLveDMMwdu/ebfzqV78ymjVrZgSDQSMjI8OYOXOmUVFRYdU52p1jkox7773X9rwMw/6utyZNmtSoe++999retVfbMWt7DBo0qEbbzUdcXJxxyimnGJmZmcakSZOMjz766JifBeDYAobBbREAAAC1YY0SAACADQIlAAAAGwRKAAAANmIqUJo7d666d++ulJQUpaSkKCsr65g7X69Zs0aZmZlKSkpSx44dNW/evAZqLQAA8LqYCpTatGmjhx56SJs2bdKmTZv005/+VJdddpk++uijWuvv3LlTw4cP14ABA5SXl6c777xTEydOVE5OTgO3HAAAeFHM3/V26qmnaubMmbruuutqvHb77bdr+fLl2r59u1U2fvx4vf/++9qwYUNDNhMAAHhQzCacrKio0IsvvqhDhw4pKyur1jobNmyokUztwgsv1IIFCxQKhRQMBmu8p7S0VKWlpdbzyspK/ec//1GzZs0c25ATAADUL8MwdPDgQbVu3VqNGtXfBFnMBUrbtm1TVlaWvv/+ezVt2lTLli1Tly5daq1bWFgYttO5JKWlpam8vFxFRUW1boo5Y8YMTZ8+vV7aDgAAGtaePXsc3VT7SDEXKGVkZGjr1q06cOCAcnJyNGbMGK1Zs8Y2WDpyFMicSbQbHZo2bZqys7Ot58XFxWrXrp327NmjlJQUh84CAADUp5KSErVt21YnnXRSvX5OzAVKCQkJ+tGPfiRJ6t27t/75z3/qiSee0B//+McadVu1alVjZ/N9+/YpPj5ezZo1q/X4iYmJte5kbt5pBwAA3KO+l83E1F1vtTEMI2xNUXVZWVlatWpVWNnKlSvVu3fvWtcnAQAARCKmAqU777xT69at065du7Rt2zbdddddys3N1a9//WtJh6fNrrnmGqv++PHjtXv3bmVnZ2v79u1auHChFixYoClTppyoUwAAAB4SU1NvX331lUaPHq2CggKlpqaqe/fuevPNN3XBBRdIkgoKCpSfn2/V79Chg1asWKHJkydr9uzZat26tZ588kldccUVJ+oUAACAh8R8HqX6VlJSotTUVBUXF7NGCQAAl2iov98xNfUGAAAQSwiUAAAAbBAoAQAA2CBQAgAAsEGgBAAAYINACQAAwAaBEgAAgA0CJQAAABsESgAAADYIlAAAAGwQKAEAANggUAIAALBBoAQAAGCDQAkAAMAGgRIAAIANAiUAAAAbBEoAAAA2CJQAAABsECgBAADYIFACAACwQaAEAABgg0AJAADABoESAACADQIlAAAAGwRKAAAANgiUAAAAbBAoAQAA2CBQAgAAsEGgBAAAYINACQAAwAaBEgAAgA0CJQAAABsESgAAADYIlAAAAGwQKAEAANggUAIAALBBoAQAAGCDQAkAAMAGgRIAAIANAiUAAAAbBEoAAAA2CJQAAABsECgBAADYIFACAACwQaAEAABgg0AJAADABoESAACADQIlAAAAGwRKAAAANgiUAAAAbMRUoDRjxgz16dNHJ510klq2bKkRI0Zox44dR31Pbm6uAoFAjccnn3zSQK0GAABeFVOB0po1a3TLLbdo48aNWrVqlcrLyzV06FAdOnTomO/dsWOHCgoKrEfnzp0boMUAAMDL4k90A6p78803w54vWrRILVu21ObNmzVw4MCjvrdly5Y6+eST67F1AADAb2JqROlIxcXFkqRTTz31mHV79uyp9PR0DRkyRKtXr7atV1paqpKSkrAHAABAbWI2UDIMQ9nZ2Tr33HPVrVs323rp6emaP3++cnJy9PLLLysjI0NDhgzR2rVra60/Y8YMpaamWo+2bdvW1ykAAACXCxiGYZzoRtTmlltu0euvv67169erTZs2Eb33kksuUSAQ0PLly2u8VlpaqtLSUut5SUmJ2rZtq+LiYqWkpNS53QAAoP6VlJQoNTW13v9+x+SI0oQJE7R8+XKtXr064iBJkvr27atPP/201tcSExOVkpIS9gAAAKhNTC3mNgxDEyZM0LJly5Sbm6sOHTpEdZy8vDylp6c73DoAAOA3MRUo3XLLLXr++ef16quv6qSTTlJhYaEkKTU1VcnJyZKkadOmae/evXr22WclSY8//rhOP/10de3aVWVlZfrLX/6inJwc5eTknLDzAAAA3hBTgdLcuXMlSYMHDw4rX7RokcaOHStJKigoUH5+vvVaWVmZpkyZor179yo5OVldu3bV66+/ruHDhzdUswEAgEfF7GLuhtJQi8EAAIBzfL2YGwAAIBYQKAEAANggUAIAALBBoAQAAGCDQAkAAMAGgRIAAIANAiUAAAAbBEoAAAA2CJQAAABsECgBAADYIFACAACwQaAEAABgg0AJAADABoESAACADQIlAAAAGwRKAAAANgiUAAAAbBAoAQAA2CBQAgAAsEGgBAAAYINACQAAwAaBEgAAgA0CJQAAABsESgAAADYIlAAAAGwQKAEAANggUAIAALBBoAQAAGCDQAkAAMAGgRIAAIANAiUAAAAbBEoAAAA2CJQAAABsECgBAADYIFACAACwQaAEAABgg0AJAADABoESAACADQIlAAAAGwRKAAAANgiUAAAAbBAoAQAA2CBQAgAAsEGgBAAAYINACQAAwAaBEgAAgA0CJQAAABsESgAAADYI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", - "text/plain": "<Figure size 640x480 with 1 Axes>" - }, - "metadata": {}, - "output_type": "display_data" - } - ] - } - }, - "15b483885901400da15996d77a0a871d": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "HBoxModel", - "state": { - "children": [ - "IPY_MODEL_5e3be4ce697e465389536f1bbf997246" - ], - "layout": "IPY_MODEL_c8b7b83c2294407caed2b93a136abda7" - } - }, - "1627977e1fbf4b91be720a5a0efe7697": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "DescriptionStyleModel", - "state": { - "description_width": "" - } - }, - "171843a8296c4cd0aefb28dcc56d61b6": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "HBoxModel", - "state": { - "children": [ - "IPY_MODEL_9d6a64ca0dbc4748bc5c5a5235366ebd" - ], - "layout": "IPY_MODEL_1aebd71480e2438895fb37a39e5f763e" - } - }, - "1889a83a2bab41dfa859502229370773": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "18a64383c5ae41119b8c2f03b4f3e99e": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "HBoxModel", - "state": { - "children": [ - "IPY_MODEL_56183b081add45238ca75241a91faadc" - ], - "layout": "IPY_MODEL_f5be0a5143ea40f4bc6c5978ee36f54f" - } - }, - "19d0d83dc73c4a51a5c60b5c4f98d095": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "1aebd71480e2438895fb37a39e5f763e": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "1b9b858f039c4dc2a04fc125fcd88cd4": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "IntSliderModel", - "state": { - "behavior": "drag-tap", - "layout": "IPY_MODEL_bd99fcbfcf1f44a49b7b8168d3e40593", - "max": 999, - "style": "IPY_MODEL_23ee35b8b8be4a27bb91e7e1ee00e833", - "value": 127 - } - }, - "1c409ebf433849c29e10d6119b614cbb": { - "model_module": "@jupyter-widgets/output", - "model_module_version": "1.0.0", - "model_name": "OutputModel", - "state": { - "layout": "IPY_MODEL_352b47bbf11f4b988bf3a40b5238e05f", - "outputs": [ - { - "data": { - "image/png": "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yGKxmEXIwuEwvF7vstuRSqXQ0dGBcDiMvXv3btrzgSKdTqOjowNVVVXr2l5FUTA7O2vphsulg6UV4crKyrIc3+985zv4nd/5HXznO9/B3XffXdJ1XwsrqbQuhfvvvx8Mw+D73/8+AKMi9s1vfhPvete7rGX+1//6X/jABz5g2XZtYQs3E26KSiuFKIq45557cM899+CrX/0qfvazn+G73/0uHnnkEciyjPvuuw8PPvggXve6112zCWV8fBznz5/Hvn37sG3btpJtI8uyqKysRGVlpRUxOD09jbNnz4IQUlBRXM3Nf2pqCn19fdizZ88NkY0diUTQ29u7pAm/HcUVMuoFOzw8jL6+vkXeueXC7Owsenp6sGPHjk0f5eh2uxEMBjE8PIympiY4HA5EIhFcuHChpE4EpUQ8HkdnZycaGhqwY8eODd0uh8OB+vp61NfXW7KeSCSCjo4OcBxnVWDtg0rqE1pXV1fypqBygBLWUkyxC4JgzSLZZSr9/f0l08FSyQWdSSj18f3e976HD3/4w3jyySc3nLCuBydPnsS3vvUt6+eamppFVdWZmZlF1dctbOFmwU1VaV0Omqbh+eefx1NPPYWnn34ayWQSd999Nx588EG84Q1vKKg+aZqGZ599Fg6HY82em2sBrShSL1hVVVeUlmR3NNiMqUZLYWxsDIODgzh48OC6bq7r9YJdKeiA4EbwjAXyA4Ldu3cXDGBoo2BxROpanAhKibm5OXR3d2P79u2bakBgl6lEIhFLN+z1ejE0NGQlMW12wkorwuWuYNsDRop1sKuRXSzVJFZK/Mu//Ave//7344knnsDb3va2kq57pVhrpfXtb387YrEYfvrTnwIwGrESiQR+9KMfWcvcfffdCAQCW41YW7gp8aogrXZomoaXX37ZIrDRaBRvetOb8MADD+C2227DBz7wAYyNjeHFF1+8bpZLS6UlUQJrj0e1Oxq0trZueosoQoiVG9/S0lLSFKZir86recGuBiMjI7h06dINMyCgoQzXSuVazolgpZGfpQKNvd2zZw/q6+s35DPXAnpNjo6OYnJyEgCsRK6qqqpNax9GCWs5uu6vheJrciU62Fwuh9OnT1sa7FJv77/927/hPe95D772ta/hne98Z0nXfS0kk0lcvHgRgGHh9uUvfxmve93rUFFRgcbGRjz66KMYHx/HE088AQB47LHH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", - "text/plain": "<Figure size 1100x700 with 2 Axes>" - }, - "metadata": {}, - "output_type": "display_data" - } - ] - } - }, - "1cbf92cd804447e0b79704651f5a1e89": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "IntSliderModel", - "state": { - "behavior": "drag-tap", - "layout": "IPY_MODEL_942bf7fdc02f42b99be6546d4813b139", - "max": 9999, - "style": "IPY_MODEL_a293a50ba9664d3da139b13f4bce283c" - } - }, - "1e5f107b8a754defbe2f251e707efac4": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "VBoxModel", - "state": { - "_dom_classes": [ - "widget-interact" - ], - "children": [ - "IPY_MODEL_491bfb41dc944588bbb9844fd978a069", - "IPY_MODEL_e8982f5972f14db4bf2f611e49b75f87" - ], - "layout": "IPY_MODEL_30c1c101e9be48388a1fafd70b92305e" - } - }, - "20fe04e667dc4106941fdfb648cc216a": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "215a78d7b9414d648f4ab73ede6a84b6": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "LinkModel", - "state": { - "source": [ - "IPY_MODEL_970f36758fee4afa8c5657b243ef7f58", - "value" - ], - "target": [ - "IPY_MODEL_883c17bd98b14f9eab6bf5c8a6ad8e96", - "value" - ] - } - }, - "22310484c33844128543f8a8f7665087": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "DescriptionStyleModel", - "state": { - "description_width": "" - } - }, - "23ee35b8b8be4a27bb91e7e1ee00e833": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "SliderStyleModel", - "state": { - "description_width": "" - } - }, - "24940361049945d4952e671a8160433b": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "DescriptionStyleModel", - "state": { - "description_width": "" - } - }, - "2634261c2d124fcaaa5e90b770cdedda": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "DescriptionStyleModel", - "state": { - "description_width": "" - } - }, - "26a84a6c19af4ef49c46737d0e5a3517": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "26c50a763abf447a877b6559f17238f0": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "PlayModel", - "state": { - "description": "step", - "layout": "IPY_MODEL_9c86ab2c7efb4ebfacb92ab22843d8d6", - "max": 999, - "style": "IPY_MODEL_22310484c33844128543f8a8f7665087", - "value": 613 - } - }, - "2b3c1fb36297445f9e4e8d6ce163ebde": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "2bc7ef0c8e324de7a60280f26d887976": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "2e60bdff5ef64267b0f82637370752cc": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "VBoxModel", - "state": { - "_dom_classes": [ - "widget-interact" - ], - "children": [ - "IPY_MODEL_cf5b1b468eb84dc28fb66e3a798aa74c", - "IPY_MODEL_5fc75f9a56b242b6be5d49d271f93bf9" - ], - "layout": "IPY_MODEL_971dd0c46be94df996b906d957530175" - } - }, - "2e84a81901e74c9fb4cd6a843ae1b41f": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "30c1c101e9be48388a1fafd70b92305e": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "30e2839ee1da43589ec4e27bd98334f8": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "DescriptionStyleModel", - "state": { - "description_width": "" - } - }, - "320a66ee1d994dcbbe29188af6aadc84": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "32edaabe677448eab2bd9f8b8e167c9f": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "352b47bbf11f4b988bf3a40b5238e05f": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "39324860e713440498dd2238f37c6250": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "PlayModel", - "state": { - "description": "step", - "layout": "IPY_MODEL_f295d4d179ee4740bd871149bce2d558", - "max": 9999, - "style": "IPY_MODEL_9615034ae68a46638ad79096e22a8572", - "value": 46 - } - }, - "3b12673e4734457a866e96b10e0b731d": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "IntSliderModel", - "state": { - "behavior": "drag-tap", - "layout": "IPY_MODEL_ef927fb5a3a74241b6449c5a302eb232", - "max": 999, - "style": "IPY_MODEL_a813dd78891c420f8a4477b225e8c5b9", - "value": 603 - } - }, - "3c8d7ea135b844baaa1c4f6e8456769d": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "HBoxModel", - "state": { - "children": [ - "IPY_MODEL_af711165b9f347fbb8857a9fad09e7f3" - ], - "layout": "IPY_MODEL_948c747af1ab4020aebde00c9c439900" - } - }, - "41654a25b1e549a99f81f05858197035": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "SliderStyleModel", - "state": { - "description_width": "" - } - }, - "41cbfd4e0c7042e6aa419a655f8e1bfe": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "41d2b49ef8d6477aab5bfafaf9646730": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "491bfb41dc944588bbb9844fd978a069": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "PlayModel", - "state": { - "description": "step", - "layout": "IPY_MODEL_ec55a750fc194d6b9ba7c32094debc2c", - "max": 999, - "style": "IPY_MODEL_e1d342daa7ac441084efceb9d8d910a0", - "value": 127 - } - }, - "4c05bcf8524c430e897e6640e7bdfb6e": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "5182cc9edabf4607b7eafd606ffe939d": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "LinkModel", - "state": { - "source": [ - "IPY_MODEL_39324860e713440498dd2238f37c6250", - "value" - ], - "target": [ - "IPY_MODEL_5e3be4ce697e465389536f1bbf997246", - "value" - ] - } - }, - "522f609e179a44ad9ce8d832b0c2c286": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "HBoxModel", - "state": { - "children": [ - "IPY_MODEL_3b12673e4734457a866e96b10e0b731d" - ], - "layout": "IPY_MODEL_68a0f6bcaf1840a1a91fd43276a2fdab" - } - }, - "5617e97c6ddb4d2f8a8aa131c91cde5a": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "56183b081add45238ca75241a91faadc": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "IntSliderModel", - "state": { - "behavior": "drag-tap", - "layout": "IPY_MODEL_cb18dc1bcf2f4a62a67a8e9d59099554", - "max": 9999, - "style": "IPY_MODEL_91bb487f9240456abbe929cd681b1cb1", - "value": 3705 - } - }, - "5b1e8269f30e43bf8a3b5a4043431139": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "5bc18ece0a9843d697664579831dc33c": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "PlayModel", - "state": { - "description": "step", - "layout": "IPY_MODEL_6ee18397e25648fc915aeb17e0cf64d6", - "max": 9999, - "style": "IPY_MODEL_24940361049945d4952e671a8160433b" - } - }, - "5be025307ba945d1bdc1a4c747ee0f5a": { - "model_module": "@jupyter-widgets/output", - "model_module_version": "1.0.0", - "model_name": "OutputModel", - "state": { - "layout": "IPY_MODEL_81194665591343b593e6c800ca72ec84", - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": "<Figure size 1100x700 with 2 Axes>" - }, - "metadata": {}, - "output_type": "display_data" - } - ] - } - }, - "5e3be4ce697e465389536f1bbf997246": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "IntSliderModel", - "state": { - "behavior": "drag-tap", - "layout": "IPY_MODEL_81c60838b4cf4968b2ddf00e662b2e6e", - "max": 9999, - "style": "IPY_MODEL_a72e4fe8ecf04fb9925ddd6a235c449d", - "value": 46 - } - }, - "5e6c742952034f5986f188d65e9d1cbe": { - "model_module": "@jupyter-widgets/output", - "model_module_version": "1.0.0", - "model_name": "OutputModel", - "state": { - "layout": "IPY_MODEL_c5b771ced109463a8def66c0152089f4", - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": "<Figure size 640x480 with 1 Axes>" - }, - "metadata": {}, - "output_type": "display_data" - } - ] - } - }, - "5e7fb76620a7475cb179f3bbb2e975d2": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "LinkModel", - "state": { - "source": [ - "IPY_MODEL_491bfb41dc944588bbb9844fd978a069", - "value" - ], - "target": [ - "IPY_MODEL_1b9b858f039c4dc2a04fc125fcd88cd4", - "value" - ] - } - }, - "5f0bbd7748f64d23a2b32bfed5a999ac": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "VBoxModel", - "state": { - "_dom_classes": [ - "widget-interact" - ], - "children": [ - "IPY_MODEL_9177dc7e4bfe45459e3c08aacf360fad", - "IPY_MODEL_f090113b148f47afb4bfab581cdd9ad6" - ], - "layout": "IPY_MODEL_19d0d83dc73c4a51a5c60b5c4f98d095" - } - }, - "5fc75f9a56b242b6be5d49d271f93bf9": { - "model_module": "@jupyter-widgets/output", - "model_module_version": "1.0.0", - "model_name": "OutputModel", - "state": { - "layout": "IPY_MODEL_7bd5129d157e40b3b53d66d2ea0cdd07", - "outputs": [ - { - "data": { - "image/png": "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v/02M2fObPbjn4sIIXC5XEydOpWOHTty3XXX8dprr5GXl8cDDzzA//zP//itjBw+fJgPPviARx55hOzsbL+AiYnJhY4pXpuALl43bNjAyJEjje1z587l/fffb7AH94IFC7j55ptZtmwZV111VchxqqqSnp7OmDFjeOmll5pt/hcSQgiKiopYunQp2dnZrFq1ij59+hhCtrGm/Kqqsn37dioqKkhPT28RgeR0Og1BdvLkSdq0aWMIslMpnhFCsGvXLkpKSkhPT2+VJg+niy62dX/Rxpy3/r4VFRVRUlJCdHS03/vW0jnQvpHtllp2bwl++uknDh48SJs2bSgvLzfaIqekpBAdHX3a79uqVauYOXMmr7/+Otddd905YR/Xkng8Hr/UgPvvv5+7776brl27AnDXXXexfPly7r33Xq677joSEhKMsX/4wx946623yMnJ4fLLL2/lmZuYnL2cc1ZZZ5JT6fCls3DhQm666SYWLVpUr3AFzZJp2LBh7N2797TnfKEiSRIpKSn87ne/45ZbbuHkyZMsW7aM7OxsnnnmGbp3705mZiZZWVn0798fWQ7s16EoCtu2bcPlcjFs2LAWy1H19UR1uVxGhOynn34yhEVqamqjBJkutisrK1ukH31LoEe2i4uLDZP+xlCfl2x4eLghyGJiYppdQOlpJEePHj2nhOuhQ4c4dOgQQ4cOJTY21miLrLf4tdvtRqvaUNZl9fHNN9/wq1/9ihdffNEUrmh/j1arlfLycp566imOHz/OgQMHUFXVGPPKK69w33338fLLL1NdXc1NN91EcnIyiqLw7bff8q9//csUriYmdTAjr03k4osvJiMjg9dee83Y1q9fPzIzM0MWbC1YsIAbb7yRBQsW1GvRoiOEYPjw4QwcOJB33nmnuaZu4qWsrIyPP/6YnJwcPvvsMzp06GAI2SFDhiDLMoWFhdxwww3cfffdXHXVVWek3auvsCguLjYEWWpqalBzf0VR+P7773E6naSnp7daQdjpIIRg586dnDx5stk6OimK4ve+Wa3WBr1kmzrnhtIbzkYOHz7Mvn37Qlp4KYpiWJcVFRUhSZKRI5uYmBj0Ac+XjRs3Mn36dJ5++mluu+02U7iqKrIs43Q66du3L8nJyTgcDnbv3s0tt9zCnDlz/Bxl7r33Xj788EPWrVtHz549/Y5hYmLijylem4hulfXG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5UoSEhJYunQp2dnZrF692vC5zMzMDNqc4Exx8uRJNm/eTFRUFDU1NciyTEpKCqmpqcTFxZ2VOa+qqvLDDz9QXV1NRkbGGRFooDky6NHskpKSBr1kddeJfv36nba5fjAqKirIysoiOjqajz/+uNUab5yt1I2q6oVX+fn5XH/99YwbN44HH3ywWbxtTUxMGocpXk1Oiddee41nn32W/Px8+vfvzwsvvMDo0aODjr3hhht49913A7b369ePHTt2AFp18OzZswPG1NTUXDA3T0VRuPnmm1m7di1fffUVXbt2NX4mhKCkpIRly5aRk5PDl19+SY8ePcjMzCQrK+uMVvOXlpayZcsWunfvTpcuXVBVlZMnT1JQUEBRURFCCJKTk0lNTW216vuGOFuEa13cbrcRzQ6WllFSUsK2bdua3XVCp6qqimuvvRZZlvn000+Jiopq9tc4V3nxxRfp1asXF198sWFFNmfOHObNm8euXbto06bNGZ6hicmFgyleTZrMudS28VxCCMEzzzzDrFmzGmwfWVpayscff0xOTg6ff/45HTt2NITs4MGDW00glpSUsHXr1pDes0IISktLKSgooLCwEEVRDD/UxMTEMxKpUlWV77//HofDQXp6+lkjXOuiKAonTpygsLCQoqIiJEnC4/HQpUsXevTo0ey/45qaGn75y1/icrlYsWKFKcZ8OHHiBLfeeiuffvop48aNY9CgQfzlL3+hrKyMX//611x88cX8+c9/PmtWQkxMzndM8WrSZM61to3nOxUVFSxfvpzs7GxWrFhBUlIS06ZNY/r06QwdOrTFhKy+fN27d286dOjQ4HghBOXl5YaQdblcJCUlkZKSQlJSUqtUsvsK14yMjFZpjdscFBcXs23bNmJjY6mqqjKi2fpDwOn+jh0OB7/+9a8pKyvj888/JzY2tplmfn6xadMmVq9ezSuvvEL79u0ZOHAg+fn5tGnThgULFhgdtUwRa2LSspji1aRJuFwuIiMjWbRoEdOnTze233PPPWzdupU1a9Y0eIypU6fidDr54osvjG3z5s3j5ptvpkOHDiiKwpAhQ3jyySdJS0trkfM4X6muruazzz4jOzubTz/9lDZt2jBt2jSysrIYMWJEs0U6dYumU12+FkJQWVlpCNmamhoSExNJSUkhOTm5RUSlqqps27YNl8tFenr6OSNcT548yZYtW4yHBD2arTsXuN1uPyHb1IcAl8vFddddx/Hjx1m5ciXx8fEtdCbnDw6Hg1deeYXdu3fzzjvvAPDqq69y++23n+GZmZhcGJji1aRJHDt2jA4dOrB+/Xo/v8W//vWvvPvuuwHL/nXJz8+nU6dOzJ8/nxkzZhjbv/32W/bt2+fXtnH58uXN1rbxQsThcLBy5Uqys7P56KOPCAsLY+rUqUyfPp1LLrnklCOdejen5qx0r2sjlZCQYOR6NseyvqIobNu2DY/HQ1pa2jkjXEtLS9m8eTMXXXQRHTt2DPi5EIKKigrjvWvqQ4Db7eb666/nwIEDfP311y3SVvZ8o25kdfXq1bzxxhsoisL7779PWFiYGXk1MWlhTPFq0iR08bphwwZGjhxpbJ87dy7vv/8+u3fvrnf/p556ir///e8cO3asXlGiqirp6emMGTPmlNs2mtTicrlYtWoVixcvZtmyZQghmDJlCllZWVx22WWNFoj5+fns2rWrxUzxQYse62KsvLycuLg4Q8ieSvHeuSxct2zZQs+ePYPmEwejsrKSoqIiCgoKGvSS9Xg83HTTTezatYuvv/66VZtgnG989dVXTJ48mXXr1jF06NAzPR0Tk/Me0+fVpEmczW0bTUJjt9sZP34848eP5/XXX2ft2rUsXryY22+/nZqaGqZMmUJmZiZXXHFFSIF49OhR9uzZw+DBg1s0QhcZGUnXrl3p2rUrDoeDwsJCCgoK+PHHH4mJiTEsuBrjh6ooClu3bkVRFNLT01utQ9TpUlZW1mThCrVest26dQvwknU4HOTm5jJjxgx69+7N7bffzvbt21m1apUpXE8RPQp75ZVX0qdPHw4cOGCKVxOTVsCMvJo0mYsvvpiMjAxee+01Y1u/fv3IzMyst2Br9erVjB07lh9++IEBAwbU+xpCCIYPH87AgQONnDKT5kdRFNavX092djZLliyhrKyMCRMmkJWVxdVXX01kZCQAf/vb3yguLuaRRx45YzmRuh9qQUEBJ0+eJDo6mtTUVMMPtS66cFVVlbS0tHNGuJaXl5OXl0ePHj2CunecCk6nk3Xr1jF37lyjA1pVVRWLFi1i7Nix5jL3afLSSy/xwAMPcPDgwUYVL5qYmJwepng1aTJnc9tGk1NHVVX++9//snjxYpYsWUJBQQHjxo0jMjKSpUuXsmDBAq688sozPU1Ay9XUheyJEyeIjIw0hGx0dDSqqrJlyxaEEOekcNU9c5sbVVW555572LBhA127dmXNmjV06tSJa665hmuuuYahQ4c2i5Btig+0/lBbl127dtGnTx/j++zsbB599FF++uknevTowdy5c/2KRs8ke/bsQZZlMz/fxKSVODc+0U3OKs7mto0mp44sy4wYMYIRI0bwzDPPsGXLFu677z6+/fZbOnTowJtvvklhYSGTJk0iJibmjEbrbDYb7du3p3379ng8HqND1cGDBwkLC0NVVex2O0OHDj1nhGtFRQWbN2+mW7duLSZc//jHP7Jy5UpWrVpFjx49qK6u5vPPPycnJ4err76auXPncuedd57W6yxcuJB7773Xzwd64sSJIX2gdfbs2UNMTIzxvW9O9caNG5k5cyZPPvkk06dPZ8mSJcyYMYN169adFW2se/fufaanYGJyQWFGXk1MTAIQQjBnzhzeeustVq5ciSRJLFq0iCVLlvDjjz9yxRVXkJmZyZQpU4iPjz9rlp2dTie5ubl4PB4URcFmsxkFS3FxcWfNPOtSUVFBXl4eXbp0oVu3bs1+fFVVeeyxx1i4cCGrVq3ioosuChjjcrlwu92n3VWrqT7QeuT15MmTxMXFBT3mzJkzKS8vZ8WKFca2CRMmEB8fz4IFC05rviYmJuceZ75Po4nJKbB27VqmTp1K+/btkSSJpUuXNrjPmjVryMjIIDw8nO7du/PGG28EjMnOzqZfv36EhYXRr18/lixZ0gKzP7sRQvDAAw8wb9481qxZw6BBgxg4cCB/+ctf+P7779m6dSujRo3izTffpHv37mRmZvL2229TWFjImXwW9ng8bNu2jfDwcC699FIuv/xy+vTpY2xfu3Ytu3bt4sSJE6iqesbmWZfKykry8vLo3LlziwhXIQRz585l/vz5rFy5MqhwBa2o73SFq8vlIi8vj3HjxvltHzduHBs2bKh337S0NNq1a8eVV17JqlWr/H62cePGgGOOHz++wWOamJicn5ji1eScpKqqisGDB/PKK680avyBAweYNGkSo0ePZsuWLfzpT3/i7rvvJjs72xijL03OmjWLbdu2MWvWLGbMmMGmTZta6jTOSjweD9XV1axdu9Yv5xBAkiT69u3Lo48+Sl5eHjt37uTqq6/mgw8+oFevXkyaNIk33niDY8eOtaqQdbvdbN68GavVypAhQ7BYLMiyTHJyMv3792fMmDFGkeD27dtZu3YtO3bsoKio6IwKWV24durUie7duzf78fWWw3oEvV+/fs3+Gr4UFxejKEqA80hqamqAQ4lOu3btePPNN8nOziYnJ4fevXtz5ZVXsnbtWmPM8ePHm3RMExOT8xszbcDknEeSJJYsWUJWVlbIMQ899BAfffQRu3btMrbddtttbNu2jY0bNwLm0uTpIITg0KFDhgD59ttvGT58OJmZmWRmZtKpU6cWW7LXhavNZmPw4MENdhGr26HK4/GQlJREamoqiYmJzdaFrCGqqqrIzc2lY8eO9OjRo9mPL4TghRde4O9//ztfffVVq3SrO10faJ2pU6ciSRIfffQRoEWF3333XX79618bY/7zn/9w00034XA4mvckTExMznrMyKvJBUGoZcfc3Fzcbne9Y8ylyYaRJIkuXbpw//3388033/Dzzz/z61//ms8++4yBAwdy+eWX849//IP9+/c3a0RWF652u92IuDZmrvHx8fTu3ZtLL72U9PR0wsPD+fHHH1m9ejXbtm3j+PHjeDyeZptnXXTh2qFDhxaLuL766qs899xzfPbZZ63WZvl0fKB9GTFihJ/Hc9u2bU/7mCYmJucPpng1uSAItezo8XgoLi6ud4y5NNk0JEmiQ4cO/P73v+frr7/m8OHD3HTTTaxZs4b09HQuueQSnnnmGfbs2XNaQtbtdpOXl4fdbmfw4MHIctM/ziRJIjY2ll69enHJJZcwfPhwoqKi2L9/P2vWrGHLli0cO3bMeMBpDqqqqsjLy6N9+/b06NGj2SPSQgj+9a9/MXfuXD799NNWdeyw2+1kZGSwcuVKv+0rV670ayfdEFu2bKFdu3bG9yNHjgw45hdffNGkY5qYmJw/nBseMiYmzUBdkaALJ9/twcacrRXq5wKSJNG2bVtuu+02br31VkpKSli2bBnZ2dk89dRT9OrVi8zMTLKysujbt2+jBajL5WLz5s2Eh4czaNCgUxKuwebapk0b2rRpQ8+ePamqqqKgoIBDhw6xc+dOEhISDOeCxrbTrUt1dTV5eXm0bduWnj17tohwfffdd3nsscf45JNPzoi4u//++5k1axZDhw41fKAPHTrEbbfdBhDgA/3CCy/QtWtX+vfvj8vl4oMPPiA7O9svH/2ee+5hzJgxPP3002RmZrJs2TK+/PJL1q1b1+rnZ2JicuYxxavJBUGoZUer1Wq0OjWXJlsWSZJITEzkxhtvZPbs2ZSVlfHxxx+TnZ3NP/7xDzp16sS0adOYPn16vYJUr2iPjIxk4MCBzSJcgxEVFUX37t3p3r071dXVFBYWcuzYMXbv3k1cXJwhZEO1061LTU0NeXl5pKam0qtXrxYRrvPnz+ehhx5i2bJljBkzplmP31ia6gPtcrl48MEHOXr0KBEREfTv359PP/2USZMmGWNGjRrFhx9+yJw5c3j00Ufp0aMHCxcuPCs8Xk1MTFofs2DL5JynsQVbH3/8MTt37jS23X777WzdutWvYKuiooLly5cbYyZOnEhcXJxZsNXCVFRU8Omnn5Kdnc2KFStISUkxhGxGRoYhUI8dO8bf//53fvvb37aocK0Ph8NhFHuVlpYSExNDSkoKqampREREBN2npqaG3NxckpOT6d27d4sI10WLFnHXXXexePFiJkyY0KzHNzExMTmbMMWryTlJZWUl+/btAzR/yOeff56xY8eSkJBA586dA5YmDxw4wIABA7j11lu55ZZb2LhxI7fddhsLFizg2muvBWDDhg2MGTOGuXPnGkuTc+bMOWu6+FwoVFVV8dlnn5Gdnc2nn35KbGws06ZNY8yYMTz00EP07NmTxYsXY7PZzvRUcblchpAtKSkhOjraELK6Z2pLC1eApUuXcsstt/Dhhx8yderUZj++iYmJydmEKV5NzklC9UO//vrrmTdvHjfccAMHDx5k9erVxs/WrFnDfffdx44dO2jfvj0PPfSQkYens3jxYubMmcP+/fuN/unXXHNNS5+OSQhqampYuXIl//nPf1i2bBndunVj9OjRXHPNNYwaNeqsav3qdrspKiqioKCAkpISIiIiSEhIoLCwkKSkJPr27dsiwvWTTz5h9uzZvP/+++a1amJickFgilcTE5Ozmvz8fK644grS09P5zW9+w9KlS1m6dCmSJDFlyhSysrIYM2bMKRdRtQQej4djx46xd+9ehBCEh4eTmppKSkoKMTExzSZiP//8c6677jreeecdZs6c2SzHNDExMTnbMa2yTExOkaa2qM3JyeHqq68mOTmZmJgYRo4cyeeff+43Zt68eUiSFPB1oRqxHz16lMsvv5yLL76Y9957j8mTJ/Ovf/2L/Px8PvzwQ8LCwrj11lvp3r07t912GytWrMDpdJ7paaMoCocPH6Zt27ZcfvnlXHTRRTgcDjZv3sy6devYs2cPJ0+ePC2rsFWrVjFr1izeeOMNZsyY0YyzNzExMTm7McWrickp0tQWtWvXruXqq69m+fLl5OXlMXbsWKZOncqWLVv8xsXExJCfn+/31diK9vONt956i0suuYS3337brwGB1Wrliiuu4PXXX+fIkSMsXbqUuLg47rvvPrp168aNN97IRx99RHV1davP2el0kpubS2xsLP369cNqtZKSksLAgQO57LLL6NOnDx6Ph23btrF27Vp27drFiRMnmtSm9ptvvuFXv/oVL730Etddd51p52ZiYnJBYaYNmJg0A41xPAhG//79mTlzJo899higRV7vvfdeSktLm3+S5yC6oGusq4CqqmzatInFixezZMkSioqKGDduHFlZWYwfP57o6OiWnC4ul4vc3FxiYmLo379/vaJSVVVOnjxpFHwJIUhOTiYlJYXExMSQ57xx40amT5/O008/zW233WYKVxMTkwsOM/JqYnKGUFWViooKEhIS/LZXVlbSpUsXOnbsyJQpUwIisxcSsiw3yQ5LlmVGjhzJ3//+d/bt28eqVavo1asXTz75JF27duVXv/oVCxYsoKysrFnb1EKtcG3Tpk2DwlWfa2JiIn379mXMmDEMHjwYq9XK7t27WbNmDT/88ANHjhyhoqLC2Oe7777j2muv5X//939N4WpiYnLBYkZeTc44qqoauZ3nKqcSeX322Wf529/+xq5du0hJSQHg22+/Zd++fQwcOJDy8nJefPFFli9fzrZt2+jVq1cLzf78R1VVtm/fzuLFi8nJyWHv3r1ceeWVZGZmMnnyZOLj40/r+tMbJ0RFRTFgwIDT8p8VQlBeXk5hYSErVqzg8ccfZ9SoUYwaNYpXXnmFOXPm8MADD5zTfy8mJiYmp4MpXk3OKGVlZcTGxvptC9a29WynqeJ1wYIF3HzzzSxbtoyrrroq5DhVVUlPT2fMmDG89NJLzTTbCxshBLt37zaE7I4dO7jsssvIzMxk6tSpJCUlNenaa8mOX6qq8t133/HOO+/w2WefUVpaysSJE7n22muZNm0a8fHxzfZaJiYmJucKZtqAyRlDCMHo0aN5+umn/ZZwz/UobEMsXLiQm266if/7v/+rV7iCtrQ8bNgw9u7d20qzO/+RJIm+ffvy6KOPsnnzZnbu3MmVV17Je++9R8+ePZk8eTL//Oc/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", - "text/plain": "<Figure size 1100x700 with 2 Axes>" - }, - "metadata": {}, - "output_type": "display_data" - } - ] - } - }, - "600a3903818d494e9e421ead56ac8a1f": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "LinkModel", - "state": { - "source": [ - "IPY_MODEL_c7e53e2cb900438994ad4a976ed38f09", - "value" - ], - "target": [ - "IPY_MODEL_6c4277ad49814aefac628aa0aaf1ab08", - "value" - ] - } - }, - "656efd54140e480db897975d031ffcf1": { - "model_module": "@jupyter-widgets/output", - "model_module_version": "1.0.0", - "model_name": "OutputModel", - "state": { - "layout": "IPY_MODEL_26a84a6c19af4ef49c46737d0e5a3517", - "outputs": [ - { - "data": { - "image/png": "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19999109++yz8vLyUkhIiHJzcx22qaytovfl7bff1kMPPaS3335bERERGjJkiG2bZs2ayWKxaP369baAca6KtubNm0uSbbyQM4SEhCgnJ8eh/eeff7bVVt8dPnxY27Zt04ABA+Ttza964LfQQwTUU2VlZXr33XfVrl07rV271uHxl7/8RTk5ObZp2YMGDdJ///tfu8HOZWVlWrZsWaXHHzt2rDZt2qTU1FR9/vnnGj16tN1lpz/84Q8yDEOHDx9Wz549HR5du3aVJPXp00fBwcFauHDhRS/xVKXXZvDgwdqzZ4+2b99u1/7ee+/JYrFo0KBBv3kMT3bq1Ck98MADKi0t1WOPPebqcgCPwH8bgHrqyy+/1M8//6wXXnhBAwcOdHi9S5cumjt3rhYvXqw//OEPevLJJ7Vy5Updf/31euqppxQYGKh58+apqKio0uPffffdio+P1913363i4mKHae99+/bV//zP/2js2LHaunWr+vfvr4YNGyonJ0epqanq2rWrHn74YTVq1EgvvfSSHnjgAd1www168MEHFRoaqv3792vnzp2aO3euJNkC1AsvvKChQ4fKy8tL3bp1k6+vr0NtkydP1nvvvadhw4Zp1qxZat26tb744gvNnz9fDz/8sK644oqa/XBr0dGjR5WSkiJJSk9Pl3T2u2zevLmaN2+uAQMG2G2fnZ2tjRs3qry8XFarVWlpaVqyZIkOHDigl156ya7XDsBFuHBAN4BaNGLECMPX19fIy8u74DZ33XWX4e3tbZtZ9s033xi9e/c2/Pz8jLCwMOOvf/2rsWjRogvOdLrnnnsMSUbfvn0v+B5Lliwxrr32WqNhw4ZGQECA0a5dO+O+++4ztm7darfdqlWrjAEDBhgNGzY0AgMDjU6dOhkvvPCC7fXi4mLjgQceMJo3b25YLBa7ms6fZWYYhnHgwAHjnnvuMUJCQgwfHx+jQ4cOxpw5c4yysjLbNhebqSXJePrppy/4uQzjwrPMGjZs6LDt008/fcFZcpUds7LHgAEDHGqveHh5eRmXXXaZER0dbUyaNMnYvXv3b74XgP9nMQymIQAAAHNjDBEAADA9AhEAADA9AhEAADA9twpECxYsULdu3RQUFKSgoCDFxMT85p2aU1JSFB0dLX9/f7Vt21YLFy6so2oBAEB94VaBqGXLlnr++ee1detWbd26Vddff71u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", - "text/plain": "<Figure size 640x480 with 1 Axes>" - }, - "metadata": {}, - "output_type": "display_data" - } - ] - } - }, - "65d60095e2734129937ad8d2620e8f92": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "66bd8ae571ac4cf2bd9fcfa21904aca1": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "68a0f6bcaf1840a1a91fd43276a2fdab": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "69927f920624499bb7dadf265bdd8f57": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "LinkModel", - "state": { - "source": [ - "IPY_MODEL_9177dc7e4bfe45459e3c08aacf360fad", - "value" - ], - "target": [ - "IPY_MODEL_b6b07613dbe34bb48bdaf77f24b87df6", - "value" - ] - } - }, - "69aaef53d0004a9c8a8350c74cf9ecb6": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "6b5c7e81dc2f480e84c3aaf0d9c6472e": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "SliderStyleModel", - "state": { - "description_width": "" - } - }, - "6c4277ad49814aefac628aa0aaf1ab08": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "IntSliderModel", - "state": { - "behavior": "drag-tap", - "layout": "IPY_MODEL_2b3c1fb36297445f9e4e8d6ce163ebde", - "max": 9999, - "style": "IPY_MODEL_c64dfe4ed7e34116b9729c7438235cb6" - } - }, - "6cda5b4c8d8540d3ab9db7eb1ca1b0bb": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "PlayModel", - "state": { - "description": "step", - "layout": "IPY_MODEL_2bc7ef0c8e324de7a60280f26d887976", - "max": 999, - "style": "IPY_MODEL_fd48764d8839460a8c983f2e74353d65", - "value": 882 - } - }, - "6dc714ca412242d39549385e291640fd": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "6ee18397e25648fc915aeb17e0cf64d6": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "71aacf54689840c4835e0e8cbfef2749": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "74ffa7bc444e4ed396a97a7a7c868844": { - "model_module": "@jupyter-widgets/output", - "model_module_version": "1.0.0", - "model_name": "OutputModel", - "state": { - "layout": "IPY_MODEL_71aacf54689840c4835e0e8cbfef2749", - "outputs": [ - { - "data": { - "image/png": "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r732ml577bVKr7/wwgt6+OGHFR0drZYtWyo/P79SnarKrNGaxYsX65ZbbtHixYvVrl07DR8+3K7TqlUreTwerVu3zg48KrLKWrduLUn2eqRwaNmypfLy8iqVf/XVV3bbmroDBw5o69atGjJkiGJi+KceCBUjSkATVVZWphdeeEFdunTR6tWrKz3uvPNO5eXl2bePX3jhhfr73//ut8i6rKxMy5Ytq/L4EyZM0ObNm7V+/Xq99dZbGjdunN/01WWXXSZjjA4cOKC+fftWepx77rmSpAEDBigpKUnz58+vdqoomFGeYcOG6dNPP9W2bdv8yl988UV5PB5deOGFNR6jMfv+++910003qbS0VNOnT2/o5gCNGn9mAE3UO++8o6+++kqPPfaYhg4dWun1Hj166Pnnn9fChQt12WWX6b777tOKFSv005/+VL/97W/VrFkzzZkzR0ePHq3y+L/85S+VkZGhX/7ylyouLq50e/7AgQP1P//zP5owYYK2bNmiwYMHq3nz5srLy9P69et17rnn6tZbb1WLFi30xBNP6KabbtJFF12km2++WcnJydq9e7c+/PBDPf/885JkB1aPPfaYRowYoejoaPXs2VOxsbGV2jZ16lS9+OKLuvTSS/Xggw+qU6dOevvttzV37lzdeuut+vGPf1y7/7l16JtvvtGaNWskSTt27JB0/Lts3bq1WrdurSFDhvjVz83N1aZNm1ReXq7CwkLl5ORo0aJF2rdvn5544gm/UT4AIWjAheQA6tCoUaNMbGysOXjwoGOd6667zsTExNh3uv3jH/8w/fv3N3FxcaZt27bm//2//2cWLFjgeOfVr371KyPJDBw40PEzFi1aZM4//3zTvHlzk5CQYLp06WKuv/56s2XLFr96K1euNEOGDDHNmzc3zZo1M926dTOPPfaY/XpxcbG56aabTOvWrY3H4/Fr08l3vRljzL59+8yvfvUr07JlS+P1ek1qaqqZPXu2KSsrs+tUd+eYJPPAAw84npcxzne9NW/evFLdBx54wPGuvaqOWdVjyJAhldpuPaKjo81pp51m0tLSzJQpU8wnn3xS42cBqJnHGG6LAAAAqAprlAAAABwQKAEAADggUAIAAHAQUYHSvHnz1LNnTyUmJioxMVHp6ek17ny9Zs0apaWlKT4+XmeddZbmz59fT60FAABNXUQFSu3bt9ejjz6q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375dKSkptW5zOIR63ifLycnxO6em+n1Lx+8s2b17t2688cYaPyfSvu9gNYVrO1SN/doOl8Z2bddGY7+2jTG644479Prrr+v9999X586da3xPvV3jAS/7biReeeUV4/V6zcKFC82nn35qpkyZYpo3b27fAXD33XebsWPH2vX//e9/m2bNmpmpU6eaTz/91CxcuNB4vV7z2muv2XX+8Y9/mOjoaPPoo4+anTt3mkcffdTExMSYTZs21fv5OQn2vF9++WUTExNj5syZY/Ly8uzH4cOH7Tq/+93vzLvvvmu++OILk5OTYyZMmGBiYmLM5s2b6/38nAR73k899ZRZvny5+de//mU+/vhjc/fddxtJJjMz067TFL9vy5gxY8z5559f5TEj/fs+cuSIycnJMTk5OUaSefLJJ01OTo7Zt2+fMabpXtvBnndTubaDPe+mcm0He96WxnxtG2PMrbfeapKSkkx2drbf7/a7776z6zTUNd7kAiVjjJkzZ47p1KmTiY2NNX369PG7vXDcuHFmyJAhfvWzs7NN7969TWxsrDnzzDPNvHnzKh3z1VdfNampqcbr9Zqzzz7b7+KLFMGc95AhQ4ykSo9x48bZdaZMmWI6duxoYmNjTevWrc3w4cPNhg0b6vGMAhPMeT/22GOmS5cuJj4+3px22mnmggsuMG+//XalYza179sYYw4fPmwSEhLMggULqjxepH/f1u3fTr/ZpnptB3veTeXaDva8m8q1HcrvvLFf28aYKs9Zklm8eLFdp6Gucc8PDQQAAMBJmtQaJQAAgHAiUAIAAHBAoAQAAOCAQAkAAMABgRIAAIADAiUAAAAHBEoAAAAOCJQAAAAcECgBaDKGDh0qj8cjj8ej7du31+pY48ePt4/1xhtvhKV9ABofAiUATcrNN9+svLw89ejRo1bHeeaZZ5SXlxemVgForGIaugEAEE7NmjVT27Zta32cpKQkJSUlhaFFABozRpQARKylS5cqPj5eBw4csMtuuukm9ezZU4WFhQEfZ+jQoZo0aZKmTJmi0047TcnJyVqwYIGOHj2qCRMm6JRTTlGXLl30zjvv1MVpAGjECJQARKzrrrtOqampmjVrliRp5syZeu+99/TOO+8EPdrzwgsvqFWrVvrggw80adIk3Xrrrbrmmms0YMAAbdu2TZdcconGjh2r7777ri5OBUAjRaAEIGJ5PB79/ve/15///Gc98sgjeuaZZ/Tuu+/qjDPOCPpYvXr10n333aeuXbtqxowZSkhIUKtWrXTzzTera9eu+u1vf6tDhw7po48+qoMzAdBYsUYJQES77LLL1K1bN82cOVOrVq1S9+7dQzpOz5497f+Ojo5Wy5Ytde6559plycnJkqSDBw/WrsEAmhRGlABEtPfee0+fffaZysrK7GAmFF6v1++5x+PxK/N4PJKk8vLykD8DQNNDoAQgYm3btk3XXHON/vjHP+qSSy7R/fff39BNAuAyTL0BiEh79+7VpZdeqrvvvltjx45Vt27d1K9fP23dulVpaWkN3TwALsGIEoCI85///EcjRozQFVdcoXvuuUeSlJaWpssvv1z33ntvA7cOgJswogQg4px++unauXNnpfI333wzpONlZ2dXKtu7d2+lMmNMSMcH0HQxogSgSZk7d65atGihHTt21Oo4EydOVIsWLcLUKgCNlcfwJxSAJuLAgQP6/vvvJUkdO3ZUbGxsyMc6ePCgioqKJEkpKSlq3rx5WNoIoHEhUAIAAHDA1BsAAIADAiUAAAAHBEoAAAAOCJQAAAAcECgBAAA4IFACAABwQKAEAADggEAJAADAAYESAACAAwIlAAAAB/8fOa26ueluUSEAAAAASUVORK5CYII=", - "text/plain": "<Figure size 640x480 with 1 Axes>" - }, - "metadata": {}, - "output_type": "display_data" - } - ] - } - }, - "783f264aa6fa4c00b2686cb556d713e1": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "VBoxModel", - "state": { - "_dom_classes": [ - "widget-interact" - ], - "children": [ - "IPY_MODEL_c7e53e2cb900438994ad4a976ed38f09", - "IPY_MODEL_74ffa7bc444e4ed396a97a7a7c868844" - ], - "layout": "IPY_MODEL_8ab28dfb8f024c6683ac6f0e1c41dafb" - } - }, - "7b82db75ecac48e4a2dcafb91efd0ceb": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "7bd5129d157e40b3b53d66d2ea0cdd07": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "7de4ad6416ad484580cb7423474d4d3e": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "7eef8be917694ee189e97029c427b838": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "LinkModel", - "state": { - "source": [ - "IPY_MODEL_0eb606f0a9954582867598d517186a3b", - "value" - ], - "target": [ - "IPY_MODEL_af711165b9f347fbb8857a9fad09e7f3", - "value" - ] - } - }, - "7f10c4ad338f4101a841ddf576814be1": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "PlayModel", - "state": { - "description": "step", - "layout": "IPY_MODEL_5b1e8269f30e43bf8a3b5a4043431139", - "max": 9999, - "style": "IPY_MODEL_30e2839ee1da43589ec4e27bd98334f8" - } - }, - "81194665591343b593e6c800ca72ec84": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "81c60838b4cf4968b2ddf00e662b2e6e": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "84a334b99d014b929f64344cefe778fe": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "VBoxModel", - "state": { - "_dom_classes": [ - "widget-interact" - ], - "children": [ - "IPY_MODEL_970f36758fee4afa8c5657b243ef7f58", - "IPY_MODEL_993a738490414b5c8c0339f8f87885b7" - ], - "layout": "IPY_MODEL_a95960ed1bf74f569d074e47dce2c9de" - } - }, - "86a3f84417b843388d2bc76372c68536": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "883c17bd98b14f9eab6bf5c8a6ad8e96": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "IntSliderModel", - "state": { - "behavior": "drag-tap", - "layout": "IPY_MODEL_f6a9b4d7f41d435e9087825265f19ed3", - "max": 9999, - "style": "IPY_MODEL_d8793922da25405da6cd5b7aa8446373", - "value": 9774 - } - }, - "8ab28dfb8f024c6683ac6f0e1c41dafb": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "8be9345e440e408481bd8109c8811c5a": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "DescriptionStyleModel", - "state": { - "description_width": "" - } - }, - "8c6044dee6b84923bb8b144f822acecd": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "8f8f19c5218a4f1e9d3b88e50d0f2d00": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "916f252dc32a40f191447a41f2c0675e": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "HBoxModel", - "state": { - "children": [ - "IPY_MODEL_ab42f5e7066d4545a393d75c1da9db9f" - ], - "layout": "IPY_MODEL_cc59ac8811794393b8562754935d03ac" - } - }, - "9177dc7e4bfe45459e3c08aacf360fad": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "PlayModel", - "state": { - "description": "step", - "layout": "IPY_MODEL_06adb370e96f452097b2c8463159fb01", - "max": 9999, - "style": "IPY_MODEL_8be9345e440e408481bd8109c8811c5a", - "value": 442 - } - }, - "91bb487f9240456abbe929cd681b1cb1": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "SliderStyleModel", - "state": { - "description_width": "" - } - }, - "9367ffcacba049b8bfd6b6a3090c510b": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "942bf7fdc02f42b99be6546d4813b139": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "948c747af1ab4020aebde00c9c439900": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "9615034ae68a46638ad79096e22a8572": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "DescriptionStyleModel", - "state": { - "description_width": "" - } - }, - "970f36758fee4afa8c5657b243ef7f58": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "PlayModel", - "state": { - "description": "step", - "layout": "IPY_MODEL_4c05bcf8524c430e897e6640e7bdfb6e", - "max": 9999, - "style": "IPY_MODEL_1627977e1fbf4b91be720a5a0efe7697", - "value": 9774 - } - }, - "971dd0c46be94df996b906d957530175": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "9746c700665145f2b6626ce3eb9c8927": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "VBoxModel", - "state": { - "_dom_classes": [ - "widget-interact" - ], - "children": [ - "IPY_MODEL_6cda5b4c8d8540d3ab9db7eb1ca1b0bb", - "IPY_MODEL_5be025307ba945d1bdc1a4c747ee0f5a" - ], - "layout": "IPY_MODEL_69aaef53d0004a9c8a8350c74cf9ecb6" - } - }, - "993a738490414b5c8c0339f8f87885b7": { - "model_module": "@jupyter-widgets/output", - "model_module_version": "1.0.0", - "model_name": "OutputModel", - "state": { - "layout": "IPY_MODEL_8f8f19c5218a4f1e9d3b88e50d0f2d00", - "outputs": [ - { - "data": { - "image/png": "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wAaBEgAAgA0CJQAAABsESgAAADYIlAAAAGw4KlCaPXu2evXqpcaNG6tFixYaOXKk9uzZc9r35OTkyOPxVHp88sknEWo1AACoqxwVKG3YsEF33nmntm7dqnXr1ikQCGjw4ME6fvz4Gd+7Z88e5efnW4+OHTtGoMUAAKAu80a7ARW9+eabQc+XLVumFi1aaPv27erfv/9p39uiRQudc845YWwdAACobxzVo/R9RUVFkqQmTZqcsW737t2VmpqqQYMGaf369bb1SkpKVFxcHPQAAACoimMDJcMwlJmZqcsuu0xdunSxrZeamqolS5YoOztbL7/8stLS0jRo0CBt3LixyvqzZ89WcnKy9WjTpk24TgEAALicxzAMI9qNqMqdd96p119/XZs3b1br1q2r9d4RI0bI4/Fo9erVlV4rKSlRSUmJ9by4uFht2rRRUVGRkpKSat1uAAAQfsXFxUpOTg77/9+O7FGaOHGiVq9erfXr11c7SJKk3r1769NPP63ytfj4eCUlJQU9AAAAquKoydyGYWjixIlatWqVcnJy1L59+xodJzc3V6mpqSFuHQAAqG8cFSjdeeedev755/Xqq6+qcePGKigokCQlJycrMTFRkjR9+nQdOnRIzz77rCRp7ty5Ov/889W5c2eVlpbqL3/5i7Kzs5WdnR218wAAAHWDowKlRYsWSZIGDhwYVL5s2TKNGzdOkpSfn6+8vDzrtdLSUk2dOlWHDh1SYmKiOnfurNdff13Dhg2LVLMBAEAd5djJ3JESqclgAAAgdOr1ZG4AAAAnIFACAACwQaAEAABgg0AJAADABoESAACADQIlAAAAGwRKAAAANgiUAAAAbBAoAQAA2CBQAgAAsEGgBAAAYINACQAAwAaBEgAAgA0CJQAAABsESgAAADYIlAAAAGwQKAEAANggUAIAALBBoAQAAGCDQAkAAMAGgRIAAIANAiUAAAAbBEoAAAA2CJQAAABsECgBAADYIFACAACwQaAEAABgg0AJAADABoESAACADQIlAAAAGwRKAAAANgiUAAAAbBAoAQAA2CBQAgAAsEGgBAAAYINACQAAwAaBEgAAgA0CJQAAABsESgAAADYIlAAAAGwQKAEAANggUAIAALBBoAQAAGCDQAkAAMAGgRIAAIANAiUAAAAbBEoAAAA2CJQAAABsECgBAADYIFACAACwQaAEAABg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BEoAAAA26mSgtHDhQrVv314JCQlKT0/Xpk2bTlt/w4YNSk9PV0JCgi644AItXry4Up3s7Gx16tRJ8fHx6tSpk1atWhWu5tdYdc775Zdf1pVXXqnmzZsrKSlJGRkZeuutt4LqLF++XB6Pp9LjxIkT4T6VaqnOeefk5FR5Tp988klQvbr2fY8bN67K8+7cubNVx+nf98aNGzVixAi1atVKHo9Hr7zyyhnfUxeu7eqed125tqt73nXl2q7uedeFa1s6uQ9rr1691LhxY7Vo0UIjR47Unj17zvi+SFzjdS5QWrlypSZPnqz77rtPubm56tevn4YOHRqUf6miffv2adiwYerXr59yc3M1Y8YMTZo0SdnZ2VadLVu2aNSoURozZozef/99jRkzRjfccIPefffdSJ3WGVX3vDdu3Kgrr7xSa9as0fbt23X55ZdrxIgRys3NDaqXlJSk/Pz8oEdCQkIkTumsVPe8TXv27Ak6p44dO1qv1cXve968eUHne/DgQTVp0kTXX399UD0nf9/Hjx9Xt27d9PTTT59V/bpybVf3vOvKtV3d8za5/dqu7nnXhWtbOhnw3Hnnndq6davWrVunQCCgwYMH6/jx47bvidg1btQxP/rRj4wJEyYElV144YXGvffeW2X9adOmGRdeeGFQ2e2332707t3ben7DDTcYP/nJT4LqDBkyxLjxxhtD1Oraq+55V6VTp07GrFmzrOfLli0zkpOTQ9XEsKjuea9fv96QZPz3v/+1PWZ9+L5XrVpleDweY//+/VaZG75vkyRj1apVp61TV67tis7mvKvixmu7orM577pybVdUk+/b7de26fDhw4YkY8OGDbZ1InWN16kepdLSUm3fvl2DBw8OKh88eLDeeeedKt+zZcuWSvWHDBmibdu2ye/3n7aO3TEjrSbn/X3l5eU6duxYpV2Yv/76a7Vr106tW7fWVVddVelXaTTV5ry7d++u1NRUDRo0SOvXrw96rT5831lZWbriiiusrPcmJ3/f1VUXru1QcOO1XRtuvrZDoa5c20VFRZJU6d9tRZG6xutUoFRYWKiysjKlpKQElaekpKigoKDK9xQUFFRZPxAIqLCw8LR17I4ZaTU57+97/PHHdfz4cd1www1W2YUXXqjly5dr9erVWrFihRISEtS3b199+umnIW1/TdXkvFNTU7VkyRJlZ2fr5ZdfVlpamgYNGqSNGzdader6952fn6833nhDt956a1C507/v6qoL13YouPHarom6cG3XVl25tg3DUGZmpi677DJ16dLFtl6krnFH7fUWKh6PJ+i5YRiVys5U//vl1T1mNNS0jStWrNBvf/tbvfrqq2rRooVV3rt3b/Xu3dt63rdvX/Xo0UNPPfWU5s+fH7qG11J1zjstLU1paWnW84yMDB08eFCPPfaY+vfvX6NjRktN27h8+XKdc845GjlyZFC5W77v6qgr13ZNuf3aro66dG3XVF25tu+66y598MEH2rx58xnrRuIar1M9Ss2aNVNsbGylSPHw4cOVIkpTy5Ytq6zv9XrVtGnT09axO2ak1eS8TStXrtQtt9yiv/3tb7riiitOWzcmJka9evVyzK+Q2px3Rb179w46p7r8fRuGoaVLl2rMmDGKi4s7bV2nfd/VVReu7dpw87UdKm67tmujrlzbEydO1OrVq7V+/Xq1bt36tHUjdY3XqUApLi5O6enpWrduXVD5unXr1KdPnyrfk5GRUan+2rVr1bNnT/l8vtPWsTtmpNXkvKWTvzbHjRun559/XsOHDz/j5xiGoZ07dyo1NbXWbQ6Fmp739+Xm5gadU139vqWTK0v27t2rW2655Yyf47Tvu7rqwrVdU26/tkPFbdd2bbj92jYMQ3fddZdefvllvf3222rfvv0Z3xOxa/ysp327xAsvvGD4fD4jKyvL+Pjjj43JkycbDRs2tFYA3HvvvcaYMWOs+v/+97+NBg0aGFOmTDE+/vhjIysry/D5fMZLL71k1fnHP/5hxMbGGo888oixe/du45FHHjG8Xq+xdevWiJ+fneqe9/PPP294vV5jwYIFRn5+vvU4evSoVee3v/2t8eabbxqfffaZkZuba4wfP97wer3Gu+++G/Hzs1Pd837yySeNVatWGf/617+MDz/80Lj33nsNSUZ2drZVpy5+36bRo0cbl156aZXHdPr3fezYMSM3N9fIzc01JBlPPPGEkZubaxw4cMAwjLp7bVf3vOvKtV3d864r13Z1z9vk5mvbMAzjjjvuMJKTk42cnJygf7fffPONVSda13idC5QMwzAWLFhgtGvXzoiLizN69OgRtLxw7NixxoABA4Lq5+TkGN27dzfi4uKM888/31i0aFGlY7744otGWlqa4fP5jAsvvDDo4nOK6pz3gAEDDEmVHmPHjrXqTJ482Wjbtq0RFxdnNG/e3Bg8eLDxzjvvRPCMzk51zvvRRx81OnToYCQkJBjnnnuucdlllxmvv/56pWPWte/bMAzj6NGjRmJiorFkyZIqj+f079tc/m33b7auXtvVPe+6cm1X97zryrVdk3/nbr+2DcOo8pwlGcuWLbPqROsa93zXQAAAAHxPnZqjBAAAEEoESgAAADYIlAAAAGwQKAEAANggUAIAALBBoAQAAGCDQAkAAMAGgRIAAIANAiUAdcbAgQPl8Xjk8Xi0c+fOWh1r3Lhx1rFeeeWVkLQPgPsQKAGoU2677Tbl5+erS5cutTrOvHnzlJ+fH6JWAXArb7QbAACh1KBBA7Vs2bLWx0lOTlZycnIIWgTAzehRAuBYK1asUEJCgg4dOmSV3XrrreratauKiorO+jgDBw7UxIkTNXnyZJ177rlKSUnRkiVLdPz4cY0fP16NGzdWhw4d9MYbb4TjNAC4GIESAMe68cYblZaWptmzZ0uSZs2apbfeektvvPFGtXt7nnnmGTVr1kzvvfeeJk6cqDvuuEPXX3+9+vTpox07dmjIkCEaM2aMvvnmm3CcCgCXIlAC4Fgej0e/+93v9Oc//1m///3vNW/ePL355ps677zzqn2sbt266f7771fHjh01ffp0JSYmqlmzZrrtttvUsWNH/eY3v9GRI0f0wQcfhOFMALgVc5QAONpVV12lTp06adasWVq7dq06d+5co+N07drV+nNsbKyaNm2qiy++2CpLSUmRJB0+fLh2DQZQp9CjBMDR3nrrLX3yyScqKyuzgpma8Pl8Qc89Hk9QmcfjkSSVl5fX+DMA1D0ESgAca8eOHbr++uv1xz/+UUOGDNHMmTOj3SQA9QxDbwAcaf/+/Ro+fLjuvfdejRkzRp06dVKvXr20fft2paenR7t5AOoJepQAOM5//vMfDR06VFdffbVmzJghSUpPT9eIESN03333Rbl1AOoTepQAOE6TJk20e/fuSuWvvvpqjY6Xk5NTqWz//v2VygzDqNHxAdRd9CgBqFMWLlyoRo0aadeuXbU6zoQJE9SoUaMQtQqAW3kMfkIBqCMOHTqkb7/9VpLUtm1bxcXF1fhYhw8fVnFxsSQpNTVVDRs2DEkbAbgLgRIAAIANht4AAABsECgBAADYIFACAACwQaAEAABgg0AJAADABoESAACADQIlAAAAGwRKAAAANgiUAAAAbBAoAQAA2Pj/ueCyHx+FsgAAAAAASUVORK5CYII=", - "text/plain": "<Figure size 640x480 with 1 Axes>" - }, - "metadata": {}, - "output_type": "display_data" - } - ] - } - }, - "99c258d501a348199a3483ac52fc44b9": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "LinkModel", - "state": { - "source": [ - "IPY_MODEL_7f10c4ad338f4101a841ddf576814be1", - "value" - ], - "target": [ - "IPY_MODEL_1cbf92cd804447e0b79704651f5a1e89", - "value" - ] - } - }, - "9a1fe753c7ca4968a03715d763592e5c": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "SliderStyleModel", - "state": { - "description_width": "" - } - }, - "9a436ef8b17a4ab1b49a2dab58f70d8f": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "DescriptionStyleModel", - "state": { - "description_width": "" - } - }, - "9c86ab2c7efb4ebfacb92ab22843d8d6": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "9d6a64ca0dbc4748bc5c5a5235366ebd": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "IntSliderModel", - "state": { - "behavior": "drag-tap", - "layout": "IPY_MODEL_e96d58e12e634cbc95fa23dcd6505eef", - "max": 9999, - "style": "IPY_MODEL_41654a25b1e549a99f81f05858197035" - } - }, - "a055c28189d442ffaf15ad332c6a2871": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "HBoxModel", - "state": { - "children": [ - "IPY_MODEL_c076e07eec204cc383b2c7816faad0cb" - ], - "layout": "IPY_MODEL_20fe04e667dc4106941fdfb648cc216a" - } - }, - "a150eeb2e9c6482bbf911b15c4044a53": { - "model_module": "@jupyter-widgets/output", - "model_module_version": "1.0.0", - "model_name": "OutputModel", - "state": { - "layout": "IPY_MODEL_320a66ee1d994dcbbe29188af6aadc84", - "outputs": [ - { - "data": { - "image/png": "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r732ml577bVKr7/wwgt6+OGHFR0drZYtWyo/P79SnarKrNGaxYsX65ZbbtHixYvVrl07DR8+3K7TqlUreTwerVu3zg48KrLKWrduLUn2eqRwaNmypfLy8iqVf/XVV3bbmroDBw5o69atGjJkiGJi+KceCBUjSkATVVZWphdeeEFdunTR6tWrKz3uvPNO5eXl2bePX3jhhfr73//ut8i6rKxMy5Ytq/L4EyZM0ObNm7V+/Xq99dZbGjdunN/01WWXXSZjjA4cOKC+fftWepx77rmSpAEDBigpKUnz58+vdqoomFGeYcOG6dNPP9W2bdv8yl988UV5PB5deOGFNR6jMfv+++910003qbS0VNOnT2/o5gCNGn9mAE3UO++8o6+++kqPPfaYhg4dWun1Hj166Pnnn9fChQt12WWX6b777tOKFSv005/+VL/97W/VrFkzzZkzR0ePHq3y+L/85S+VkZGhX/7ylyouLq50e/7AgQP1P//zP5owYYK2bNmiwYMHq3nz5srLy9P69et17rnn6tZbb1WLFi30xBNP6KabbtJFF12km2++WcnJydq9e7c+/PBDPf/885JkB1aPPfaYRowYoejoaPXs2VOxsbGV2jZ16lS9+OKLuvTSS/Xggw+qU6dOevvttzV37lzdeuut+vGPf1y7/7l16JtvvtGaNWskSTt27JB0/Lts3bq1WrdurSFDhvjVz83N1aZNm1ReXq7CwkLl5ORo0aJF2rdvn5544gm/UT4AIWjAheQA6tCoUaNMbGysOXjwoGOd6667zsTExNh3uv3jH/8w/fv3N3FxcaZt27bm//2//2cWLFjgeOfVr371KyPJDBw40PEzFi1aZM4//3zTvHlzk5CQYLp06WKuv/56s2XLFr96K1euNEOGDDHNmzc3zZo1M926dTOPPfaY/XpxcbG56aabTOvWrY3H4/Fr08l3vRljzL59+8yvfvUr07JlS+P1ek1qaqqZPXu2KSsrs+tUd+eYJPPAAw84npcxzne9NW/evFLdBx54wPGuvaqOWdVjyJAhldpuPaKjo81pp51m0tLSzJQpU8wnn3xS42cBqJnHGG6LAAAAqAprlAAAABwQKAEAADggUAIAAHAQUYHSvHnz1LNnTyUmJioxMVHp6ek17ny9Zs0apaWlKT4+XmeddZbmz59fT60FAABNXUQFSu3bt9ejjz6q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375dKSkptW5zOIR63ifLycnxO6em+n1Lx+8s2b17t2688cYaPyfSvu9gNYVrO1SN/doOl8Z2bddGY7+2jTG644479Prrr+v9999X586da3xPvV3jAS/7biReeeUV4/V6zcKFC82nn35qpkyZYpo3b27fAXD33XebsWPH2vX//e9/m2bNmpmpU6eaTz/91CxcuNB4vV7z2muv2XX+8Y9/mOjoaPPoo4+anTt3mkcffdTExMSYTZs21fv5OQn2vF9++WUTExNj5syZY/Ly8uzH4cOH7Tq/+93vzLvvvmu++OILk5OTYyZMmGBiYmLM5s2b6/38nAR73k899ZRZvny5+de//mU+/vhjc/fddxtJJjMz067TFL9vy5gxY8z5559f5TEj/fs+cuSIycnJMTk5OUaSefLJJ01OTo7Zt2+fMabpXtvBnndTubaDPe+mcm0He96WxnxtG2PMrbfeapKSkkx2drbf7/a7776z6zTUNd7kAiVjjJkzZ47p1KmTiY2NNX369PG7vXDcuHFmyJAhfvWzs7NN7969TWxsrDnzzDPNvHnzKh3z1VdfNampqcbr9Zqzzz7b7+KLFMGc95AhQ4ykSo9x48bZdaZMmWI6duxoYmNjTevWrc3w4cPNhg0b6vGMAhPMeT/22GOmS5cuJj4+3px22mnmggsuMG+//XalYza179sYYw4fPmwSEhLMggULqjxepH/f1u3fTr/ZpnptB3veTeXaDva8m8q1HcrvvLFf28aYKs9Zklm8eLFdp6Gucc8PDQQAAMBJmtQaJQAAgHAiUAIAAHBAoAQAAOCAQAkAAMABgRIAAIADAiUAAAAHBEoAAAAOCJQAAAAcECgBaDKGDh0qj8cjj8ej7du31+pY48ePt4/1xhtvhKV9ABofAiUATcrNN9+svLw89ejRo1bHeeaZZ5SXlxemVgForGIaugEAEE7NmjVT27Zta32cpKQkJSUlhaFFABozRpQARKylS5cqPj5eBw4csMtuuukm9ezZU4WFhQEfZ+jQoZo0aZKmTJmi0047TcnJyVqwYIGOHj2qCRMm6JRTTlGXLl30zjvv1MVpAGjECJQARKzrrrtOqampmjVrliRp5syZeu+99/TOO+8EPdrzwgsvqFWrVvrggw80adIk3Xrrrbrmmms0YMAAbdu2TZdcconGjh2r7777ri5OBUAjRaAEIGJ5PB79/ve/15///Gc98sgjeuaZZ/Tuu+/qjDPOCPpYvXr10n333aeuXbtqxowZSkhIUKtWrXTzzTera9eu+u1vf6tDhw7po48+qoMzAdBYsUYJQES77LLL1K1bN82cOVOrVq1S9+7dQzpOz5497f+Ojo5Wy5Ytde6559plycnJkqSDBw/WrsEAmhRGlABEtPfee0+fffaZysrK7GAmFF6v1++5x+PxK/N4PJKk8vLykD8DQNNDoAQgYm3btk3XXHON/vjHP+qSSy7R/fff39BNAuAyTL0BiEh79+7VpZdeqrvvvltjx45Vt27d1K9fP23dulVpaWkN3TwALsGIEoCI85///EcjRozQFVdcoXvuuUeSlJaWpssvv1z33ntvA7cOgJswogQg4px++unauXNnpfI333wzpONlZ2dXKtu7d2+lMmNMSMcH0HQxogSgSZk7d65atGihHTt21Oo4EydOVIsWLcLUKgCNlcfwJxSAJuLAgQP6/vvvJUkdO3ZUbGxsyMc6ePCgioqKJEkpKSlq3rx5WNoIoHEhUAIAAHDA1BsAAIADAiUAAAAHBEoAAAAOCJQAAAAcECgBAAA4IFACAABwQKAEAADggEAJAADAAYESAACAAwIlAAAAB/8fOa26ueluUSEAAAAASUVORK5CYII=", - "text/plain": "<Figure size 640x480 with 1 Axes>" - }, - "metadata": {}, - "output_type": "display_data" - } - ] - } - }, - "a293a50ba9664d3da139b13f4bce283c": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "SliderStyleModel", - "state": { - "description_width": "" - } - }, - "a72839a02f2445c8a304265a3d757180": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "VBoxModel", - "state": { - "_dom_classes": [ - "widget-interact" - ], - "children": [ - "IPY_MODEL_0eb606f0a9954582867598d517186a3b", - "IPY_MODEL_656efd54140e480db897975d031ffcf1" - ], - "layout": "IPY_MODEL_fcd7375fdf014230a300b03ba461a8d6" - } - }, - "a72e4fe8ecf04fb9925ddd6a235c449d": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "SliderStyleModel", - "state": { - "description_width": "" - } - }, - "a7568c92da3c45b99bf9d04ebf022230": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "a813dd78891c420f8a4477b225e8c5b9": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "SliderStyleModel", - "state": { - "description_width": "" - } - }, - "a95960ed1bf74f569d074e47dce2c9de": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "a98c222629ff4cd1b693037889a6d7b2": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "LinkModel", - "state": { - "source": [ - "IPY_MODEL_ce0293c0184f4edfa7e7c3a773752a83", - "value" - ], - "target": [ - "IPY_MODEL_56183b081add45238ca75241a91faadc", - "value" - ] - } - }, - "ab42f5e7066d4545a393d75c1da9db9f": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "IntSliderModel", - "state": { - "behavior": "drag-tap", - "layout": "IPY_MODEL_0f0919d6a29146829871df260aee51e3", - "max": 999, - "style": "IPY_MODEL_6b5c7e81dc2f480e84c3aaf0d9c6472e", - "value": 613 - } - }, - "af711165b9f347fbb8857a9fad09e7f3": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "IntSliderModel", - "state": { - "behavior": "drag-tap", - "layout": "IPY_MODEL_8c6044dee6b84923bb8b144f822acecd", - "max": 9999, - "style": "IPY_MODEL_fe927fbda0bd4cdd872132f9f1f2846e", - "value": 1745 - } - }, - "b0d238932a794fdcab5f319af14ad86c": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "LinkModel", - "state": { - "source": [ - "IPY_MODEL_6cda5b4c8d8540d3ab9db7eb1ca1b0bb", - "value" - ], - "target": [ - "IPY_MODEL_c076e07eec204cc383b2c7816faad0cb", - "value" - ] - } - }, - "b153a996a6364c55a3f6b38cc7481291": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "b46d9d44e12f4095b8f7514e5255eb86": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "HBoxModel", - "state": { - "children": [ - "IPY_MODEL_6c4277ad49814aefac628aa0aaf1ab08" - ], - "layout": "IPY_MODEL_41cbfd4e0c7042e6aa419a655f8e1bfe" - } - }, - "b6b07613dbe34bb48bdaf77f24b87df6": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "IntSliderModel", - "state": { - "behavior": "drag-tap", - "layout": "IPY_MODEL_32edaabe677448eab2bd9f8b8e167c9f", - "max": 9999, - "style": "IPY_MODEL_9a1fe753c7ca4968a03715d763592e5c", - "value": 442 - } - }, - "b831aaaade704637b922bb05c4f29eef": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "ba0ea63c04e34efdb99e579184cd450d": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "HBoxModel", - "state": { - "children": [ - "IPY_MODEL_883c17bd98b14f9eab6bf5c8a6ad8e96" - ], - "layout": "IPY_MODEL_b831aaaade704637b922bb05c4f29eef" - } - }, - "bd99fcbfcf1f44a49b7b8168d3e40593": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "bef5f3447c7e456494a7b32035bb4a95": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "DescriptionStyleModel", - "state": { - "description_width": "" - } - }, - "c076e07eec204cc383b2c7816faad0cb": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "IntSliderModel", - "state": { - "behavior": "drag-tap", - "layout": "IPY_MODEL_86a3f84417b843388d2bc76372c68536", - "max": 999, - "style": "IPY_MODEL_0fea6efd37c34272b7810500b9f57936", - "value": 882 - } - }, - "c5b771ced109463a8def66c0152089f4": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "c64dfe4ed7e34116b9729c7438235cb6": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "SliderStyleModel", - "state": { - "description_width": "" - } - }, - "c7e53e2cb900438994ad4a976ed38f09": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "PlayModel", - "state": { - "description": "step", - "layout": "IPY_MODEL_a7568c92da3c45b99bf9d04ebf022230", - "max": 9999, - "style": "IPY_MODEL_c80dbe9594674511b7a2ebceceee30e6" - } - }, - "c80dbe9594674511b7a2ebceceee30e6": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "DescriptionStyleModel", - "state": { - "description_width": "" - } - }, - "c874f8d826d34f37aaddc03e5e7c8509": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "HBoxModel", - "state": { - "children": [ - "IPY_MODEL_1cbf92cd804447e0b79704651f5a1e89" - ], - "layout": "IPY_MODEL_6dc714ca412242d39549385e291640fd" - } - }, - "c8b7b83c2294407caed2b93a136abda7": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "cb18dc1bcf2f4a62a67a8e9d59099554": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "cc45ea152448414d9e78d4dab82c6c45": { - "model_module": "@jupyter-widgets/output", - "model_module_version": "1.0.0", - "model_name": "OutputModel", - "state": { - "layout": "IPY_MODEL_7de4ad6416ad484580cb7423474d4d3e", - "outputs": [ - { - "data": { - "image/png": "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evToNpddA0BeXh7GjRuHYcOGIScnBy+99BKeffZZZGVlaepkZ2cjOTkZ06ZNw9GjRzFt2jRMmTIFBw8etESziIiIyI5Z9Wq+q1evomvXrti9ezeSkpJarfPiiy9i06ZNOHnypKZszpw5OHr0KLKzswEAycnJKC8v12w8CAD33XcfunTpgoyMDPM2goiIiOyaVW/aqT4gtb0zo7Kzs3U2nBszZgxWr16N+vp6uLq6Ijs7G/PmzdOps3Tp0lbvWVtbi9raWs21SqXCtWvX4OfnZ7JDVomIiMi8RFFERUUFunXrBicn8w3GWW0yJYoiUlJScNdddyEqKqrNekVFRVon2ANAYGAgGhoaUFJSguDg4DbrtHaeGNA0d2vhwoXGN4KIiIgkd/HiRZMelN6S1SZTTz/9NH799Vfs27fvlnVb9hapRy6bl7dWp61eptTUVKSkpGiulUolQkJCcPHiRfj4+HS4DURERCSd8vJy9OzZE506dTLr51hlMvXMM89g06ZN2LNnzy0zyaCgIJ0epuLiYri4uMDPz6/dOi17q9Tc3d1bPcHex8eHyRQREZGNMfcUHatazSeKIp5++mmsW7cOO3bsQFhY2C3fEx8fj+3bt2uVbdu2DUOGDIGrq2u7dRISEkwXPBERETkkq0qmnnrqKXzxxRf48ssv0alTJxQVFaGoqAg1NTWaOqmpqXjkkUc013PmzMGFCxeQkpKCkydPYs2aNVi9ejWef/55TZ3nnnsO27Ztw+LFi3Hq1CksXrwYP/74I+bOnWvJ5hEREZEdsqqtEdrqhvvss88wY8YMAMCMGTOQn5+PXbt2ab6+e/duzJs3D7/99hu6deuGF198EXPmzNG6x7fffotXXnkF58+fR3h4OP75z39i8uTJHYqrvLwccrkcSqWSw3xEREQ2wlK/v60qmbJWTKaIiIhsj6V+f1vVMB8RERGRrWEyRURERGQEJlNERERERmAyRURERGQEJlNERERERmAyRURERGQEJlNERERERmAyRURERGQEJlNERERERmAyRURERGQEJlNERERERmAyRURERGQEJlNERERERmAyRURERGQEJlNERERERmAyRURERGQEJlNERERERmAyRURERGQEJlNERERERmAyRURERGQEJlNERERERmAyRURERGQEJlNERERERmAyRURERGQEJlNERERERmAyRURE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+ukn0dnZWVy0aJF48uRJcdGiRaKLi4t44MABi7evLfq2+8svvxRdXFzEFStWiAqFQvMqKyvT1HnttdfEH374QTx37pyYk5Mjzpw5U3RxcREPHjxo8fa1Rd92v//+++L69evF33//XTx+/Lg4f/58EYCYlZWlqWOP32+1qVOnikOHDm31ntb+/a6oqBBzcnLEnJwcEYD43nvviTk5OeKFCxdEUbTfZ1vfdtvLs61vu+3l2da33Wq2/GyLoig++eSTolwuF3ft2qX1/211dbWmjlTPuEMmU6IoiitWrBBDQ0NFNzc3cfDgwVpLK6dPny7efffdWvV37dolRkdHi25ubmKvXr3Ejz76SOee33zzjRgRESG6urqK/fr103pArYU+7b777rtFADqv6dOna+rMnTtXDAkJEd3c3MSAgABx9OjR4v79+y3Yoo7Rp92LFy8Ww8PDRZlMJnbp0kW86667xO+//17nnvb2/RZFUSwrKxM9PDzETz75pNX7Wfv3W730va3/Z+312da33fbybOvbbnt5tg35/9zWn21RFFttMwDxs88+09SR6hkXbgZIRERERAZwuDlTRERERKbEZIqIiIjICEymiIiIiIzAZIqIiIjICEymiIiIiIzAZIqIiIjICEymiIiIiIzAZIqIiIjICEymiMih3HPPPRAEAYIgIDc316h7zZgxQ3OvDRs2mCQ+IrI9TKaIyOE89thjUCgUiIqKMuo+y5Ytg0KhMFFURGSrXKQOgIjI0jw9PREUFGT0feRyOeRyuQkiIiJbxp4pIrJpGRkZkMlkKCws1JTNnj0bAwcOhFKp7PB97rnnHjzzzDOYO3cuunTpgsDAQHzyySeoqqrCzJkz0alTJ4SHh2PLli3maAYR2TAmU0Rk0/785z8jIiICaWlpAICFCxdi69at2LJli969Rv/+97/h7++Pn3/+Gc888wyefPJJPPzww0hISMCRI0cwZswYTJs2DdXV1eZoChHZKCZTRGTTBEHAP//5T3z66ad46623sGzZMvzwww/o3r273vcaNGgQXnnlFfTp0wepqanw8PCAv78/HnvsMfTp0wf/+Mc/UFpail9//dUMLSEiW8U5U0Rk8+6//35ERkZi4cKF2LZtG/r372/QfQYOHKj5b2dnZ/j5+WHAgAGassDAQABAcXGxcQETkV1hzxQR2bytW7fi1KlTaGxs1CQ8hnB1ddW6FgRBq0wQBACASqUy+DOIyP4wmSIim3bkyBE8/PDD+PjjjzFmzBgsWLBA6pCIyMFwmI+IbFZ+fj7Gjx+P+fPnY9q0aYiMjERsbCwOHz6MmJgYqcMjIgfBnikisknXrl3D2LFj8cADD+Cll14CAMTExGDChAl4+eWXJY6OiBwJe6aIyCb5+vri5MmTOuUbN2406H67du3SKcvPz9cpE0XRoPsTkf1izxQROZyVK1fC29sbx44dM+o+c+bMgbe3t4miIiJbJYj8M4uIHEhhYSFqamoAACEhIXBzczP4XsXFxSgvLwcABAcHw8vLyyQxEpFtYTJFREREZAQO8xEREREZgckUERERkRGYTBEREREZgckUERERkRGYTBEREREZgckUERERkRGYTBEREREZgckUERERkRGYTBEREREZgckUERERkRH+H9eTTdwQO2dvAAAAAElFTkSuQmCC", - "text/plain": "<Figure size 640x480 with 1 Axes>" - }, - "metadata": {}, - "output_type": "display_data" - } - ] - } - }, - "cc59ac8811794393b8562754935d03ac": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "ce0293c0184f4edfa7e7c3a773752a83": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "PlayModel", - "state": { - "description": "step", - "layout": "IPY_MODEL_d99a4e6aebd8415fba8c77274b6cd597", - "max": 9999, - "style": "IPY_MODEL_9a436ef8b17a4ab1b49a2dab58f70d8f", - "value": 3705 - } - }, - "ce28bcf090b144c5a34a61d93169cf81": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "HBoxModel", - "state": { - "children": [ - "IPY_MODEL_b6b07613dbe34bb48bdaf77f24b87df6" - ], - "layout": "IPY_MODEL_b153a996a6364c55a3f6b38cc7481291" - } - }, - "cf5b1b468eb84dc28fb66e3a798aa74c": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "PlayModel", - "state": { - "description": "step", - "layout": "IPY_MODEL_d4934da185764a938fb3b2430f414bbf", - "max": 999, - "style": "IPY_MODEL_2634261c2d124fcaaa5e90b770cdedda", - "value": 603 - } - }, - "d05124351f7a4915b7c815918be4d93b": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "HBoxModel", - "state": { - "children": [ - "IPY_MODEL_1b9b858f039c4dc2a04fc125fcd88cd4" - ], - "layout": "IPY_MODEL_f8712758714e473dbe11fcb68e86fc54" - } - }, - "d149c879ba5e4f07a5a4fda68591ff4a": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "VBoxModel", - "state": { - "_dom_classes": [ - "widget-interact" - ], - "children": [ - "IPY_MODEL_7f10c4ad338f4101a841ddf576814be1", - "IPY_MODEL_a150eeb2e9c6482bbf911b15c4044a53" - ], - "layout": "IPY_MODEL_07ad0b7f06b5448d9c863b4780bca156" - } - }, - "d2364ca2ae1a4088a5e77bcd68fbfb84": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "VBoxModel", - "state": { - "_dom_classes": [ - "widget-interact" - ], - "children": [ - "IPY_MODEL_39324860e713440498dd2238f37c6250", - "IPY_MODEL_cc45ea152448414d9e78d4dab82c6c45" - ], - "layout": "IPY_MODEL_65d60095e2734129937ad8d2620e8f92" - } - }, - "d4934da185764a938fb3b2430f414bbf": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "d8793922da25405da6cd5b7aa8446373": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "SliderStyleModel", - "state": { - "description_width": "" - } - }, - "d99a4e6aebd8415fba8c77274b6cd597": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "de2e5c28ab474b5490fda00ffa872f22": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "VBoxModel", - "state": { - "_dom_classes": [ - "widget-interact" - ], - "children": [ - "IPY_MODEL_5bc18ece0a9843d697664579831dc33c", - "IPY_MODEL_5e6c742952034f5986f188d65e9d1cbe" - ], - "layout": "IPY_MODEL_66bd8ae571ac4cf2bd9fcfa21904aca1" - } - }, - "e1d342daa7ac441084efceb9d8d910a0": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "DescriptionStyleModel", - "state": { - "description_width": "" - } - }, - "e7ec156bc3b349839c0179ceb9476de1": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "LinkModel", - "state": { - "source": [ - "IPY_MODEL_5bc18ece0a9843d697664579831dc33c", - "value" - ], - "target": [ - "IPY_MODEL_9d6a64ca0dbc4748bc5c5a5235366ebd", - "value" - ] - } - }, - "e8982f5972f14db4bf2f611e49b75f87": { - "model_module": "@jupyter-widgets/output", - "model_module_version": "1.0.0", - "model_name": "OutputModel", - "state": { - "layout": "IPY_MODEL_5617e97c6ddb4d2f8a8aa131c91cde5a", - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": "<Figure size 1100x700 with 2 Axes>" - }, - "metadata": {}, - "output_type": "display_data" - } - ] - } - }, - "e96d58e12e634cbc95fa23dcd6505eef": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "e9cf902de1034631a131ba686a34ae81": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "VBoxModel", - "state": { - "_dom_classes": [ - "widget-interact" - ], - "children": [ - "IPY_MODEL_ce0293c0184f4edfa7e7c3a773752a83", - "IPY_MODEL_13aba5ea04d74b40b4da582ea5ad51fa" - ], - "layout": "IPY_MODEL_1889a83a2bab41dfa859502229370773" - } - }, - "ec55a750fc194d6b9ba7c32094debc2c": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "ef927fb5a3a74241b6449c5a302eb232": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "f02da2a5b0c6430f9a38bf0a58036d62": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "VBoxModel", - "state": { - "_dom_classes": [ - "widget-interact" - ], - "children": [ - "IPY_MODEL_26c50a763abf447a877b6559f17238f0", - "IPY_MODEL_1c409ebf433849c29e10d6119b614cbb" - ], - "layout": "IPY_MODEL_2e84a81901e74c9fb4cd6a843ae1b41f" - } - }, - "f090113b148f47afb4bfab581cdd9ad6": { - "model_module": "@jupyter-widgets/output", - "model_module_version": "1.0.0", - "model_name": "OutputModel", - "state": { - "layout": "IPY_MODEL_41d2b49ef8d6477aab5bfafaf9646730", - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkQAAAHHCAYAAABeLEexAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABEU0lEQVR4nO3deXhU9d3+8ftkTyAJkEAWIRAQkH0JVMImiuIDVKWoxVoUUPsrFlFMqQJqfdwISrWoCBQLrlWpBiw+opKWvYKyBAVk1UAgTAhBmQTIQpLz+yPOSEhAkkwyy3m/rmsune+cOfMJ4XJuv6thmqYpAAAAC/NzdwEAAADuRiACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACLOKll16SYRjq2rVrjd73+uuvyzAMHTx4sH4Ku0QrVqzQ//7v/1b7Wps2bTR+/PgGrUeS1qxZI8MwtGbNGpfdc8OGDbrnnnuUlJSk4ODgC/7ZHzx4UIZhOB+BgYGKiopS37599eCDD2rXrl0uqwmwAgIRYBGLFy+WJO3atUtffPGFm6upuRUrVuiJJ56o9rVly5bpsccea+CKpN69e2vjxo3q3bu3y+75n//8R//+97+VkJCg/v37/+z1kydP1saNG7V27Vq99dZbGjVqlJYvX64ePXpo9uzZLqsL8HUEIsACtmzZoq+++kojR46UJC1atMjNFblWr1691K5duwb/3IiICPXr108REREuu+djjz2mgwcPatmyZc7f18UkJCSoX79+6t+/v0aMGKFHHnlEO3fu1HXXXaeHHnpIn3zyictqA3wZgQiwAEcAmjVrlvr376/33ntPZ86cqXLdpk2bNGDAAIWEhCg+Pl7Tp0/X2bNnK10zatQotW7dWuXl5VXef+WVV1bqLTFNU/PmzVPPnj0VGhqqpk2b6pZbbtF3331X5b2ffvqphg4dqsjISIWFhalTp05KTU2VJI0fP16vvPKKJFUaJnIMJVU3ZJaVlaWxY8eqRYsWCg4OVqdOnfT8889Xqtsx7PSXv/xFL7zwghITE9W4cWMlJydr06ZNP/vnWt2Q2fjx49W4cWMdOHBAI0aMUOPGjdWqVSv98Y9/VHFx8c/e08+v7v9ZDg0N1aJFixQYGEgvEXCJCESAjyssLNS7776rvn37qmvXrrrrrrtUUFCg999/v9J133zzjYYOHaqTJ0/q9ddf14IFC5SRkaGnn3660nV33XWXsrKytGrVqkrte/bs0ZdffqkJEyY4237/+99rypQpuvbaa/Xhhx9q3rx52rVrl/r3769jx445r1u0aJFGjBih8vJyLViwQB999JHuv/9+HTlyRFJFr8ktt9wiSdq4caPzERcXV+3PfPz4cfXv318rV67UU089peXLl+vaa6/V1KlTdd9991W5/pVXXlF6errmzJmjf/zjHzp9+rRGjBghu91egz/pn5w9e1Y33nijhg4dqn/961+666679Ne//lXPPvtsre5XG/Hx8UpKStLnn3+u0tLSBvtcwGuZAHzam2++aUoyFyxYYJqmaRYUFJiNGzc2Bw0aVOm6MWPGmKGhoWZOTo6zrbS01LziiitMSWZmZqZpmqZ59uxZMyYmxrz99tsrvf+hhx4yg4KCzLy8PNM0TXPjxo2mJPP555+vdN3hw4fN0NBQ86GHHnLWExERYQ4cONAsLy+/4M8xadIk80L/yWrdurU5btw45/Np06aZkswvvvii0nX33nuvaRiGuXfvXtM0TTMzM9OUZHbr1s0sLS11Xvfll1+aksx33333gvWYpmmuXr3alGSuXr3a2TZu3DhTkvnPf/6z0rUjRowwO3bseNH7nW/27NmV/uzP5ah99uzZF3z/mDFjTEnmsWPHavS5gBXRQwT4uEWLFik0NFS33XabJKlx48a69dZbtX79eu3fv9953erVqzV06FDFxMQ42/z9/TVmzJhK9wsICNDYsWO1dOlSZw9KWVmZ3nrrLd10002KioqSJP3f//2fDMPQ2LFjVVpa6nzExsaqR48ezmGmzz//XPn5+frDH/4gwzBc8jOvWrVKnTt31i9+8YtK7ePHj5dpmlV6t0aOHCl/f3/n8+7du0uSDh06VKvPNwxDN9xwQ6W27t271/p+tWWaZoN+HuDNCESADztw4IDWrVunkSNHyjRNnTx5UidPnnQOPzlWnknSiRMnFBsbW+Ue1bXdddddKioq0nvvvSdJ+uyzz2Sz2SoNlx07dkymaSomJkaBgYGVHps2bVJeXp6kiuEtSWrZsqXLfu4TJ05UO5wWHx/vfP1cjhDnEBwcLKliuLE2wsLCFBISUuWeRUVFtbpfbR06dEjBwcFq1qxZg34u4I0C3F0AgPqzePFimaapDz74QB988EGV19944w09/fTT8vf3V1RUlHJycqpcU12bo/fltdde0+9//3u99tprio+P17Bhw5zXREdHyzAMrV+/3hkwzuVoa968uSQ55wu5QlRUlGw2W5X2o0ePOmvzddnZ2dq6dauuuuoqBQTwn3rg59BDBPiosrIyvfHGG2rXrp1Wr15d5fHHP/5RNpvNuSz76quv1n/+859Kk53Lysq0ZMmSau8/YcIEffHFF9qwYYM++ugjjRs3rtKw0y9/+UuZpqns7Gz16dOnyqNbt26SpP79+ysyMlILFiy46BBPTXpthg4dqm+++Ubbtm2r1P7mm2/KMAxdffXVP3sPb1ZYWKh77rlHpaWleuihh9xdDuAV+N8GwEd98sknOnr0qJ599lkNGTKkyutdu3bV3LlztWjRIv3yl7/Uo48+quXLl+uaa67Rn//8Z4WFhemVV17R6dOnq73/b37zG6WkpOg3v/mNiouLqyx7HzBggP7f//t/mjBhgrZs2aLBgwerUaNGstls2rBhg7p166Z7771XjRs31vPPP6977rlH1157rX73u98pJiZGBw4c0FdffaW5c+dKkjNAPfvssxo+fLj8/f3VvXt3BQUFVantwQcf1JtvvqmRI0fqySefVOvWrfXxxx9r3rx5uvfee9WhQ4e6/eHWo+PHj2vt2rWSpB07dkiq+F02b95czZs311VXXVXp+qysLG3atEnl5eWy2+3KyMjQ4sWLdejQIT3//POVeu0AXIQbJ3QDqEejRo0yg4KCzNzc3Atec9ttt5kBAQHOlWX//e9/zX79+pnBwcFmbGys+ac//clcuHDhBVc63X777aYkc8CAARf8jMWLF5tXXnml2ahRIzM0NNRs166deeedd5pbtmypdN2KFSvMq666ymzUqJEZFhZmdu7c2Xz22WedrxcXF5v33HOP2bx5c9MwjEo1nb/KzDRN89ChQ+btt99uRkVFmYGBgWbHjh3N2bNnm2VlZc5rLrZSS5L5+OOPX/DnMs0LrzJr1KhRlWsff/zxC66Sq+6e1T2uuuqqKrU7Hv7+/mbTpk3NpKQkc8qUKeauXbt+9rMA/MQwTZYhAAAAa2MOEQAAsDwCEQAAsDwCEQAAsDyPCkTz589X9+7dFRERoYiICCUnJ//sSc1r165VUlKSQkJC1LZtWy1YsKCBqgUAAL7CowJRy5YtNWvWLG3ZskVbtmzRNddco5tuukm7du2q9vrMzEyNGDFCgwYNUkZGhmbMmKH7779faWlpDVw5AADwZh6/yqxZs2aaPXu27r777iqvPfzww1q+fLl2797tbJs4caK++uorbdy4sSHLBAAAXsxjN2YsKyvT+++/r9OnTys5ObnaazZu3Fhl07Hrr79eixYt0tmzZxUYGFjlPcXFxSouLnY+Ly8v1/fff6+oqCiXHSwJAADql2maKigoUHx8vPz86j7g5XGBaMeOHUpOTlZRUZEaN26sZcuWqXPnztVem5OTU+lkbkmKiYlRaWmp8vLyqj3cMTU1VU888US91A4AABrW4cOHXXI4tMcFoo4dO2r79u06efKk0tLSNG7cOK1du/aCoej8Xh3HCOCFenumT5+ulJQU53O73a6EhAQdPnxYERERLvopAABAfcrPz1erVq0UHh7ukvt5XCAKCgrS5ZdfLknq06ePNm/erBdffFF/+9vfqlwbGxtb5STu3NxcBQQEKCoqqtr7BwcHV3vytmNlGwAA8B6umu7iUavMqmOaZqU5P+dKTk5Wenp6pbaVK1eqT58+1c4fAgAAqI5HBaIZM2Zo/fr1OnjwoHbs2KFHHnlEa9as0W9/+1tJFcNdd955p/P6iRMn6tChQ0pJSdHu3bu1ePFiLVq0SFOnTnXXjwAAALyQRw2ZHTt2THfccYdsNpsiIyPVvXt3ffrpp7ruuuskSTabTVlZWc7rExMTtWLFCj344IN65ZVXFB8fr5deekk333yzu34EAADghTx+H6L6lp+fr8jISNntduYQAQDgJVz9/e1RQ2YAAADuQCACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACW51GBKDU1VX379lV4eLhatGihUaNGae/evRd9z5o1a2QYRpXHnj17GqhqAADg7TwqEK1du1aTJk3Spk2blJ6ertLSUg0bNkynT5/+2ffu3btXNpvN+Wjfvn0DVAwAAHxBgLsLONenn35a6flrr72mFi1aaOvWrRo8ePBF39uiRQs1adKkHqsDAAC+yqN6iM5nt9slSc2aNfvZa3v16qW4uDgNHTpUq1evvuB1xcXFys/Pr/QAAADW5rGByDRNpaSkaODAgeratesFr4uLi9PChQuVlpampUuXqmPHjho6dKjWrVtX7fWpqamKjIx0Plq1alVfPwIAAPAShmmapruLqM6kSZP08ccfa8OGDWrZsmWN3nvDDTfIMAwtX768ymvFxcUqLi52Ps/Pz1erVq1kt9sVERFR57oBAED9y8/PV2RkpMu+vz2yh2jy5Mlavny5Vq9eXeMwJEn9+vXT/v37q30tODhYERERlR4AAMDaPGpStWmamjx5spYtW6Y1a9YoMTGxVvfJyMhQXFyci6sDAAC+yqMC0aRJk/TOO+/oX//6l8LDw5WTkyNJioyMVGhoqCRp+vTpys7O1ptvvilJmjNnjtq0aaMuXbqopKREb7/9ttLS0pSWlua2nwMAAHgXjwpE8+fPlyQNGTKkUvtrr72m8ePHS5JsNpuysrKcr5WUlGjq1KnKzs5WaGiounTpoo8//lgjRoxoqLIBAICX89hJ1Q3F1ZOyAABA/bPEpGoAAICGRCACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACWRyACAACW51GBKDU1VX379lV4eLhatGihUaNGae/evT/7vrVr1yopKUkhISFq27atFixY0ADVAgAAX+FRgWjt2rWaNGmSNm3apPT0dJWWlmrYsGE6ffr0Bd+TmZmpESNGaNCgQcrIyNCMGTN0//33Ky0trQErBwAA3swwTdN0dxEXcvz4cbVo0UJr167V4MGDq73m4Ycf1vLly7V7925n28SJE/XVV19p48aNP/sZ+fn5ioyMlN1uV0REhMtqBwAA9cfV398e1UN0PrvdLklq1qzZBa/ZuHGjhg0bVqnt+uuv15YtW3T27Nkq1xcXFys/P7/SAwAAWJvHBiLTNJWSkqKBAweqa9euF7wuJydHMTExldpiYmJUWlqqvLy8KtenpqYqMjLS+WjVqpXLawcAAN7FYwPRfffdp6+//lrvvvvuz15rGEal545RwPPbJWn69Omy2+3Ox+HDh11TMAAA8FoB7i6gOpMnT9by5cu1bt06tWzZ8qLXxsbGKicnp1Jbbm6uAgICFBUVVeX64OBgBQcHu7ReAADg3Tyqh8g0Td13331aunSpVq1apcTExJ99T3JystLT0yu1rVy5Un369FFgYGB9lQoAAHyIRwWiSZMm6e2339Y777yj8PBw5eTkKCcnR4WFhc5rpk+frjvvvNP5fOLEiTp06JBSUlK0e/duLV68WIsWLdLUqVPd8SMAAAAv5FGBaP78+bLb7RoyZIji4uKcjyVLljivsdlsysrKcj5PTEzUihUrtGbNGvXs2VNPPfWUXnrpJd18883u+BEAAIAXqtE+RMuXL6/xB1x33XUKDQ2t8fsaCvsQAQDgfVz9/V2jSdWjRo2q0c0Nw9D+/fvVtm3bGr0PAACgIdV4yCwnJ0fl5eWX9AgLC6uPmgEAAFyqRoFo3LhxNRr+Gjt2LMNQAADA43n0WWYNgTlEAAB4H0udZQYAANAQXBKItm3bppKSElfcCgAAoMG5JBD17dtXBw8edMWtAAAAGpxLApHFpyEBAAAvxxwiAABgeQQiAABgeQQiAABgeQQiAABgeQQiAABgeQQiAABgeS4JRI8//riio6NdcSsAAIAGx1lmnGUGAIDXcetZZl9//bXKy8sv+fpdu3aptLS0xkUBAAA0pBoFol69eunEiROXfH1ycrKysrJqXBQAAEBDCqjJxaZp6rHHHlNYWNglXc+BrwAAwBvUKBANHjxYe/fuveTrk5OTFRoaWuOiAAAAGlKNAtGaNWvqqQwAAAD3YR8iAABgeQQiAABgeQQiAABgeQQiAABgeTWaVH2+bdu2af369QoKCtKAAQPUvXt3V9UFAADQYGodiObMmaOUlBQ1adJEAQEBysvLU5cuXfT6668rKSnJlTUCAADUqxoNmS1evFjbtm1TcXGxZs6cqVmzZunEiRPKzc3VoUOHdNNNN2nIkCHasGFDfdULAADgcjU63LVTp046cOCAJKm8vFyjR49WcnKyevfurZ49e6pJkyaaP3++3njjDW3atKneinYlDncFAMD7uPVw1927d6ugoECff/65AgMD5efnp3/+858aOXKkoqKi1Lp1a73//vvKyMjQRx99pMzMzDoXCAAAUN9qvMosJCREffv21YABA9SjRw9t2rRJBQUF+vrrr5WamqoOHTro7NmzGj9+vNq1a0evCwAA8Hi1nlT9/PPPa8iQIfruu+80ceJE9ejRQwkJCdq2bZvi4+N15MgRHTlyRDt37nRlvQAAAC5X60DUs2dPbd26VRMnTlS/fv3kmIoUEBCgxYsXS5Jatmypli1buqZSAACAelKnfYjatWun9PR0HTt2TJs2bVJJSYn69eunVq1auao+AACAelenQOQQExOjm266yRW3AgAAaHAc3QEAACyPQAQAACyPQAQAACyPQAQAACyPQAQAACyvXgKRn5+frrnmGm3durU+bg8AAOBS9RKIFi9erKuuukr3339/fdweAADApWp02r0v4rR7AAC8j1tPuwcAAPBFdQpE69ev19ixY5WcnKzs7GxJ0ltvvaUNGza4pDgAAICGUOtAlJaWpuuvv16hoaHKyMhQcXGxJKmgoEAzZ850WYEAAAD1rdaB6Omnn9aCBQv06quvKjAw0Nnev39/bdu2zSXFAQAANIRaB6K9e/dq8ODBVdojIiJ08uTJutQEAADQoGodiOLi4nTgwIEq7Rs2bFDbtm3rVBQAAEBDqnUg+v3vf68HHnhAX3zxhQzD0NGjR/WPf/xDU6dO1R/+8AdX1ggAAFCvAmr7xoceekh2u11XX321ioqKNHjwYAUHB2vq1Km67777XFkjAABAvarTsvtnnnlGeXl5+vLLL7Vp0yYdP35cTz31VK3vt27dOt1www2Kj4+XYRj68MMPL3r9mjVrZBhGlceePXtqXQMAALCeWvcQOYSFhalPnz6uqEWnT59Wjx49NGHCBN18882X/L69e/dW2qWyefPmLqkHAABYQ40CUUpKyiVf+8ILL9S4mOHDh2v48OE1fl+LFi3UpEmTGr8PAABAqmEgysjIqPR869atKisrU8eOHSVJ+/btk7+/v5KSklxX4SXo1auXioqK1LlzZz366KO6+uqrL3htcXGxcxNJqeIsFAAAYG01CkSrV692/vsLL7yg8PBwvfHGG2ratKkk6YcfftCECRM0aNAg11Z5AXFxcVq4cKGSkpJUXFyst956S0OHDtWaNWuq3SNJklJTU/XEE080SH0AAMA71Pq0+8suu0wrV65Uly5dKrXv3LlTw4YN09GjR+tWmGFo2bJlGjVqVI3ed8MNN8gwDC1fvrza16vrIWrVqhWn3QMA4EU85rT7/Px8HTt2rEp7bm6uCgoK6lRUXfTr10/79++/4OvBwcGKiIio9AAAANZW60D0q1/9ShMmTNAHH3ygI0eO6MiRI/rggw909913a/To0a6ssUYyMjIUFxfnts8HAADep9bL7hcsWKCpU6dq7NixOnv2rEzTVGBgoO6++27Nnj27Vvc8depUpeNAMjMztX37djVr1kwJCQmaPn26srOz9eabb0qS5syZozZt2qhLly4qKSnR22+/rbS0NKWlpdX2xwIAABZU60AUFhamefPmafbs2fr2229lmqYuv/xyNWrUqNbFbNmypdIKMccy/3Hjxun111+XzWZTVlaW8/WSkhJNnTpV2dnZCg0NVZcuXfTxxx9rxIgRta4BAABYT60nVT/55JMXff3Pf/5zrQpqaK6elAUAAOqfq7+/a91DtGzZskrPz549q8zMTAUEBKhdu3ZeE4gAAABqHYjO36RRqkhr48eP169+9as6FQUAANCQ6nS46/kiIiL05JNP6rHHHnPlbQEAAOqVSwORJJ08eVJ2u93Vt4WHs9kL9fm3ebLZC91dCgAANVbrIbOXXnqp0nPTNGWz2fTWW2/pf/7nf+pcGLzHks1Zmr50h8pNyc+QUkd305i+Ce4uCwCAS1brVWaJiYmVnvv5+al58+a65pprNH36dIWHh7ukwPrGKrO6sdkLNWDWKpWf87fI3zC0YdrViosMdV9hAACf5jGrzDIzM+v84fB+mXmnK4UhSSozTR3MO0MgAgB4jVrPIcrKytKFOpfO3TwRvu3EqeJq26MbBzVwJQAA1F6tA1FiYqKOHz9epf3E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", - "text/plain": "<Figure size 640x480 with 1 Axes>" - }, - "metadata": {}, - "output_type": "display_data" - } - ] - } - }, - "f295d4d179ee4740bd871149bce2d558": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "f5be0a5143ea40f4bc6c5978ee36f54f": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "f6a9b4d7f41d435e9087825265f19ed3": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "f8712758714e473dbe11fcb68e86fc54": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "fcd7375fdf014230a300b03ba461a8d6": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} - }, - "fd48764d8839460a8c983f2e74353d65": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "DescriptionStyleModel", - "state": { - "description_width": "" - } - }, - "fe927fbda0bd4cdd872132f9f1f2846e": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "SliderStyleModel", - "state": { - "description_width": "" - } - } - }, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/synced_files/students/Week_2_1/WS_2_1_wiggle.md b/synced_files/students/Week_2_1/WS_2_1_wiggle.md deleted file mode 100644 index cff1273e60de0748a471962604d9cff072c2ae05..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_2_1/WS_2_1_wiggle.md +++ /dev/null @@ -1,575 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: mude-base - language: python - name: python3 ---- - -# WS 2.1: Wiggles - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 90px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -</h1> -<h2 style="height: 25px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 2.1, Wednesday November 13, 2024.* - -<!-- #region --> -## Overview: - -In this workshop the advection problem from the textbook is treated first in 1D and then in 2D. R - -$$ -\frac{\partial \phi}{\partial t} + c\frac{\partial \phi}{\partial x} = 0 -$$ - -There are two main objectives: -1. Understand the advection problem itself (how the quantity of interest is transported by the velocity field) -2. Explore characteristics of the numerical analysis schemes employed, in particular: numerical diffusion and FVM stability - -To do this we will do the following: -- Implement the central difference and upwind schemes in space for FVM and Forward Euler in time -- Apply a boundary condition such that the quantity of interest repeatedly travels through the plot window (this helps us visualize the process!) -- Evaluate stability of central difference and upwind schemes in combination with Forward Euler in time -- Use the CFL to understand numerical stability - -Programming requirements: you will need to fill in a few missing pieces of the functions, but mostly you will change the values of a few Python variables to evaluate different aspects of the problem. - - -The following Python variables will be defined to set up the problem: -``` -p0 = initial value of our "pulse" (the quantity of interest, phi) [-] -c = speed of the velocity field [m/s] -L = length of the domain [m] -Nx = number of volumes in the direction x -T = duration of the simulation (maximum time) [s] -Nt = number of time steps -``` - -There are also two flag variables: 1) `central` will allow you to switch between central and backward spatial discretization schemes, and 2) `square` changes the pulse from a square to a smooth bell curve (default for both is `True`; don't worry about it until instructed to change it). - -For the 2D case, `c`, `L`, `Nx` are extended as follows: -``` -c --> cx, cy -L --> Lx, Ly -Nx -> Nx, Ny -``` -<!-- #endregion --> - -## Part 1: Implement Central Averaging - -We are going to implement the central averaging scheme as derived in the textbook; however, **instead of implementing the system of equations in a matrix formulation**, we will _loop over each of the finite volumes in the system,_ one at a time. - -Because we will want to watch the "pulse" travel over a long period of time, we will take advantage of the reverse-indexing of Python (i.e., the fact that an index `a[-3]`, for example, will access the third item from the end of the array or list). When taking the volumes to the left of the first volume in direction $x$, we can use the values of $phi$ from the "last" volumes in $x$ (the end of the array). All we need to do is shift the index for $phi_i$ such that we avoid a situation where `i+1` "breaks" the loop (because the maximum index is `i`). In other words, only volumes with index `i` or smaller should be used (e.g., instead of `i-1`, `i`, and `i+1`, use `i-2`, `i-1` and `i`. - -_Note: remmeber that the term "central difference" was used in the finite difference method; we use the term "central averaging" here, or "linear interpolation," as used in the book, to indicate that the finite volume method is interpolating across the volume (using the boundaries/faces)._ - - - -<div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.1:</b> - -Write by hand for FMV the <code>advection_1D</code> equation, compute the convective fluxes of $\phi$ at the surfaces using a linear interpolation (central averaging). Then apply Forward Euler in time to the resulting ODE. Make sure you use the right indexing (maximum index should be <code>i</code>). - -$$ -\frac{\partial \phi}{\partial t} + c\frac{\partial \phi}{\partial x} = 0 -$$ - -</div> - - - -<div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.2:</b> - -<b>Read.</b> Read the code to understand the problem that has been set up for you. Check the arguments and return values; the docstrings are purposefully ommitted so you can focus on the code. You might as well re-read the instructions above one more time, as well (let's be honest, you probably just skimmed over it anyway...) - -</div> - -```python -import numpy as np -import matplotlib.pylab as plt -%matplotlib inline -from ipywidgets import interact, fixed, widgets -import matplotlib.pyplot as plt -from mpl_toolkits.mplot3d import Axes3D -``` - - -<div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3:</b> - -Implement the scheme in the function <code>advection_1D</code>. Make sure you use the right indexing (maximum index should be <code>i</code>). - -</div> - - -Complete the functions to solve the 1D problem. A plotting function has already been defined, which will be used to check your initial conditions and visualize time steps in the solution. - -```python -def initialize_1D(p0, L, Nx, T, Nt, square=True): - """Initialize 1D advection simulation. - - Arguments are defined elsewhere, except one keyword argument - defines the shape of the initial condition. - - square : bool - - specifies a square pulse if True - - specifies a Gaussian shape if False - """ - - dx = L/Nx - dt = T/Nt - - x = np.linspace(dx/2, L - dx/2, Nx) - - - if square: - p_init = np.zeros(Nx) - p_init[int(.5/dx):int(1/dx + 1)] = p0 - else: - p_init = np.exp(-((x-1.0)/0.5**2)**2) - - p_all = np.zeros((Nt+1, Nx)) - p_all[0] = p_init - return x, p_all - -def advection_1D(p, dx, dt, c, Nx, central=True): - """Solve the advection problem.""" - p_new = np.zeros(Nx) - for i in range(0, Nx): - if central: - pass # add central averaging + FE scheme here (remove pass) - else: - pass # add upwind + FE scheme here (remove pass) - return p_new - -def run_simulation_1D(p0, c, L, Nx, T, Nt, dx, dt, - central=True, square=True): - """Run sumulation by evaluating each time step.""" - - x, p_all = initialize_1D(p0, L, Nx, T, Nt, square=square) - - for t in range(Nt): - p = advection_1D(p_all[t], dx, dt, c, Nx, central=central) - p_all[t + 1] = p - - return x, p_all - -def plot_1D(x, p, step=0): - """Plot phi(x, t) at a given time step.""" - fig = plt.figure() - ax = plt.axes(xlim=(0, round(x.max())), - ylim=(0, int(np.ceil(p[0].max())) + 1)) - ax.plot(x, p[step], marker='.') - plt.xlabel('$x$ [m]') - plt.ylabel('Amplitude, $phi$ [$-$]') - plt.title('Advection in 1D') - plt.show() - -def plot_1D_all(): - """Create animation of phi(x, t) for all t.""" - check_variables_1D() - - play = widgets.Play(min=0, max=Nt-1, step=1, value=0, - interval=100, disabled=False) - slider = widgets.IntSlider(min=0, max=Nt-1, step=1, value=0) - widgets.jslink((play, 'value'), (slider, 'value')) - - interact(plot_1D, x=fixed(x), p=fixed(p_all), step=play) - - return widgets.HBox([slider]) - -def check_variables_1D(): - """Print current variable values. - - Students define CFL. - """ - print('Current variables values:') - print(f' p0 [---]: {p0:0.2f}') - print(f' c [m/s]: {c:0.2f}') - print(f' L [ m ]: {L:0.1f}') - print(f' Nx [---]: {Nx:0.1f}') - print(f' T [ s ]: {T:0.1f}') - print(f' Nt [---]: {Nt:0.1f}') - print(f' dx [ m ]: {dx:0.2e}') - print(f' dt [ s ]: {dt:0.2e}') - print(f'Using central difference?: {central}') - print(f'Using square init. cond.?: {square}') - calculated_CFL = None - if calculated_CFL is None: - print('CFL not calculated yet.') - else: - print(f'CFL: {calculated_CFL:.2e}') -``` - -Variables are set below, then you should use the functions provided, for example, `check_variables_1D`, prior to running a simulation to make sure you are solving the problem you think you are! - -```python -p0 = 2.0 -c = 5.0 - -L = 2.0 -Nx = 100 -T = 40 -Nt = 10000 - -dx = L/Nx -dt = T/Nt - -central = True -square = True -``` - -_You can ignore any warning that result from running the code below._ - -```python -check_variables_1D() -x, p_all = run_simulation_1D(p0, c, L, Nx, T, Nt, dx, dt, central, square) -``` - -Use the plotting function to check your initial values. It should look like a "box" shape somwhere in the $x$ domain with velocity $c$ m/s. - -```python -plot_1D(x, p_all) -``` - -Visualize. At the very beginning, you should see the wave moving from the left to right. What happens afterwards? - -```python -plot_1D_all() -``` - -## Part 2: Central Difference issues! - -The discretization is unstable (regardless of the time step used), largely due to weighting equally the influence by adjacent volumes in the fluxes. The hyperbolic nature of the equation implies that more weight should be given to the upstream/upwind $\phi$ values. - -You might think that the initial abrupt edges of the square wave are responsible for the instability. You can test this by replacing the square pulse with a smooth one. - - - -<div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2:</b> -Run the 1D simulation again using a smooth pulse. You can do this by changing the value of `square` from `True` to `False`. Does the simulation work? -</div> - -```python -square=False -x, p_all = run_simulation_1D(p0, c, L, Nx, T, Nt, dx, dt, central, square) -plot_1D_all() -``` - -## Task 3: Upwind scheme - -More weight can be given to the upwind cells by choosing $\phi$ values for the East face $\phi_i$, and for the West face, use $\phi_{i-1}$. This holds true for positive flow directions. For negative flow directions, you should choose $\phi$ values for the East face $\phi_{i-1}$, and for the West face, use $\phi_{i}$. Note that this is less accurate than the central diffence approach but it will ensure stability. - - - -<div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 3.1:</b> - -Derive the upwind scheme and apply Forward Euler to the resulting ODE. Then implement it in the function <code>advection_1D</code>. Re-run the analysis after setting the <code>central</code> flag to <code>False</code>. - -</div> - -```python -# re-define key variables and use run_simulation_1D() and plot_1D_all() -``` - - -<div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 3.2:</b> - -In the previous task you should have seen that the method is unstable. Experiment with different time step $\Delta t$ to see if you can find a limit above/below which the method is stable. Write down your $\Delta t$ values and whether or not they were stable, as we will reflect on them later. - -</div> - -```python -# you can change variable values and rerun the analysis here. -``` - -_Write your time stepts here, along with the result:_ - -| $\Delta t$ | stable or unstable? | -| :---: | :---: | -| | | - - -## Part 4: False Diffusion - -In the previous tasks, we saw how upwinding can be an effective way to handle the type of PDE we are studying (in this case hyperbolic). Now, we will consider _another_ aspect of stability: that of the time integration scheme. - -Let’s play with the code. In convective kinematics a von Neumann analysis on the advection equation suggests that the following must hold for stability: -$$ -CFL = \frac{c \Delta t}{\Delta x} \leq 1 -$$ - -$CFL$ is the Courant–Friedrichs–Lewy condtion, a dimensionless quantity that relates the speed of information leaves a finite volume, relating speed to the ratio of time step duration and cell length. The ratio can provide us an indication of the inherent stability of explicit schemes. - - - - -<div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 4.1:</b> -If you have not already done so, modify the function above to calculate the CFL and run the function <code>check_variables_1D()</code> to check the values. Evaluate the CFL for the time steps you tried in Task 3.2 and write them below, along with the statement of whether or not the scheme was stable. -</div> - - -_Write your CFL values here, along with the result:_ - -| CFL | $\Delta t$ | stable or unstable? | -| :---: | :---: | :---: | -| | | | - - - -<div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 4.2:</b> - -Now use the CFL to compute the time step $\Delta t$ that defines the boundary between the stable and unstable region. Then re-run the analysis for this value, as well as a value that is slightly above and below that threshold $\Delta t$. -</div> - -```python -# re-define key variables and use run_simulation_1D() and plot_1D_all() -``` - -### So you think everything is stable and perfect, right? - -Based on the previous task, it looks like we have a good handle on this problem, and are able to use the CFL to set up a reliable numerical scheme for all sorts of complex problems---right?! - -**WRONG!** - -Remember, in this problem we are dealing with single "wave" propagating at a _constant_ speed. In practice we apply numerical schemes to more complex methods. For example, most problems consider _variable_ speed/velocity in more than one dimension. When this is the case, the problem cannot be described by a single CFL value! As a rule of thumb, a modeller would then choose a conservative CFL value, determined by the largest expected flow velocities (in the case of a regular mesh). - -Let's apply this concept by using a CFL condition of 0.8 to visualize the impact on the numerical solution. - - - -<div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 4.3:</b> - -Find $\Delta t$ such that CFL is 0.8 and re-run the analysis. What do you observe? - -<em>Make sure you look at the complete solution, not just the first few steps.</em> - -</div> - -```python -# re-define key variables and use run_simulation_1D() and plot_1D_all() -``` - - -<div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 4.4:</b> - -Describe what you observe in the result of the previous task and state (yes/no) whether or not this should be expected, given the PDE we are solving. Explain your answer in a couple sentences. - -</div> - - -_Write your answer here._ - - -## Part 5: 2D Implementation in Python - - -<div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 5.1:</b> -Apply FVM by hand to the 2D advection equation. The volumes are rectangular. This is a good example of an exam problem. - -$$ -\frac{\partial \phi}{\partial t} + c_x\frac{\partial \phi}{\partial x} + c_y\frac{\partial \phi}{\partial y} = 0 -$$ - -</div> - - -<div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 5.2:</b> -The code is set up in a very similar way to the 1D case above. Use it to explore how the advection problem works in 2D! In particular, see if you observe the effect called "numerical diffusion" --- when the numerical scheme causes the square pulse to "diffuse" into a bell shaped surface. Even though only the advection term was implmented! -</div> - -<!-- #region id="0491cc69" --> -<div style="background-color:#facb8e; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> - <p> - The initial values of the variables below will result in numerical instability. See if you can fix it! - </p> -</div> -<!-- #endregion --> - -```python -p0 = 2.0 -cx = 5.0 -cy = 5.0 - -Lx = 2.0 -Nx = 100 -Ly = 2.0 -Ny = 100 -T = 40 -Nt = 900 - -dx = Lx/Nx -dy = Ly/Ny -dt = T/Nt - -central = True -``` - -```python -def initialize_2D(p0, Lx, Nx, Ly, Ny, T, Nt): - x = np.linspace(dx/2, Lx - dx/2, Nx) - y = np.linspace(dy/2, Ly - dx/2, Ny) - X, Y = np.meshgrid(x, y) - - # Initialise domain: cubic pulse with p0 between 0.5 and 1 - p_init = np.zeros((Nx, Ny)) - p_init[int(0.5/dx):int(1/dx + 1), int(0.5/dy):int(1/dy + 1)] = p0 - - p_all = np.zeros((Nt + 1, Nx, Ny)) - p_all[0] = p_init - return X, Y, p_all - -def advection_2D(p, cx, cy, Nx, Ny, dx, dy, dt, central=True): - - p_new = np.ones((Nx,Ny)) - - for i in range(0, Nx): - for j in range(0, Ny): - if central: - p_new[i-1,j-1] = (p[i-1,j-1] - - 0.5*(cx*dt/dx)*(p[i,j-1] - p[i-2,j-1]) - - 0.5*(cy*dt/dy)*(p[i-1,j] - p[i-1,j-2])) - else: - p_new[i, j] = (p[i, j] - (cx*dt/dx)*(p[i, j] - p[i - 1, j]) - - (cy*dt/dy)*(p[i, j] - p[i, j - 1])) - return p_new - -def run_simulation_2D(p0, cx, cy, Lx, Nx, Ly, Ny, - T, Nt, dx, dy, dt, central=True): - - X, Y, p_all = initialize_2D(p0, Lx, Nx, Ly, Ny, T, Nt) - - for t in range(Nt): - p = advection_2D(p_all[t], cx, cy, Nx, Ny, - dx, dy, dt, central=central) - p_all[t + 1] = p - - return X, Y, p_all - -def plot_2D(p, X, Y, step=0): - 'Create 2D plot, X and Y are formatted as meshgrid.''' - fig = plt.figure(figsize=(11, 7), dpi=100) - ax = fig.add_subplot(111, projection='3d') - ax.set_xlabel('x [m]') - ax.set_ylabel('y [m]') - ax.set_zlabel('$\phi$ [-]') - ax.set_title('Advection in 2D') - surf = ax.plot_surface(X, Y, p[step], - cmap='Blues', rstride=2, cstride=2) - fig.colorbar(surf, shrink=0.5, aspect=5) - plt.show() - -def plot_2D_all(): - check_variables_2D() - - play = widgets.Play(min=0, max=Nt-1, step=1, value=0, - interval=100, disabled=False) - slider = widgets.IntSlider(min=0, max=Nt-1, - step=1, value=0) - widgets.jslink((play, 'value'), (slider, 'value')) - - interact(plot_2D, - p=fixed(p_all), - X=fixed(X), - Y=fixed(Y), - step=play) - - return widgets.HBox([slider]) - -def check_variables_2D(): - print('Current variables values:') - print(f' p0 [---]: {p0:0.2f}') - print(f' cx [m/s]: {cx:0.2f}') - print(f' cy [m/s]: {cy:0.2f}') - print(f' Lx [ m ]: {Lx:0.1f}') - print(f' Nx [---]: {Nx:0.1f}') - print(f' Ly [ m ]: {Ly:0.1f}') - print(f' Ny [---]: {Ny:0.1f}') - print(f' T [ s ]: {T:0.1f}') - print(f' Nt [---]: {Nt:0.1f}') - print(f' dx [ m ]: {dx:0.2e}') - print(f' dy [ m ]: {dy:0.2e}') - print(f' dt [ s ]: {dt:0.2e}') - print(f'Using central difference?: {central}') - print(f'Solution shape p_all[t_i]: ({Nx}, {Ny})') - print(f'Total time steps in p_all: {Nt+1}') - print(f'CFL, direction x: {cx*dt/dx:.2e}') - print(f'CFL, direction y: {cy*dt/dy:.2e}') -``` - -```python -T = 1 -Nt = 1000 -dt = T/Nt -check_variables_2D() -X, Y, p_all = initialize_2D(p0, Lx, Nx, Ly, Ny, T, Nt) -plot_2D(p_all, X, Y) -``` - -```python -X, Y, p_all = run_simulation_2D(p0, cx, cy, Lx, Nx, Ly, Ny, T, Nt, dx, dy, dt, central) -plot_2D_all() -``` - -```python -X, Y, p_all = run_simulation_2D(p0, cx, cy, Lx, Nx, Ly, Ny, T, Nt, dx, dy, dt, central=False) -plot_2D_all() -``` - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Week_2_1/WS_2_1_wiggle.py b/synced_files/students/Week_2_1/WS_2_1_wiggle.py deleted file mode 100644 index aa0f471b7b515347e3144aa9706e06ed69e5d09d..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_2_1/WS_2_1_wiggle.py +++ /dev/null @@ -1,575 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: mude-base -# language: python -# name: python3 -# --- - -# %% [markdown] -# # WS 2.1: Wiggles -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 90px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -# </h1> -# <h2 style="height: 25px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 2.1, Wednesday November 13, 2024.* - -# %% [markdown] -# ## Overview: -# -# In this workshop the advection problem from the textbook is treated first in 1D and then in 2D. R -# -# $$ -# \frac{\partial \phi}{\partial t} + c\frac{\partial \phi}{\partial x} = 0 -# $$ -# -# There are two main objectives: -# 1. Understand the advection problem itself (how the quantity of interest is transported by the velocity field) -# 2. Explore characteristics of the numerical analysis schemes employed, in particular: numerical diffusion and FVM stability -# -# To do this we will do the following: -# - Implement the central difference and upwind schemes in space for FVM and Forward Euler in time -# - Apply a boundary condition such that the quantity of interest repeatedly travels through the plot window (this helps us visualize the process!) -# - Evaluate stability of central difference and upwind schemes in combination with Forward Euler in time -# - Use the CFL to understand numerical stability -# -# Programming requirements: you will need to fill in a few missing pieces of the functions, but mostly you will change the values of a few Python variables to evaluate different aspects of the problem. -# -# -# The following Python variables will be defined to set up the problem: -# ``` -# p0 = initial value of our "pulse" (the quantity of interest, phi) [-] -# c = speed of the velocity field [m/s] -# L = length of the domain [m] -# Nx = number of volumes in the direction x -# T = duration of the simulation (maximum time) [s] -# Nt = number of time steps -# ``` -# -# There are also two flag variables: 1) `central` will allow you to switch between central and backward spatial discretization schemes, and 2) `square` changes the pulse from a square to a smooth bell curve (default for both is `True`; don't worry about it until instructed to change it). -# -# For the 2D case, `c`, `L`, `Nx` are extended as follows: -# ``` -# c --> cx, cy -# L --> Lx, Ly -# Nx -> Nx, Ny -# ``` - -# %% [markdown] -# ## Part 1: Implement Central Averaging -# -# We are going to implement the central averaging scheme as derived in the textbook; however, **instead of implementing the system of equations in a matrix formulation**, we will _loop over each of the finite volumes in the system,_ one at a time. -# -# Because we will want to watch the "pulse" travel over a long period of time, we will take advantage of the reverse-indexing of Python (i.e., the fact that an index `a[-3]`, for example, will access the third item from the end of the array or list). When taking the volumes to the left of the first volume in direction $x$, we can use the values of $phi$ from the "last" volumes in $x$ (the end of the array). All we need to do is shift the index for $phi_i$ such that we avoid a situation where `i+1` "breaks" the loop (because the maximum index is `i`). In other words, only volumes with index `i` or smaller should be used (e.g., instead of `i-1`, `i`, and `i+1`, use `i-2`, `i-1` and `i`. -# -# _Note: remmeber that the term "central difference" was used in the finite difference method; we use the term "central averaging" here, or "linear interpolation," as used in the book, to indicate that the finite volume method is interpolating across the volume (using the boundaries/faces)._ - -# %% [markdown] -# -# <div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.1:</b> -# -# Write by hand for FMV the <code>advection_1D</code> equation, compute the convective fluxes of $\phi$ at the surfaces using a linear interpolation (central averaging). Then apply Forward Euler in time to the resulting ODE. Make sure you use the right indexing (maximum index should be <code>i</code>). -# -# $$ -# \frac{\partial \phi}{\partial t} + c\frac{\partial \phi}{\partial x} = 0 -# $$ -# -# </div> - -# %% [markdown] -# -# <div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.2:</b> -# -# <b>Read.</b> Read the code to understand the problem that has been set up for you. Check the arguments and return values; the docstrings are purposefully ommitted so you can focus on the code. You might as well re-read the instructions above one more time, as well (let's be honest, you probably just skimmed over it anyway...) -# -# </div> - -# %% -import numpy as np -import matplotlib.pylab as plt -# %matplotlib inline -from ipywidgets import interact, fixed, widgets -import matplotlib.pyplot as plt -from mpl_toolkits.mplot3d import Axes3D - - -# %% [markdown] -# -# <div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3:</b> -# -# Implement the scheme in the function <code>advection_1D</code>. Make sure you use the right indexing (maximum index should be <code>i</code>). -# -# </div> - -# %% [markdown] -# Complete the functions to solve the 1D problem. A plotting function has already been defined, which will be used to check your initial conditions and visualize time steps in the solution. - -# %% -def initialize_1D(p0, L, Nx, T, Nt, square=True): - """Initialize 1D advection simulation. - - Arguments are defined elsewhere, except one keyword argument - defines the shape of the initial condition. - - square : bool - - specifies a square pulse if True - - specifies a Gaussian shape if False - """ - - dx = L/Nx - dt = T/Nt - - x = np.linspace(dx/2, L - dx/2, Nx) - - - if square: - p_init = np.zeros(Nx) - p_init[int(.5/dx):int(1/dx + 1)] = p0 - else: - p_init = np.exp(-((x-1.0)/0.5**2)**2) - - p_all = np.zeros((Nt+1, Nx)) - p_all[0] = p_init - return x, p_all - -def advection_1D(p, dx, dt, c, Nx, central=True): - """Solve the advection problem.""" - p_new = np.zeros(Nx) - for i in range(0, Nx): - if central: - pass # add central averaging + FE scheme here (remove pass) - else: - pass # add upwind + FE scheme here (remove pass) - return p_new - -def run_simulation_1D(p0, c, L, Nx, T, Nt, dx, dt, - central=True, square=True): - """Run sumulation by evaluating each time step.""" - - x, p_all = initialize_1D(p0, L, Nx, T, Nt, square=square) - - for t in range(Nt): - p = advection_1D(p_all[t], dx, dt, c, Nx, central=central) - p_all[t + 1] = p - - return x, p_all - -def plot_1D(x, p, step=0): - """Plot phi(x, t) at a given time step.""" - fig = plt.figure() - ax = plt.axes(xlim=(0, round(x.max())), - ylim=(0, int(np.ceil(p[0].max())) + 1)) - ax.plot(x, p[step], marker='.') - plt.xlabel('$x$ [m]') - plt.ylabel('Amplitude, $phi$ [$-$]') - plt.title('Advection in 1D') - plt.show() - -def plot_1D_all(): - """Create animation of phi(x, t) for all t.""" - check_variables_1D() - - play = widgets.Play(min=0, max=Nt-1, step=1, value=0, - interval=100, disabled=False) - slider = widgets.IntSlider(min=0, max=Nt-1, step=1, value=0) - widgets.jslink((play, 'value'), (slider, 'value')) - - interact(plot_1D, x=fixed(x), p=fixed(p_all), step=play) - - return widgets.HBox([slider]) - -def check_variables_1D(): - """Print current variable values. - - Students define CFL. - """ - print('Current variables values:') - print(f' p0 [---]: {p0:0.2f}') - print(f' c [m/s]: {c:0.2f}') - print(f' L [ m ]: {L:0.1f}') - print(f' Nx [---]: {Nx:0.1f}') - print(f' T [ s ]: {T:0.1f}') - print(f' Nt [---]: {Nt:0.1f}') - print(f' dx [ m ]: {dx:0.2e}') - print(f' dt [ s ]: {dt:0.2e}') - print(f'Using central difference?: {central}') - print(f'Using square init. cond.?: {square}') - calculated_CFL = None - if calculated_CFL is None: - print('CFL not calculated yet.') - else: - print(f'CFL: {calculated_CFL:.2e}') - - -# %% [markdown] -# Variables are set below, then you should use the functions provided, for example, `check_variables_1D`, prior to running a simulation to make sure you are solving the problem you think you are! - -# %% -p0 = 2.0 -c = 5.0 - -L = 2.0 -Nx = 100 -T = 40 -Nt = 10000 - -dx = L/Nx -dt = T/Nt - -central = True -square = True - -# %% [markdown] -# _You can ignore any warning that result from running the code below._ - -# %% -check_variables_1D() -x, p_all = run_simulation_1D(p0, c, L, Nx, T, Nt, dx, dt, central, square) - -# %% [markdown] -# Use the plotting function to check your initial values. It should look like a "box" shape somwhere in the $x$ domain with velocity $c$ m/s. - -# %% -plot_1D(x, p_all) - -# %% [markdown] -# Visualize. At the very beginning, you should see the wave moving from the left to right. What happens afterwards? - -# %% -plot_1D_all() - -# %% [markdown] -# ## Part 2: Central Difference issues! -# -# The discretization is unstable (regardless of the time step used), largely due to weighting equally the influence by adjacent volumes in the fluxes. The hyperbolic nature of the equation implies that more weight should be given to the upstream/upwind $\phi$ values. -# -# You might think that the initial abrupt edges of the square wave are responsible for the instability. You can test this by replacing the square pulse with a smooth one. - -# %% [markdown] -# -# <div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2:</b> -# Run the 1D simulation again using a smooth pulse. You can do this by changing the value of `square` from `True` to `False`. Does the simulation work? -# </div> - -# %% -square=False -x, p_all = run_simulation_1D(p0, c, L, Nx, T, Nt, dx, dt, central, square) -plot_1D_all() - -# %% [markdown] -# ## Task 3: Upwind scheme -# -# More weight can be given to the upwind cells by choosing $\phi$ values for the East face $\phi_i$, and for the West face, use $\phi_{i-1}$. This holds true for positive flow directions. For negative flow directions, you should choose $\phi$ values for the East face $\phi_{i-1}$, and for the West face, use $\phi_{i}$. Note that this is less accurate than the central diffence approach but it will ensure stability. - -# %% [markdown] -# -# <div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 3.1:</b> -# -# Derive the upwind scheme and apply Forward Euler to the resulting ODE. Then implement it in the function <code>advection_1D</code>. Re-run the analysis after setting the <code>central</code> flag to <code>False</code>. -# -# </div> - -# %% -# re-define key variables and use run_simulation_1D() and plot_1D_all() - -# %% [markdown] -# -# <div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 3.2:</b> -# -# In the previous task you should have seen that the method is unstable. Experiment with different time step $\Delta t$ to see if you can find a limit above/below which the method is stable. Write down your $\Delta t$ values and whether or not they were stable, as we will reflect on them later. -# -# </div> - -# %% -# you can change variable values and rerun the analysis here. - -# %% [markdown] -# _Write your time stepts here, along with the result:_ -# -# | $\Delta t$ | stable or unstable? | -# | :---: | :---: | -# | | | - -# %% [markdown] -# ## Part 4: False Diffusion -# -# In the previous tasks, we saw how upwinding can be an effective way to handle the type of PDE we are studying (in this case hyperbolic). Now, we will consider _another_ aspect of stability: that of the time integration scheme. -# -# Let’s play with the code. In convective kinematics a von Neumann analysis on the advection equation suggests that the following must hold for stability: -# $$ -# CFL = \frac{c \Delta t}{\Delta x} \leq 1 -# $$ -# -# $CFL$ is the Courant–Friedrichs–Lewy condtion, a dimensionless quantity that relates the speed of information leaves a finite volume, relating speed to the ratio of time step duration and cell length. The ratio can provide us an indication of the inherent stability of explicit schemes. -# - -# %% [markdown] -# -# <div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 4.1:</b> -# If you have not already done so, modify the function above to calculate the CFL and run the function <code>check_variables_1D()</code> to check the values. Evaluate the CFL for the time steps you tried in Task 3.2 and write them below, along with the statement of whether or not the scheme was stable. -# </div> - -# %% [markdown] -# _Write your CFL values here, along with the result:_ -# -# | CFL | $\Delta t$ | stable or unstable? | -# | :---: | :---: | :---: | -# | | | | - -# %% [markdown] -# -# <div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 4.2:</b> -# -# Now use the CFL to compute the time step $\Delta t$ that defines the boundary between the stable and unstable region. Then re-run the analysis for this value, as well as a value that is slightly above and below that threshold $\Delta t$. -# </div> - -# %% -# re-define key variables and use run_simulation_1D() and plot_1D_all() - -# %% [markdown] -# ### So you think everything is stable and perfect, right? -# -# Based on the previous task, it looks like we have a good handle on this problem, and are able to use the CFL to set up a reliable numerical scheme for all sorts of complex problems---right?! -# -# **WRONG!** -# -# Remember, in this problem we are dealing with single "wave" propagating at a _constant_ speed. In practice we apply numerical schemes to more complex methods. For example, most problems consider _variable_ speed/velocity in more than one dimension. When this is the case, the problem cannot be described by a single CFL value! As a rule of thumb, a modeller would then choose a conservative CFL value, determined by the largest expected flow velocities (in the case of a regular mesh). -# -# Let's apply this concept by using a CFL condition of 0.8 to visualize the impact on the numerical solution. - -# %% [markdown] -# -# <div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 4.3:</b> -# -# Find $\Delta t$ such that CFL is 0.8 and re-run the analysis. What do you observe? -# -# <em>Make sure you look at the complete solution, not just the first few steps.</em> -# -# </div> - -# %% -# re-define key variables and use run_simulation_1D() and plot_1D_all() - -# %% [markdown] -# -# <div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 4.4:</b> -# -# Describe what you observe in the result of the previous task and state (yes/no) whether or not this should be expected, given the PDE we are solving. Explain your answer in a couple sentences. -# -# </div> - -# %% [markdown] -# _Write your answer here._ - -# %% [markdown] -# ## Part 5: 2D Implementation in Python - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 5.1:</b> -# Apply FVM by hand to the 2D advection equation. The volumes are rectangular. This is a good example of an exam problem. -# -# $$ -# \frac{\partial \phi}{\partial t} + c_x\frac{\partial \phi}{\partial x} + c_y\frac{\partial \phi}{\partial y} = 0 -# $$ -# -# </div> - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 5.2:</b> -# The code is set up in a very similar way to the 1D case above. Use it to explore how the advection problem works in 2D! In particular, see if you observe the effect called "numerical diffusion" --- when the numerical scheme causes the square pulse to "diffuse" into a bell shaped surface. Even though only the advection term was implmented! -# </div> - -# %% [markdown] id="0491cc69" -# <div style="background-color:#facb8e; color: black; width: 95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# The initial values of the variables below will result in numerical instability. See if you can fix it! -# </p> -# </div> - -# %% -p0 = 2.0 -cx = 5.0 -cy = 5.0 - -Lx = 2.0 -Nx = 100 -Ly = 2.0 -Ny = 100 -T = 40 -Nt = 900 - -dx = Lx/Nx -dy = Ly/Ny -dt = T/Nt - -central = True - - -# %% -def initialize_2D(p0, Lx, Nx, Ly, Ny, T, Nt): - x = np.linspace(dx/2, Lx - dx/2, Nx) - y = np.linspace(dy/2, Ly - dx/2, Ny) - X, Y = np.meshgrid(x, y) - - # Initialise domain: cubic pulse with p0 between 0.5 and 1 - p_init = np.zeros((Nx, Ny)) - p_init[int(0.5/dx):int(1/dx + 1), int(0.5/dy):int(1/dy + 1)] = p0 - - p_all = np.zeros((Nt + 1, Nx, Ny)) - p_all[0] = p_init - return X, Y, p_all - -def advection_2D(p, cx, cy, Nx, Ny, dx, dy, dt, central=True): - - p_new = np.ones((Nx,Ny)) - - for i in range(0, Nx): - for j in range(0, Ny): - if central: - p_new[i-1,j-1] = (p[i-1,j-1] - - 0.5*(cx*dt/dx)*(p[i,j-1] - p[i-2,j-1]) - - 0.5*(cy*dt/dy)*(p[i-1,j] - p[i-1,j-2])) - else: - p_new[i, j] = (p[i, j] - (cx*dt/dx)*(p[i, j] - p[i - 1, j]) - - (cy*dt/dy)*(p[i, j] - p[i, j - 1])) - return p_new - -def run_simulation_2D(p0, cx, cy, Lx, Nx, Ly, Ny, - T, Nt, dx, dy, dt, central=True): - - X, Y, p_all = initialize_2D(p0, Lx, Nx, Ly, Ny, T, Nt) - - for t in range(Nt): - p = advection_2D(p_all[t], cx, cy, Nx, Ny, - dx, dy, dt, central=central) - p_all[t + 1] = p - - return X, Y, p_all - -def plot_2D(p, X, Y, step=0): - 'Create 2D plot, X and Y are formatted as meshgrid.''' - fig = plt.figure(figsize=(11, 7), dpi=100) - ax = fig.add_subplot(111, projection='3d') - ax.set_xlabel('x [m]') - ax.set_ylabel('y [m]') - ax.set_zlabel('$\phi$ [-]') - ax.set_title('Advection in 2D') - surf = ax.plot_surface(X, Y, p[step], - cmap='Blues', rstride=2, cstride=2) - fig.colorbar(surf, shrink=0.5, aspect=5) - plt.show() - -def plot_2D_all(): - check_variables_2D() - - play = widgets.Play(min=0, max=Nt-1, step=1, value=0, - interval=100, disabled=False) - slider = widgets.IntSlider(min=0, max=Nt-1, - step=1, value=0) - widgets.jslink((play, 'value'), (slider, 'value')) - - interact(plot_2D, - p=fixed(p_all), - X=fixed(X), - Y=fixed(Y), - step=play) - - return widgets.HBox([slider]) - -def check_variables_2D(): - print('Current variables values:') - print(f' p0 [---]: {p0:0.2f}') - print(f' cx [m/s]: {cx:0.2f}') - print(f' cy [m/s]: {cy:0.2f}') - print(f' Lx [ m ]: {Lx:0.1f}') - print(f' Nx [---]: {Nx:0.1f}') - print(f' Ly [ m ]: {Ly:0.1f}') - print(f' Ny [---]: {Ny:0.1f}') - print(f' T [ s ]: {T:0.1f}') - print(f' Nt [---]: {Nt:0.1f}') - print(f' dx [ m ]: {dx:0.2e}') - print(f' dy [ m ]: {dy:0.2e}') - print(f' dt [ s ]: {dt:0.2e}') - print(f'Using central difference?: {central}') - print(f'Solution shape p_all[t_i]: ({Nx}, {Ny})') - print(f'Total time steps in p_all: {Nt+1}') - print(f'CFL, direction x: {cx*dt/dx:.2e}') - print(f'CFL, direction y: {cy*dt/dy:.2e}') - - -# %% -T = 1 -Nt = 1000 -dt = T/Nt -check_variables_2D() -X, Y, p_all = initialize_2D(p0, Lx, Nx, Ly, Ny, T, Nt) -plot_2D(p_all, X, Y) - -# %% -X, Y, p_all = run_simulation_2D(p0, cx, cy, Lx, Nx, Ly, Ny, T, Nt, dx, dy, dt, central) -plot_2D_all() - -# %% -X, Y, p_all = run_simulation_2D(p0, cx, cy, Lx, Nx, Ly, Ny, T, Nt, dx, dy, dt, central=False) -plot_2D_all() - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Week_2_2/WS_2_2_more_support.ipynb b/synced_files/students/Week_2_2/WS_2_2_more_support.ipynb deleted file mode 100644 index 1bf3bf6bd19ebbb333da8f097cc5fee518af6ee2..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_2_2/WS_2_2_more_support.ipynb +++ /dev/null @@ -1,251 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "e9d1ff8c", - "metadata": {}, - "source": [ - "# WS 2.2: More support\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px\" />\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px\" />\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 2.2. For: 20 November, 2024*" - ] - }, - { - "cell_type": "markdown", - "id": "576445ba-cfe4-4c22-acbf-5d5fc6d0da1c", - "metadata": {}, - "source": [ - "In the book, the finite element derivation and implementation of rod extension (the 1D Poisson equation) is presented. In this workshop, you are asked to do the same for a slightly different problem.\n", - "\n", - "## Part 1: A modification to the PDE: continuous elastic support\n", - "\n", - "<p align=\"center\">\n", - "<img src=\"https://raw.githubusercontent.com/fmeer/public-files/main/barDefinition-2.png\" width=\"400\"/>\n", - "</p>\n", - "\n", - "For this exercise we still consider a 1D rod. However, now the rod is elastically supported. An example of this would be a foundation pile in soil. \n", - "\n", - "The problem of an elastically supported rod can be described with the following differential equation:\n", - "\n", - "$$ -EA \\frac{\\partial^2 u}{\\partial x^2} + ku = f $$\n", - "\n", - "with:\n", - "\n", - "$$\n", - "u = 0, \\quad \\text{at} \\quad x = 0 \\\\\n", - "EA\\frac{\\partial u}{{\\partial x}} = F, \\quad \\text{at} \\quad x = L\n", - "$$\n", - "\n", - "This differential equation is the inhomogeneous Helmholtz equation, which also has applications in dynamics and electromagnetics. The additional term with respect to the case without elastic support is the second term on the left hand side: $ku$. \n", - "\n", - "The finite element discretized version of this PDE can be obtained following the same steps as shown for the unsupported rod in the book. Note that there are no derivatives in the $ku$ which means that integration by parts does not need to be applied on this term. Using Neumann boundary condition (i.e. an applied load) at $x=L$ and a constant distributed load $f(x)=q$, the following expression is found for the discretized form:\n", - "\n", - "$$\\left[\\int \\mathbf{B}^T EA \\mathbf{B} + \\mathbf{N}^T k \\mathbf{N} \\,dx\\right]\\mathbf{u} = \\int \\mathbf{N}^T q \\,d x + \\mathbf{N}^T F \\Bigg|_{x=L} $$" - ] - }, - { - "cell_type": "markdown", - "id": "nonprofit-solution", - "metadata": { - "tags": [] - }, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Task 1: Derive the discrete form</b> \n", - "\n", - "Derive the discrete form of the PDE given above. You can follow the same steps as in the book for the term with $EA$ and the right hand side, but now carrying along the additional term $ku$ from the PDE. Show that this term leads to the $\\int\\mathbf{N}^Tk\\mathbf{N}\\,dx$ term in the $\\mathbf{K}$-matrix. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "f4805906", - "metadata": {}, - "source": [ - "***Your derivation here***" - ] - }, - { - "cell_type": "markdown", - "id": "6240afb2-28a3-49c4-b3d2-fb53ea110b99", - "metadata": {}, - "source": [ - "## Part 2: Modification to the FE implementation\n", - "\n", - "The only change with respect to the procedure as implemented in the book is the formulation of the $\\mathbf{K}$-matrix, which now consists of two terms:\n", - "\n", - "$$ \\mathbf{K} = \\int \\mathbf{B}^TEA\\mathbf{B} + \\mathbf{N}^Tk\\mathbf{N}\\,dx $$\n", - "\n", - "To calculate the integral exactly we must use two integration points.\n", - "\n", - "$$ \\mathbf{K_e} = \\sum_{i=1}^{n_\\mathrm{ip}} \\left(\\mathbf{B}^T(x_i)EA\\mathbf{B}(x_i) + \\mathbf{N}^T(x_i) k\\mathbf{N}(x_i) \\right) w_i$$" - ] - }, - { - "cell_type": "markdown", - "id": "f247cc75-caa2-47b7-8fe8-80f8521f7d8c", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Task 2: Code implementation</b> \n", - "\n", - "The only change needed with respect to the implementation of the book is in the calculation of the element stiffness matrix. Copy the code from the book and add the term related to the distributed support in the right position. \n", - " \n", - "Use the following parameters: $L=3\\text{ m}$, $EA=1000\\text{ N}$, $F=10\\text{ N}$, $q=0 \\text{ N/m}$ (all values are the same as in the book, except for $q$). Additionally, use $k=1000\\text{ N/m}^2$.\n", - "\n", - "Remarks:\n", - "\n", - "- The function <code>evaluate_N</code> is already present in the code in the book\n", - "- The <code>get_element_matrix</code> function already included a loop over two integration points\n", - "- You need to define $k$ somewhere. To allow for varying $k$ as required below, it is convenient to make $k$ a second argument of the <code>simulate</code> function and pass it on to lower level functions from there (cf. how $EA$ is passed on)\n", - "\n", - "Check the influence of the distributed support on the solution:\n", - "\n", - "- First use $q=0$ N/m and $k=1000$ N/$mm^2$\n", - "- Then set $k$ to zero and compare the results\n", - "- Does the influence of the supported spring on the solution make sense?\n", - "</p>\n", - "\n", - "</div>\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "retired-cartoon", - "metadata": {}, - "outputs": [], - "source": [ - "# YOUR_CODE_HERE" - ] - }, - { - "cell_type": "markdown", - "id": "20bcac74-1918-4c5e-bd17-148829c7ef8f", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "\n", - "<p>\n", - "\n", - "<b>Task 3: Investigate the influence of discretization on the quality of the solution</b>\n", - "\n", - "- How many elements do you need to get a good solution?\n", - "- How about when the stiffness of the distributed support is increased to $k=10^6$ N/$m^2$ ?\n", - "</p>\n", - "\n", - "Simulate and plot different cases for each of the above questions.\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e35e64ac-5e72-4575-bbb1-371fa524a747", - "metadata": {}, - "outputs": [], - "source": [ - "# YOUR_CODE_HERE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "936a7ebd-262b-457c-9c3f-8ab3196b7c26", - "metadata": {}, - "outputs": [], - "source": [ - "# YOUR_CODE_HERE" - ] - }, - { - "cell_type": "markdown", - "id": "7ac81786", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" />\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" />\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2024 <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">MUDE</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">CC BY 4.0 License</a>." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - }, - "latex_envs": { - "LaTeX_envs_menu_present": true, - "autoclose": false, - "autocomplete": true, - "bibliofile": "biblio.bib", - "cite_by": "apalike", - "current_citInitial": 1, - "eqLabelWithNumbers": true, - "eqNumInitial": 1, - "hotkeys": { - "equation": "Ctrl-E", - "itemize": "Ctrl-I" - }, - "labels_anchors": false, - "latex_user_defs": false, - "report_style_numbering": false, - "user_envs_cfg": false - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/synced_files/students/Week_2_2/WS_2_2_more_support.md b/synced_files/students/Week_2_2/WS_2_2_more_support.md deleted file mode 100644 index 4ed88e2ecd880ae5c1567057f99e3cfd9c148938..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_2_2/WS_2_2_more_support.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -# WS 2.2: More support - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 2.2. For: 20 November, 2024* - - -In the book, the finite element derivation and implementation of rod extension (the 1D Poisson equation) is presented. In this workshop, you are asked to do the same for a slightly different problem. - -## Part 1: A modification to the PDE: continuous elastic support - -<p align="center"> -<img src="https://raw.githubusercontent.com/fmeer/public-files/main/barDefinition-2.png" width="400"/> -</p> - -For this exercise we still consider a 1D rod. However, now the rod is elastically supported. An example of this would be a foundation pile in soil. - -The problem of an elastically supported rod can be described with the following differential equation: - -$$ -EA \frac{\partial^2 u}{\partial x^2} + ku = f $$ - -with: - -$$ -u = 0, \quad \text{at} \quad x = 0 \\ -EA\frac{\partial u}{{\partial x}} = F, \quad \text{at} \quad x = L -$$ - -This differential equation is the inhomogeneous Helmholtz equation, which also has applications in dynamics and electromagnetics. The additional term with respect to the case without elastic support is the second term on the left hand side: $ku$. - -The finite element discretized version of this PDE can be obtained following the same steps as shown for the unsupported rod in the book. Note that there are no derivatives in the $ku$ which means that integration by parts does not need to be applied on this term. Using Neumann boundary condition (i.e. an applied load) at $x=L$ and a constant distributed load $f(x)=q$, the following expression is found for the discretized form: - -$$\left[\int \mathbf{B}^T EA \mathbf{B} + \mathbf{N}^T k \mathbf{N} \,dx\right]\mathbf{u} = \int \mathbf{N}^T q \,d x + \mathbf{N}^T F \Bigg|_{x=L} $$ - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Task 1: Derive the discrete form</b> - -Derive the discrete form of the PDE given above. You can follow the same steps as in the book for the term with $EA$ and the right hand side, but now carrying along the additional term $ku$ from the PDE. Show that this term leads to the $\int\mathbf{N}^Tk\mathbf{N}\,dx$ term in the $\mathbf{K}$-matrix. -</p> -</div> - - -***Your derivation here*** - - -## Part 2: Modification to the FE implementation - -The only change with respect to the procedure as implemented in the book is the formulation of the $\mathbf{K}$-matrix, which now consists of two terms: - -$$ \mathbf{K} = \int \mathbf{B}^TEA\mathbf{B} + \mathbf{N}^Tk\mathbf{N}\,dx $$ - -To calculate the integral exactly we must use two integration points. - -$$ \mathbf{K_e} = \sum_{i=1}^{n_\mathrm{ip}} \left(\mathbf{B}^T(x_i)EA\mathbf{B}(x_i) + \mathbf{N}^T(x_i) k\mathbf{N}(x_i) \right) w_i$$ - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Task 2: Code implementation</b> - -The only change needed with respect to the implementation of the book is in the calculation of the element stiffness matrix. Copy the code from the book and add the term related to the distributed support in the right position. - -Use the following parameters: $L=3\text{ m}$, $EA=1000\text{ N}$, $F=10\text{ N}$, $q=0 \text{ N/m}$ (all values are the same as in the book, except for $q$). Additionally, use $k=1000\text{ N/m}^2$. - -Remarks: - -- The function <code>evaluate_N</code> is already present in the code in the book -- The <code>get_element_matrix</code> function already included a loop over two integration points -- You need to define $k$ somewhere. To allow for varying $k$ as required below, it is convenient to make $k$ a second argument of the <code>simulate</code> function and pass it on to lower level functions from there (cf. how $EA$ is passed on) - -Check the influence of the distributed support on the solution: - -- First use $q=0$ N/m and $k=1000$ N/$mm^2$ -- Then set $k$ to zero and compare the results -- Does the influence of the supported spring on the solution make sense? -</p> - -</div> - - - -```python -# YOUR_CODE_HERE -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> - -<p> - -<b>Task 3: Investigate the influence of discretization on the quality of the solution</b> - -- How many elements do you need to get a good solution? -- How about when the stiffness of the distributed support is increased to $k=10^6$ N/$m^2$ ? -</p> - -Simulate and plot different cases for each of the above questions. -</div> - -```python -# YOUR_CODE_HERE -``` - -```python -# YOUR_CODE_HERE -``` - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Week_2_2/WS_2_2_more_support.py b/synced_files/students/Week_2_2/WS_2_2_more_support.py deleted file mode 100644 index d387d078294b9d2d2ad521065fcb12a4255f8f02..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_2_2/WS_2_2_more_support.py +++ /dev/null @@ -1,152 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: Python 3 (ipykernel) -# language: python -# name: python3 -# --- - -# %% [markdown] -# # WS 2.2: More support -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 2.2. For: 20 November, 2024* - -# %% [markdown] -# In the book, the finite element derivation and implementation of rod extension (the 1D Poisson equation) is presented. In this workshop, you are asked to do the same for a slightly different problem. -# -# ## Part 1: A modification to the PDE: continuous elastic support -# -# <p align="center"> -# <img src="https://raw.githubusercontent.com/fmeer/public-files/main/barDefinition-2.png" width="400"/> -# </p> -# -# For this exercise we still consider a 1D rod. However, now the rod is elastically supported. An example of this would be a foundation pile in soil. -# -# The problem of an elastically supported rod can be described with the following differential equation: -# -# $$ -EA \frac{\partial^2 u}{\partial x^2} + ku = f $$ -# -# with: -# -# $$ -# u = 0, \quad \text{at} \quad x = 0 \\ -# EA\frac{\partial u}{{\partial x}} = F, \quad \text{at} \quad x = L -# $$ -# -# This differential equation is the inhomogeneous Helmholtz equation, which also has applications in dynamics and electromagnetics. The additional term with respect to the case without elastic support is the second term on the left hand side: $ku$. -# -# The finite element discretized version of this PDE can be obtained following the same steps as shown for the unsupported rod in the book. Note that there are no derivatives in the $ku$ which means that integration by parts does not need to be applied on this term. Using Neumann boundary condition (i.e. an applied load) at $x=L$ and a constant distributed load $f(x)=q$, the following expression is found for the discretized form: -# -# $$\left[\int \mathbf{B}^T EA \mathbf{B} + \mathbf{N}^T k \mathbf{N} \,dx\right]\mathbf{u} = \int \mathbf{N}^T q \,d x + \mathbf{N}^T F \Bigg|_{x=L} $$ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Task 1: Derive the discrete form</b> -# -# Derive the discrete form of the PDE given above. You can follow the same steps as in the book for the term with $EA$ and the right hand side, but now carrying along the additional term $ku$ from the PDE. Show that this term leads to the $\int\mathbf{N}^Tk\mathbf{N}\,dx$ term in the $\mathbf{K}$-matrix. -# </p> -# </div> - -# %% [markdown] -# ***Your derivation here*** - -# %% [markdown] -# ## Part 2: Modification to the FE implementation -# -# The only change with respect to the procedure as implemented in the book is the formulation of the $\mathbf{K}$-matrix, which now consists of two terms: -# -# $$ \mathbf{K} = \int \mathbf{B}^TEA\mathbf{B} + \mathbf{N}^Tk\mathbf{N}\,dx $$ -# -# To calculate the integral exactly we must use two integration points. -# -# $$ \mathbf{K_e} = \sum_{i=1}^{n_\mathrm{ip}} \left(\mathbf{B}^T(x_i)EA\mathbf{B}(x_i) + \mathbf{N}^T(x_i) k\mathbf{N}(x_i) \right) w_i$$ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Task 2: Code implementation</b> -# -# The only change needed with respect to the implementation of the book is in the calculation of the element stiffness matrix. Copy the code from the book and add the term related to the distributed support in the right position. -# -# Use the following parameters: $L=3\text{ m}$, $EA=1000\text{ N}$, $F=10\text{ N}$, $q=0 \text{ N/m}$ (all values are the same as in the book, except for $q$). Additionally, use $k=1000\text{ N/m}^2$. -# -# Remarks: -# -# - The function <code>evaluate_N</code> is already present in the code in the book -# - The <code>get_element_matrix</code> function already included a loop over two integration points -# - You need to define $k$ somewhere. To allow for varying $k$ as required below, it is convenient to make $k$ a second argument of the <code>simulate</code> function and pass it on to lower level functions from there (cf. how $EA$ is passed on) -# -# Check the influence of the distributed support on the solution: -# -# - First use $q=0$ N/m and $k=1000$ N/$mm^2$ -# - Then set $k$ to zero and compare the results -# - Does the influence of the supported spring on the solution make sense? -# </p> -# -# </div> -# -# - -# %% -# YOUR_CODE_HERE - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# -# <p> -# -# <b>Task 3: Investigate the influence of discretization on the quality of the solution</b> -# -# - How many elements do you need to get a good solution? -# - How about when the stiffness of the distributed support is increased to $k=10^6$ N/$m^2$ ? -# </p> -# -# Simulate and plot different cases for each of the above questions. -# </div> - -# %% -# YOUR_CODE_HERE - -# %% -# YOUR_CODE_HERE - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Week_2_3/WS_2_3_DFT_you_try_meow.ipynb b/synced_files/students/Week_2_3/WS_2_3_DFT_you_try_meow.ipynb deleted file mode 100644 index c55cf9d6cf882b19faa8a61e2d778c7741b704f2..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_2_3/WS_2_3_DFT_you_try_meow.ipynb +++ /dev/null @@ -1,469 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "81475e62", - "metadata": {}, - "source": [ - "# WS 2.3: Discrete Fourier Transform (DFT): You Try Meow (Miauw)\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px\" />\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px\" />\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 2.3, Signal Processing. For: November 27, 2024*" - ] - }, - { - "cell_type": "markdown", - "id": "eff9791a", - "metadata": {}, - "source": [ - "The goal of this workshop to work with the _Discrete Fourier Transform_ (DFT), implemented in Python as the _Fast Fourier Transform_ (FFT) through `np.fft.fft`, and to understand and interpret its output.\n", - "\n", - "The notebook consists of two parts:\n", - "- The first part (Task 0) is a demonstration of the use of the DFT (_you read and execute the code cells_),\n", - "- The second part is a simple exercise with the DFT (_you write the code_).\n", - "\n", - "To start off, let's do a quick quiz question: _what is the primary purpose of the DFT?_\n", - "\n", - "_Run the code cell below to find the answer._" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "36a05bbd-69a1-4805-a4ad-e84de89de560", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "%%html\n", - "<iframe src=\"https://tudelft.h5p.com/content/1292126914399042257/embed\" aria-label=\"Meow\" width=\"1088\" height=\"637\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\" allow=\"autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *\"></iframe><script src=\"https://tudelft.h5p.com/js/h5p-resizer.js\" charset=\"UTF-8\"></script>" - ] - }, - { - "cell_type": "markdown", - "id": "03f3b3c6-d3f6-4121-9f39-c30c8bf70ea5", - "metadata": {}, - "source": [ - "That's right! We convert our signal into the frequency domain.\n", - "\n", - "And if you would like an additional explanation of the key frequencies, you can find it [here](https://medium.com/@kovalenko.alx/fun-with-fourier-591662576a77)." - ] - }, - { - "cell_type": "markdown", - "id": "bfca25a5-75ce-4837-9387-01f95be10bd0", - "metadata": { - "id": "0491cc69" - }, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\"> <p>Note the use of <code>zip</code>, <code>stem</code>, <code>annotate</code> and the modulo operator\n", - "<code>%</code>. Refer to PA 2.3 if you do not understand these tools. Furthermore, note that the term _modulus_ is also used here (and in the textbook), which is another term for _absolute value._</p></div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "da13fbf3", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "from matplotlib import pyplot as plt" - ] - }, - { - "cell_type": "markdown", - "id": "13234855", - "metadata": {}, - "source": [ - "## Task 0: Demonstration of DFT using pulse function\n", - "\n", - "In the first part of this notebook, we use $x(t)=\\Pi(\\frac{t}{4})$, and its Fourier transform $X(f)=4 \\,\\textrm{sinc}(4f)$, as an example (see the first worked example in Chapter 3 on the Fourier transform). The pulse lasts for 4 seconds in the time domain; for convenience, below it is not centered at $t$ = 0, but shifted (delayed) to the right.\n", - "\n", - "The signal $x(t)$ clearly is non-periodic and is an energy signal; apart from a short time span of 'activity' it is zero elsewhere.\n", - "\n", - "We create a pulse function $x(t)$ in discrete time $x_n$ by numpy. The total signal duration is $T$ = 20 seconds (observation or record length). The sampling interval is $\\Delta t$ = 1 second. There are $N$ = 20 samples, and each sample represents 1 second, hence $N \\Delta t = T$.\n", - "\n", - "Note that the time array starts at $t$ = 0 s, and hence, the last sample is at $t$ = 19 s (and not at $t$ = 20 s, as then we would have 21 samples).\n", - "\n", - "### Task 0.1: Visualize the Signal" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b33e1be2", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "t = np.arange(0,20,1)\n", - "xt = np.concatenate((np.zeros(8), np.ones(4), np.zeros(8)))\n", - "\n", - "plt.plot(t, xt,'o')\n", - "plt.stem(t[8:12], xt[8:12]) \n", - "plt.xticks(ticks=np.arange(0,21,5), labels=np.arange(0,21,5))\n", - "plt.xlabel('time [s]')\n", - "plt.ylabel('xn');" - ] - }, - { - "cell_type": "markdown", - "id": "a338eede", - "metadata": {}, - "source": [ - "### Task 0.2: Evaluate (and visualize) the DFT\n", - "\n", - "We use `numpy.fft.fft` to compute the one-dimensional Discrete Fourier Transform (DFT) of $x_n$, which takes a signal as argument and returns an array of coefficients (refer to the [documentation](https://numpy.org/doc/stable/reference/generated/numpy.fft.fft.html) as needed).\n", - "\n", - "The DFT converts $N$ samples of the time domain signal $x_n$, into $N$ samples of the frequency domain. In this case, it produces $X_k$ with $k = 0, 1, 2, \\ldots, N-1$, with $N$ = 20, which are complex numbers. " - ] - }, - { - "cell_type": "markdown", - "id": "26d0f558-caa7-41f2-9477-60d74940fc10", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Task 0.2:</b> \n", - "Read the code cell below before executing it and identify the following:\n", - "<ol>\n", - " <li>Where is the DFT computed, and what is the output?</li>\n", - " <li>Why is the modulus (absolute value) used on the DFT output?</li>\n", - " <li>What are the values are used for the x and y axes of the plot?</li>\n", - " <li>How is frequency information found and added to the plot (mathematically)?</li>\n", - "</ol>\n", - "Once you understand the figure, continue reading to understand <em>what do these 20 complex numbers mean, and how should we interpret them?</em>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3acb465b", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "abs_fft = np.abs(np.fft.fft(xt))\n", - "index_fft = np.arange(0,20,1)\n", - "plt.plot(index_fft, abs_fft, 'o')\n", - "\n", - "freq = np.arange(0, 1, 0.05)\n", - "for x,y in zip(index_fft, abs_fft):\n", - " if x%5 == 0 or x==19:\n", - " label = f\"f={freq[x]:.2f} Hz\"\n", - " plt.annotate(label, \n", - " (x,y),\n", - " textcoords=\"offset points\", \n", - " xytext=(0,10),\n", - " fontsize=10,\n", - " ha='center') \n", - "plt.ylim(0,5)\n", - "plt.xlim(-2,21)\n", - "plt.xlabel('fft-index')\n", - "plt.ylabel('$|X_k|$')\n", - "plt.stem(index_fft, abs_fft);" - ] - }, - { - "cell_type": "markdown", - "id": "09c72cdd", - "metadata": {}, - "source": [ - "The frequency resolution $\\Delta f$ equals one-over-the-measurement-duration, hence $\\Delta f = 1/T$. With that knowledge, we can reconstruct the frequencies expressed in Hertz.\n", - "\n", - "The spectrum of the sampled signal is periodic in the sampling frequency $f_s$ which equals 1 Hz ($\\Delta t$ = 1 s). Therefore, it is computed just for one period $[0,f_s)$. The last value, with index 19, represents the component with frequency $f$ = 0.95 Hz. A spectrum is commonly presented and interpreted as double-sided, so in the above graph we can interpret the spectral components with indices 10 to 19 corresponding to negative frequencies. \n", - "\n", - "### Task 0.3: Identify negative frequencies" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "df1f483b", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "abs_fft = np.abs(np.fft.fft(xt))\n", - "plt.stem(index_fft, abs_fft)\n", - "plt.plot(index_fft, abs_fft, 'o')\n", - "\n", - "freq = np.concatenate((np.arange(0, 0.5, 0.05), np.arange(-0.5, 0, 0.05)))\n", - "for x,y in zip(index_fft, abs_fft):\n", - " if x%5 == 0 or x==19:\n", - " label = f\"f={freq[x]:.2f} Hz\"\n", - " plt.annotate(label, \n", - " (x,y),\n", - " textcoords=\"offset points\", \n", - " xytext=(0,10),\n", - " fontsize=10,\n", - " ha='center') \n", - "plt.ylim(0,5)\n", - "plt.xlim(-2,21)\n", - "plt.xlabel('fft-index')\n", - "plt.ylabel('$|X_k|$');" - ] - }, - { - "cell_type": "markdown", - "id": "2d87a9a6", - "metadata": { - "tags": [] - }, - "source": [ - "Now we can interpret the DFT of the $x(t)=\\Pi(\\frac{t}{4})$. The sampling interval is $\\Delta t$ = 1 second, and the obsesrvation length is T=20 seconds, and we have N=20 samples. \n", - "- We can recognize a bit of a sinc function.\n", - "- The DFT is computed from 0 Hz, for positive frequencies up to $\\frac{fs}{2} = 0.5$ Hz, after which the negative frequencies follow from -0.5 to -0.05 Hz.\n", - "- $X(f)=4 \\textrm{sinc}(4f)$ has its first null at $f=0.25$Hz.\n", - "\n", - "### Task 0.4: Create symmetric plot\n", - "\n", - "For convenient visualization, we may want to explicitly shift the negative frequencies to the left-hand side to create a symmetric plot. We can use `numpy.fft.fftshift` to do that. In other words, the zero-frequency component appears in the center of the spectrum. Now, it nicely shows a symmetric sprectrum. It well resembles the sinc-function (taking into account that we plot the modulus/absolute value). The output of the DFT still consists of $N$ = 20 elements. To enable this, we set up a new frequency array (in Hz) on the interval $[-fs/2,fs/2)$." - ] - }, - { - "cell_type": "markdown", - "id": "e1eef6b6-1e90-43db-b059-6521b2a840d3", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Task 0.4:</b> \n", - "Read the code cell below before executing it and identify how the plot is modified based on the (new) specification of frequency. Note that it is more than just the <code>freq</code> variable!\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a8aac894", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "abs_fft_shift = np.abs(np.fft.fftshift(np.fft.fft(xt)))\n", - "freq = np.arange(-0.5, 0.5, 0.05)\n", - "plt.stem(freq, abs_fft_shift)\n", - "plt.plot(freq, abs_fft_shift, 'o')\n", - "plt.ylabel('|Xk|')\n", - "plt.xlabel('frequency [Hz]');" - ] - }, - { - "cell_type": "markdown", - "id": "569ca2d3", - "metadata": {}, - "source": [ - "### Task 0.5: Showing spectrum only for positive frequencies\n", - "\n", - "In practice, because of the symmetry, one typically plots only the right-hand side of the (double-sided) spectrum, hence only the part for positive frequencies $f \\geq 0$. This is simply a matter of preference, and a way to save some space." - ] - }, - { - "cell_type": "markdown", - "id": "a26e361d-c5fa-47a2-b32c-416cc3d10659", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Task 0.5:</b> \n", - "Can you identify what has changed (in the code and visually), compared to the previous plot?\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b9608638", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "N=len(xt)\n", - "abs_fft = np.abs(np.fft.fft(xt))\n", - "freq = np.arange(0.0, 1.0, 0.05)\n", - "plt.plot(freq[:int(N/2)], abs_fft[:int(N/2)], 'o')\n", - "plt.stem(freq[:int(N/2)], abs_fft[:int(N/2)])\n", - "plt.ylabel('$|X_k|$')\n", - "plt.xlabel('frequency [Hz]');" - ] - }, - { - "cell_type": "markdown", - "id": "83c4ca67-9234-4741-a56f-294a12bcd98a", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Task 0.6:</b> \n", - "Confirm that you understand how we have arrived at the plot above, which illustrates the magnitude (amplitude) spectrum for frequencies $f \\in [0,f_s/2)$, rather than $[0,f_s)$.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "9f5558b4", - "metadata": {}, - "source": [ - "## Task 1: Application of DFT using simple cosine" - ] - }, - { - "cell_type": "markdown", - "id": "46dd5c0c", - "metadata": {}, - "source": [ - "It is always a good idea, in spectral analysis, to run a test with a very simple, basic signal. In this way you can test and verify your coding and interpretation of the results. \n", - "\n", - "Our basic signal is just a plain cosine. We take the amplitude equal to one, and zero initial phase, so the signal reads $x(t) = \\cos(2 \\pi f_c t)$, with $f_c$ = 3 Hz in this exercise. With such a simple signal, we know in advance how the spectrum should look like. Namely just a spike at $f$ = 3 Hz, and also one at $f$ = -3 Hz, as we're, for mathematical convenience, working with double sided spectra. The spectrum should be zero at all other frequencies.\n", - "\n", - "As a side note: the cosine is strictly a periodic function, not a-periodic (as above); still, the Fourier transform of the cosine is defined as two Dirac delta pulses or peaks (at 3 Hz and -3 Hz). You may want to check out the second worked example in Chapter 3 on the Fourier transform: Fourier transform in the limit." - ] - }, - { - "cell_type": "markdown", - "id": "87de3cc5", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\">\n", - "<p>\n", - "<b>Task 1:</b> \n", - " \n", - "Create a sampled (discrete time) cosine signal by sampling at $f_s$ = 10 Hz, for a duration of $T$ = 2 seconds (make sure you use exactly $N$ = 20 samples). Plot the sampled signal, compute its DFT and plot its magnitude spectrum $|X_k|$ with proper labeling of the axes (just like we did in the first part of this notebook). Include a plot of the spectrum of the sampled cosine signal using only the positive frequencies (up to $f_s/2$, as in the last plot of the previous task).\n", - "\n", - "<em>Note: you are expected to produce three separate plots.</em>\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "28ad034e", - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE_PLOT_1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "af87d120", - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE_PLOT_2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6fd9014c", - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE_PLOT_3" - ] - }, - { - "cell_type": "markdown", - "id": "0b3584c9", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" />\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" />\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2024 <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">MUDE</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">CC BY 4.0 License</a>." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.4" - }, - "latex_envs": { - "LaTeX_envs_menu_present": true, - "autoclose": false, - "autocomplete": true, - "bibliofile": "biblio.bib", - "cite_by": "apalike", - "current_citInitial": 1, - "eqLabelWithNumbers": true, - "eqNumInitial": 1, - "hotkeys": { - "equation": "Ctrl-E", - "itemize": "Ctrl-I" - }, - "labels_anchors": false, - "latex_user_defs": false, - "report_style_numbering": false, - "user_envs_cfg": false - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/synced_files/students/Week_2_3/WS_2_3_DFT_you_try_meow.md b/synced_files/students/Week_2_3/WS_2_3_DFT_you_try_meow.md deleted file mode 100644 index c7b59b2f7a5c242177e87620f14a38ec65d9c888..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_2_3/WS_2_3_DFT_you_try_meow.md +++ /dev/null @@ -1,260 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -# WS 2.3: Discrete Fourier Transform (DFT): You Try Meow (Miauw) - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 2.3, Signal Processing. For: November 27, 2024* - - -The goal of this workshop to work with the _Discrete Fourier Transform_ (DFT), implemented in Python as the _Fast Fourier Transform_ (FFT) through `np.fft.fft`, and to understand and interpret its output. - -The notebook consists of two parts: -- The first part (Task 0) is a demonstration of the use of the DFT (_you read and execute the code cells_), -- The second part is a simple exercise with the DFT (_you write the code_). - -To start off, let's do a quick quiz question: _what is the primary purpose of the DFT?_ - -_Run the code cell below to find the answer._ - -```html -<iframe src="https://tudelft.h5p.com/content/1292126914399042257/embed" aria-label="Meow" width="1088" height="637" frameborder="0" allowfullscreen="allowfullscreen" allow="autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *"></iframe><script src="https://tudelft.h5p.com/js/h5p-resizer.js" charset="UTF-8"></script> -``` - -That's right! We convert our signal into the frequency domain. - -And if you would like an additional explanation of the key frequencies, you can find it [here](https://medium.com/@kovalenko.alx/fun-with-fourier-591662576a77). - -<!-- #region id="0491cc69" --> -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>Note the use of <code>zip</code>, <code>stem</code>, <code>annotate</code> and the modulo operator -<code>%</code>. Refer to PA 2.3 if you do not understand these tools. Furthermore, note that the term _modulus_ is also used here (and in the textbook), which is another term for _absolute value._</p></div> -<!-- #endregion --> - -```python -import numpy as np -from matplotlib import pyplot as plt -``` - -## Task 0: Demonstration of DFT using pulse function - -In the first part of this notebook, we use $x(t)=\Pi(\frac{t}{4})$, and its Fourier transform $X(f)=4 \,\textrm{sinc}(4f)$, as an example (see the first worked example in Chapter 3 on the Fourier transform). The pulse lasts for 4 seconds in the time domain; for convenience, below it is not centered at $t$ = 0, but shifted (delayed) to the right. - -The signal $x(t)$ clearly is non-periodic and is an energy signal; apart from a short time span of 'activity' it is zero elsewhere. - -We create a pulse function $x(t)$ in discrete time $x_n$ by numpy. The total signal duration is $T$ = 20 seconds (observation or record length). The sampling interval is $\Delta t$ = 1 second. There are $N$ = 20 samples, and each sample represents 1 second, hence $N \Delta t = T$. - -Note that the time array starts at $t$ = 0 s, and hence, the last sample is at $t$ = 19 s (and not at $t$ = 20 s, as then we would have 21 samples). - -### Task 0.1: Visualize the Signal - -```python -t = np.arange(0,20,1) -xt = np.concatenate((np.zeros(8), np.ones(4), np.zeros(8))) - -plt.plot(t, xt,'o') -plt.stem(t[8:12], xt[8:12]) -plt.xticks(ticks=np.arange(0,21,5), labels=np.arange(0,21,5)) -plt.xlabel('time [s]') -plt.ylabel('xn'); -``` - -### Task 0.2: Evaluate (and visualize) the DFT - -We use `numpy.fft.fft` to compute the one-dimensional Discrete Fourier Transform (DFT) of $x_n$, which takes a signal as argument and returns an array of coefficients (refer to the [documentation](https://numpy.org/doc/stable/reference/generated/numpy.fft.fft.html) as needed). - -The DFT converts $N$ samples of the time domain signal $x_n$, into $N$ samples of the frequency domain. In this case, it produces $X_k$ with $k = 0, 1, 2, \ldots, N-1$, with $N$ = 20, which are complex numbers. - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Task 0.2:</b> -Read the code cell below before executing it and identify the following: -<ol> - <li>Where is the DFT computed, and what is the output?</li> - <li>Why is the modulus (absolute value) used on the DFT output?</li> - <li>What are the values are used for the x and y axes of the plot?</li> - <li>How is frequency information found and added to the plot (mathematically)?</li> -</ol> -Once you understand the figure, continue reading to understand <em>what do these 20 complex numbers mean, and how should we interpret them?</em> -</p> -</div> - -```python -abs_fft = np.abs(np.fft.fft(xt)) -index_fft = np.arange(0,20,1) -plt.plot(index_fft, abs_fft, 'o') - -freq = np.arange(0, 1, 0.05) -for x,y in zip(index_fft, abs_fft): - if x%5 == 0 or x==19: - label = f"f={freq[x]:.2f} Hz" - plt.annotate(label, - (x,y), - textcoords="offset points", - xytext=(0,10), - fontsize=10, - ha='center') -plt.ylim(0,5) -plt.xlim(-2,21) -plt.xlabel('fft-index') -plt.ylabel('$|X_k|$') -plt.stem(index_fft, abs_fft); -``` - -The frequency resolution $\Delta f$ equals one-over-the-measurement-duration, hence $\Delta f = 1/T$. With that knowledge, we can reconstruct the frequencies expressed in Hertz. - -The spectrum of the sampled signal is periodic in the sampling frequency $f_s$ which equals 1 Hz ($\Delta t$ = 1 s). Therefore, it is computed just for one period $[0,f_s)$. The last value, with index 19, represents the component with frequency $f$ = 0.95 Hz. A spectrum is commonly presented and interpreted as double-sided, so in the above graph we can interpret the spectral components with indices 10 to 19 corresponding to negative frequencies. - -### Task 0.3: Identify negative frequencies - -```python -abs_fft = np.abs(np.fft.fft(xt)) -plt.stem(index_fft, abs_fft) -plt.plot(index_fft, abs_fft, 'o') - -freq = np.concatenate((np.arange(0, 0.5, 0.05), np.arange(-0.5, 0, 0.05))) -for x,y in zip(index_fft, abs_fft): - if x%5 == 0 or x==19: - label = f"f={freq[x]:.2f} Hz" - plt.annotate(label, - (x,y), - textcoords="offset points", - xytext=(0,10), - fontsize=10, - ha='center') -plt.ylim(0,5) -plt.xlim(-2,21) -plt.xlabel('fft-index') -plt.ylabel('$|X_k|$'); -``` - -Now we can interpret the DFT of the $x(t)=\Pi(\frac{t}{4})$. The sampling interval is $\Delta t$ = 1 second, and the obsesrvation length is T=20 seconds, and we have N=20 samples. -- We can recognize a bit of a sinc function. -- The DFT is computed from 0 Hz, for positive frequencies up to $\frac{fs}{2} = 0.5$ Hz, after which the negative frequencies follow from -0.5 to -0.05 Hz. -- $X(f)=4 \textrm{sinc}(4f)$ has its first null at $f=0.25$Hz. - -### Task 0.4: Create symmetric plot - -For convenient visualization, we may want to explicitly shift the negative frequencies to the left-hand side to create a symmetric plot. We can use `numpy.fft.fftshift` to do that. In other words, the zero-frequency component appears in the center of the spectrum. Now, it nicely shows a symmetric sprectrum. It well resembles the sinc-function (taking into account that we plot the modulus/absolute value). The output of the DFT still consists of $N$ = 20 elements. To enable this, we set up a new frequency array (in Hz) on the interval $[-fs/2,fs/2)$. - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Task 0.4:</b> -Read the code cell below before executing it and identify how the plot is modified based on the (new) specification of frequency. Note that it is more than just the <code>freq</code> variable! -</p> -</div> - -```python -abs_fft_shift = np.abs(np.fft.fftshift(np.fft.fft(xt))) -freq = np.arange(-0.5, 0.5, 0.05) -plt.stem(freq, abs_fft_shift) -plt.plot(freq, abs_fft_shift, 'o') -plt.ylabel('|Xk|') -plt.xlabel('frequency [Hz]'); -``` - -### Task 0.5: Showing spectrum only for positive frequencies - -In practice, because of the symmetry, one typically plots only the right-hand side of the (double-sided) spectrum, hence only the part for positive frequencies $f \geq 0$. This is simply a matter of preference, and a way to save some space. - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Task 0.5:</b> -Can you identify what has changed (in the code and visually), compared to the previous plot? -</p> -</div> - -```python -N=len(xt) -abs_fft = np.abs(np.fft.fft(xt)) -freq = np.arange(0.0, 1.0, 0.05) -plt.plot(freq[:int(N/2)], abs_fft[:int(N/2)], 'o') -plt.stem(freq[:int(N/2)], abs_fft[:int(N/2)]) -plt.ylabel('$|X_k|$') -plt.xlabel('frequency [Hz]'); -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Task 0.6:</b> -Confirm that you understand how we have arrived at the plot above, which illustrates the magnitude (amplitude) spectrum for frequencies $f \in [0,f_s/2)$, rather than $[0,f_s)$. -</p> -</div> - - -## Task 1: Application of DFT using simple cosine - - -It is always a good idea, in spectral analysis, to run a test with a very simple, basic signal. In this way you can test and verify your coding and interpretation of the results. - -Our basic signal is just a plain cosine. We take the amplitude equal to one, and zero initial phase, so the signal reads $x(t) = \cos(2 \pi f_c t)$, with $f_c$ = 3 Hz in this exercise. With such a simple signal, we know in advance how the spectrum should look like. Namely just a spike at $f$ = 3 Hz, and also one at $f$ = -3 Hz, as we're, for mathematical convenience, working with double sided spectra. The spectrum should be zero at all other frequencies. - -As a side note: the cosine is strictly a periodic function, not a-periodic (as above); still, the Fourier transform of the cosine is defined as two Dirac delta pulses or peaks (at 3 Hz and -3 Hz). You may want to check out the second worked example in Chapter 3 on the Fourier transform: Fourier transform in the limit. - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -<p> -<b>Task 1:</b> - -Create a sampled (discrete time) cosine signal by sampling at $f_s$ = 10 Hz, for a duration of $T$ = 2 seconds (make sure you use exactly $N$ = 20 samples). Plot the sampled signal, compute its DFT and plot its magnitude spectrum $|X_k|$ with proper labeling of the axes (just like we did in the first part of this notebook). Include a plot of the spectrum of the sampled cosine signal using only the positive frequencies (up to $f_s/2$, as in the last plot of the previous task). - -<em>Note: you are expected to produce three separate plots.</em> -</p> -</div> - -```python -YOUR_CODE_HERE_PLOT_1 -``` - -```python -YOUR_CODE_HERE_PLOT_2 -``` - -```python -YOUR_CODE_HERE_PLOT_3 -``` - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/students/Week_2_3/WS_2_3_DFT_you_try_meow.py b/synced_files/students/Week_2_3/WS_2_3_DFT_you_try_meow.py deleted file mode 100644 index 8fd405e956f3483470e1e045ea3bf148aadfb791..0000000000000000000000000000000000000000 --- a/synced_files/students/Week_2_3/WS_2_3_DFT_you_try_meow.py +++ /dev/null @@ -1,258 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: Python 3 (ipykernel) -# language: python -# name: python3 -# --- - -# %% [markdown] -# # WS 2.3: Discrete Fourier Transform (DFT): You Try Meow (Miauw) -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 2.3, Signal Processing. For: November 27, 2024* - -# %% [markdown] -# The goal of this workshop to work with the _Discrete Fourier Transform_ (DFT), implemented in Python as the _Fast Fourier Transform_ (FFT) through `np.fft.fft`, and to understand and interpret its output. -# -# The notebook consists of two parts: -# - The first part (Task 0) is a demonstration of the use of the DFT (_you read and execute the code cells_), -# - The second part is a simple exercise with the DFT (_you write the code_). -# -# To start off, let's do a quick quiz question: _what is the primary purpose of the DFT?_ -# -# _Run the code cell below to find the answer._ - -# %% language="html" -# <iframe src="https://tudelft.h5p.com/content/1292126914399042257/embed" aria-label="Meow" width="1088" height="637" frameborder="0" allowfullscreen="allowfullscreen" allow="autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *"></iframe><script src="https://tudelft.h5p.com/js/h5p-resizer.js" charset="UTF-8"></script> - -# %% [markdown] -# That's right! We convert our signal into the frequency domain. -# -# And if you would like an additional explanation of the key frequencies, you can find it [here](https://medium.com/@kovalenko.alx/fun-with-fourier-591662576a77). - -# %% [markdown] id="0491cc69" -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> <p>Note the use of <code>zip</code>, <code>stem</code>, <code>annotate</code> and the modulo operator -# <code>%</code>. Refer to PA 2.3 if you do not understand these tools. Furthermore, note that the term _modulus_ is also used here (and in the textbook), which is another term for _absolute value._</p></div> - -# %% -import numpy as np -from matplotlib import pyplot as plt - -# %% [markdown] -# ## Task 0: Demonstration of DFT using pulse function -# -# In the first part of this notebook, we use $x(t)=\Pi(\frac{t}{4})$, and its Fourier transform $X(f)=4 \,\textrm{sinc}(4f)$, as an example (see the first worked example in Chapter 3 on the Fourier transform). The pulse lasts for 4 seconds in the time domain; for convenience, below it is not centered at $t$ = 0, but shifted (delayed) to the right. -# -# The signal $x(t)$ clearly is non-periodic and is an energy signal; apart from a short time span of 'activity' it is zero elsewhere. -# -# We create a pulse function $x(t)$ in discrete time $x_n$ by numpy. The total signal duration is $T$ = 20 seconds (observation or record length). The sampling interval is $\Delta t$ = 1 second. There are $N$ = 20 samples, and each sample represents 1 second, hence $N \Delta t = T$. -# -# Note that the time array starts at $t$ = 0 s, and hence, the last sample is at $t$ = 19 s (and not at $t$ = 20 s, as then we would have 21 samples). -# -# ### Task 0.1: Visualize the Signal - -# %% -t = np.arange(0,20,1) -xt = np.concatenate((np.zeros(8), np.ones(4), np.zeros(8))) - -plt.plot(t, xt,'o') -plt.stem(t[8:12], xt[8:12]) -plt.xticks(ticks=np.arange(0,21,5), labels=np.arange(0,21,5)) -plt.xlabel('time [s]') -plt.ylabel('xn'); - -# %% [markdown] -# ### Task 0.2: Evaluate (and visualize) the DFT -# -# We use `numpy.fft.fft` to compute the one-dimensional Discrete Fourier Transform (DFT) of $x_n$, which takes a signal as argument and returns an array of coefficients (refer to the [documentation](https://numpy.org/doc/stable/reference/generated/numpy.fft.fft.html) as needed). -# -# The DFT converts $N$ samples of the time domain signal $x_n$, into $N$ samples of the frequency domain. In this case, it produces $X_k$ with $k = 0, 1, 2, \ldots, N-1$, with $N$ = 20, which are complex numbers. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Task 0.2:</b> -# Read the code cell below before executing it and identify the following: -# <ol> -# <li>Where is the DFT computed, and what is the output?</li> -# <li>Why is the modulus (absolute value) used on the DFT output?</li> -# <li>What are the values are used for the x and y axes of the plot?</li> -# <li>How is frequency information found and added to the plot (mathematically)?</li> -# </ol> -# Once you understand the figure, continue reading to understand <em>what do these 20 complex numbers mean, and how should we interpret them?</em> -# </p> -# </div> - -# %% -abs_fft = np.abs(np.fft.fft(xt)) -index_fft = np.arange(0,20,1) -plt.plot(index_fft, abs_fft, 'o') - -freq = np.arange(0, 1, 0.05) -for x,y in zip(index_fft, abs_fft): - if x%5 == 0 or x==19: - label = f"f={freq[x]:.2f} Hz" - plt.annotate(label, - (x,y), - textcoords="offset points", - xytext=(0,10), - fontsize=10, - ha='center') -plt.ylim(0,5) -plt.xlim(-2,21) -plt.xlabel('fft-index') -plt.ylabel('$|X_k|$') -plt.stem(index_fft, abs_fft); - -# %% [markdown] -# The frequency resolution $\Delta f$ equals one-over-the-measurement-duration, hence $\Delta f = 1/T$. With that knowledge, we can reconstruct the frequencies expressed in Hertz. -# -# The spectrum of the sampled signal is periodic in the sampling frequency $f_s$ which equals 1 Hz ($\Delta t$ = 1 s). Therefore, it is computed just for one period $[0,f_s)$. The last value, with index 19, represents the component with frequency $f$ = 0.95 Hz. A spectrum is commonly presented and interpreted as double-sided, so in the above graph we can interpret the spectral components with indices 10 to 19 corresponding to negative frequencies. -# -# ### Task 0.3: Identify negative frequencies - -# %% -abs_fft = np.abs(np.fft.fft(xt)) -plt.stem(index_fft, abs_fft) -plt.plot(index_fft, abs_fft, 'o') - -freq = np.concatenate((np.arange(0, 0.5, 0.05), np.arange(-0.5, 0, 0.05))) -for x,y in zip(index_fft, abs_fft): - if x%5 == 0 or x==19: - label = f"f={freq[x]:.2f} Hz" - plt.annotate(label, - (x,y), - textcoords="offset points", - xytext=(0,10), - fontsize=10, - ha='center') -plt.ylim(0,5) -plt.xlim(-2,21) -plt.xlabel('fft-index') -plt.ylabel('$|X_k|$'); - -# %% [markdown] -# Now we can interpret the DFT of the $x(t)=\Pi(\frac{t}{4})$. The sampling interval is $\Delta t$ = 1 second, and the obsesrvation length is T=20 seconds, and we have N=20 samples. -# - We can recognize a bit of a sinc function. -# - The DFT is computed from 0 Hz, for positive frequencies up to $\frac{fs}{2} = 0.5$ Hz, after which the negative frequencies follow from -0.5 to -0.05 Hz. -# - $X(f)=4 \textrm{sinc}(4f)$ has its first null at $f=0.25$Hz. -# -# ### Task 0.4: Create symmetric plot -# -# For convenient visualization, we may want to explicitly shift the negative frequencies to the left-hand side to create a symmetric plot. We can use `numpy.fft.fftshift` to do that. In other words, the zero-frequency component appears in the center of the spectrum. Now, it nicely shows a symmetric sprectrum. It well resembles the sinc-function (taking into account that we plot the modulus/absolute value). The output of the DFT still consists of $N$ = 20 elements. To enable this, we set up a new frequency array (in Hz) on the interval $[-fs/2,fs/2)$. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Task 0.4:</b> -# Read the code cell below before executing it and identify how the plot is modified based on the (new) specification of frequency. Note that it is more than just the <code>freq</code> variable! -# </p> -# </div> - -# %% -abs_fft_shift = np.abs(np.fft.fftshift(np.fft.fft(xt))) -freq = np.arange(-0.5, 0.5, 0.05) -plt.stem(freq, abs_fft_shift) -plt.plot(freq, abs_fft_shift, 'o') -plt.ylabel('|Xk|') -plt.xlabel('frequency [Hz]'); - -# %% [markdown] -# ### Task 0.5: Showing spectrum only for positive frequencies -# -# In practice, because of the symmetry, one typically plots only the right-hand side of the (double-sided) spectrum, hence only the part for positive frequencies $f \geq 0$. This is simply a matter of preference, and a way to save some space. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Task 0.5:</b> -# Can you identify what has changed (in the code and visually), compared to the previous plot? -# </p> -# </div> - -# %% -N=len(xt) -abs_fft = np.abs(np.fft.fft(xt)) -freq = np.arange(0.0, 1.0, 0.05) -plt.plot(freq[:int(N/2)], abs_fft[:int(N/2)], 'o') -plt.stem(freq[:int(N/2)], abs_fft[:int(N/2)]) -plt.ylabel('$|X_k|$') -plt.xlabel('frequency [Hz]'); - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Task 0.6:</b> -# Confirm that you understand how we have arrived at the plot above, which illustrates the magnitude (amplitude) spectrum for frequencies $f \in [0,f_s/2)$, rather than $[0,f_s)$. -# </p> -# </div> - -# %% [markdown] -# ## Task 1: Application of DFT using simple cosine - -# %% [markdown] -# It is always a good idea, in spectral analysis, to run a test with a very simple, basic signal. In this way you can test and verify your coding and interpretation of the results. -# -# Our basic signal is just a plain cosine. We take the amplitude equal to one, and zero initial phase, so the signal reads $x(t) = \cos(2 \pi f_c t)$, with $f_c$ = 3 Hz in this exercise. With such a simple signal, we know in advance how the spectrum should look like. Namely just a spike at $f$ = 3 Hz, and also one at $f$ = -3 Hz, as we're, for mathematical convenience, working with double sided spectra. The spectrum should be zero at all other frequencies. -# -# As a side note: the cosine is strictly a periodic function, not a-periodic (as above); still, the Fourier transform of the cosine is defined as two Dirac delta pulses or peaks (at 3 Hz and -3 Hz). You may want to check out the second worked example in Chapter 3 on the Fourier transform: Fourier transform in the limit. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"> -# <p> -# <b>Task 1:</b> -# -# Create a sampled (discrete time) cosine signal by sampling at $f_s$ = 10 Hz, for a duration of $T$ = 2 seconds (make sure you use exactly $N$ = 20 samples). Plot the sampled signal, compute its DFT and plot its magnitude spectrum $|X_k|$ with proper labeling of the axes (just like we did in the first part of this notebook). Include a plot of the spectrum of the sampled cosine signal using only the positive frequencies (up to $f_s/2$, as in the last plot of the previous task). -# -# <em>Note: you are expected to produce three separate plots.</em> -# </p> -# </div> - -# %% -YOUR_CODE_HERE_PLOT_1 - -# %% -YOUR_CODE_HERE_PLOT_2 - -# %% -YOUR_CODE_HERE_PLOT_3 - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/teachers/Week_1_5/WS_1_5_dont_integr_hate.ipynb b/synced_files/teachers/Week_1_5/WS_1_5_dont_integr_hate.ipynb deleted file mode 100644 index d1a5c97f31d85310a5d15b314f59a45b64775307..0000000000000000000000000000000000000000 --- a/synced_files/teachers/Week_1_5/WS_1_5_dont_integr_hate.ipynb +++ /dev/null @@ -1,778 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "6cf87eaa-cae9-436c-86f5-b64181df5850", - "metadata": {}, - "source": [ - "# Workshop 5: Exploring Numerical Summing Schemes\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 90px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px\" />\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px\" />\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.5, Wednesday, Oct 4, 2024.*" - ] - }, - { - "cell_type": "markdown", - "id": "82cfc0b4", - "metadata": {}, - "source": [ - "## Problem definition: Numerical Integration\n", - "\n", - "Integration can be used to solve differential equations and to calculate relevant quantities in diverse engineering and scientific problems. When analyzing experiments or numerical models results, a desired physical quantity may be expressed as an integral of measured/model quantities. Sometimes the analytical integration is known, then this is the most accurate and fastest solution, certainly better than computing it numerically. However, it is common that the analytic solution is unknown, then numerical integration is the way to go. \n", - "\n", - "\n", - "You will use a function with a known integral to evaluate how precise numerical integration can be. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "caebff09-a533-40aa-9115-985c78e45693", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "from scipy.interpolate import make_interp_spline\n", - "\n", - "\n", - "plt.rcParams['figure.figsize'] = (15, 5) # Set the width and height of plots in inches\n", - "plt.rcParams.update({'font.size': 13}) # Change this value to your desired font size" - ] - }, - { - "cell_type": "markdown", - "id": "a6773319", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "352f1493", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1:</b> \n", - "\n", - "Calculate and evaluate the following integral by hand: \n", - "\n", - "$$I=\\int_a^{b} f\\left(x\\right)\\mathrm{d}x = \\int_0^{3\\pi} \\left(20 \\cos(x)+3x^2\\right)\\mathrm{d}x.$$\n", - "\n", - "The result will be later used to explore how diverse numerical integration techniques work and their accuracy. \n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "fea89e84", - "metadata": {}, - "source": [ - "**Function definition**\n", - "\n", - "Let's define the python function \n", - "\n", - "\n", - "$$f\\left(x\\right) = \\left(20 \\cos x+3x^2\\right)$$ " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "98e6e3b6", - "metadata": {}, - "outputs": [], - "source": [ - "# Define the function to be later integrated\n", - "def f(x):\n", - " return 20*np.cos(x)+3*x**2" - ] - }, - { - "cell_type": "markdown", - "id": "cd6b9447", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2:</b> \n", - "\n", - "Below, call the function f written above to evaluate it at x=0. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "de1759f8", - "metadata": {}, - "outputs": [], - "source": [ - "f_at_x_equal_0 = YOUR_CODE_HERE\n", - "\n", - "print(\"f evaluated at x=0 is:\" , f_at_x_equal_0)" - ] - }, - { - "cell_type": "markdown", - "id": "f3bbdf8c", - "metadata": {}, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>NOTE:</b> Calling f(x) is equivalent to evaluating it! \n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "1c3d671e", - "metadata": {}, - "source": [ - "**Define an x vector to evaluate the function**\n", - "\n", - "The function `f(x)` exists in \"all space\". However, the integration is bounded to the limits `a to b`, $I=\\int_a^{b} f\\left(x\\right)\\mathrm{d}x = \\int_0^{3\\pi} \\left(20 \\cos(x)+3x^2\\right)\\mathrm{d}x$. \n", - "\n", - "<br><br>\n", - "Use those limits to create an x array using `linspace(a,b,n)`, where `a` is the limit to the left, `b` is the limit to the right and `n` is the number of points. Below you see the case with 5 points.\n", - "\n", - "<img src=\"linspace.jpg\" style=\"height:100px\" />\n" - ] - }, - { - "cell_type": "markdown", - "id": "add4309b", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 3:</b> \n", - "\n", - "Define the intervals `a,b` and the number of points needed to have a subinterval length $\\Delta x=\\pi$. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4b85d2a4", - "metadata": {}, - "outputs": [], - "source": [ - "a = YOUR_CODE_HERE\n", - "b = YOUR_CODE_HERE\n", - "number_of_points = YOUR_CODE_HERE\n", - "\n", - "x_values = np.linspace(YOUR_CODE_HERE)\n", - "dx = x_values[1]-x_values[0]\n", - "\n", - "print(\"x = \",x_values)\n", - "\n", - "\n", - "\n", - "# test dx value\n", - "assert abs(dx - np.pi)<1e-5, \"Oops! dx is not equal to pi. Please check your values for a, b and number of points.\"" - ] - }, - { - "cell_type": "markdown", - "id": "ec5511fb", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 4:</b> \n", - "\n", - "How do the number of points and number of subintervals relate? Write a brief answer below.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "098d751a", - "metadata": {}, - "source": [ - "**answer**: " - ] - }, - { - "cell_type": "markdown", - "id": "1049c443", - "metadata": {}, - "source": [ - "**Visualize a \"continuous\" function and list comprehension**\n", - "\n", - "For visualization purposes in the rest of the notebook, `f(x)` is here evaluated with high resolution. A \"list comprehension\" method is used for this purpose. **Understanding \"list comprehensions\" is essential to solve the rest of the notebook**.\n" - ] - }, - { - "cell_type": "markdown", - "id": "d17856b3", - "metadata": {}, - "source": [ - "**Visualize a \"continuous\" function and list comprehension**\n", - "\n", - "For visualization purposes in the rest of the notebook, `f(x)` is here evaluated with high resolution. A \"list comprehension\" method is used for this purpose, which is a special feature of the Python programming language (you learned about it in the PA!).\n" - ] - }, - { - "cell_type": "markdown", - "id": "12e2ea3d", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 5:</b> \n", - "\n", - "Three equivalent solutions to define <code>f_high_resolution</code> are shown below. The first one loops <code>x_high_resolution</code> and assigns its values to x, which is then used to evaluate f. \n", - "\n", - "The second one creates an index list based on the number of points contained in <code>x_high_resolution</code>, then loops it to evaluate f at each element of <code>x_high_resolution</code>.\n", - "\n", - "The third simply uses a function to evaluate the values.\n", - "\n", - "Which method do you find easier to read/write?\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "84f395cb", - "metadata": {}, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>NOTE:</b> although list comprehensions may look more cumbersome here, it is important tool to learn, as in more complex code it can help make the algorithm easier to read and write. In terms of computation time, list comprehensions are faster than \"regular\" for loops (both are native Python features), However, the third approach is actually the fastest in terms of numerical computation time, because Numpy ndarrays (not native Python) are optimized for efficient computation.\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "65878405", - "metadata": {}, - "outputs": [], - "source": [ - "# To plot a smooth graph of the function\n", - "x_high_resolution = np.linspace(a, b, 50)\n", - "\n", - "f_high_resolution = [ f(x) for x in x_high_resolution ] #first solution\n", - "\n", - "f_high_resolution = [ f(x_high_resolution[i]) for i in range(len(x_high_resolution))] #second solution\n", - "\n", - "\n", - "# Plotting\n", - "plt.plot(x_high_resolution, f_high_resolution, '+', markersize='12', color='black')\n", - "plt.plot(x_high_resolution, f_high_resolution, 'b')\n", - "plt.legend(['Points evaluated','Continuous function representation'])\n", - "plt.title('Function for approximation')\n", - "plt.xlabel('x')\n", - "plt.ylabel('$f(x)$');" - ] - }, - { - "cell_type": "markdown", - "id": "a9ef5459-2ffb-4bde-830c-646264c3648a", - "metadata": {}, - "source": [ - "<b>The Left Riemann Sum</b>\n", - "\n", - "This method approximates an integral by summing the area of rectangles defined with left points of the function:\n", - "\n", - "$$I_{_{left}} \\approx \\sum_{i=0}^{n-1} f(x_i)\\Delta x$$\n", - "\n", - "From now on, you will use ten points to define the function.\n", - "<br><br>\n", - "\n", - "Let's look at the implementation of the Left Riemann sum following the same methods described in task 5. The differences are that (i) the index of the vector x ignores the last point, (ii) the multiplication by $\\Delta x$ and (iii) the sum of the vector. Thus the result is not an array but a single number. \n", - "<br><br>\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "80eb6362", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 6:</b> \n", - "\n", - "Scrutinize the correct implementations below. Why is it necessary to ignore the last point in x_values? What would happen if you include it? \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d3a75fe0-017b-4e8a-b729-68412a492854", - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "x_values = np.linspace(a, b, 10) \n", - "dx = x_values[1]-x_values[0]\n", - "\n", - "# Left Riemann summation: 1st option\n", - "I_left_riemann = sum( [f(x)*dx for x in x_values[:-1]] ) #method 1\n", - "print(f\"Left Riemann Sum: {I_left_riemann: 0.3f}\")\n", - "\n", - "# Left Riemann summation: 2nd option\n", - "I_left_riemann = sum( [ f(x_values[i])*dx for i in range(len(x_values)-1) ] ) #method 2\n", - "print(f\"Left Riemann Sum: {I_left_riemann: 0.3f}\")" - ] - }, - { - "cell_type": "markdown", - "id": "409b0530", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 7:</b> \n", - "\n", - "Scrutinize the correct implementation below to visualize the bar plot (plt.bar) and location of the points (plt.plot with '*', in the line code below plt.bar) that define the height of each rectangle. \n", - "<br>\n", - "<br>\n", - "Tip: The bar plot requires one less element than the total number of points defining the function. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0c09dc12", - "metadata": {}, - "outputs": [], - "source": [ - "# Visualization\n", - "# Plot the rectangles and left corners of the elements in the riemann sum\n", - "plt.bar(x_values[:-1],[f(x) for x in x_values[:-1]], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25)\n", - "plt.plot(x_values[:-1],[f(x) for x in x_values[:-1]], '*', markersize='16', color='red')\n", - "\n", - "#Plot \"continuous\" function\n", - "plt.plot(x_high_resolution, f_high_resolution, 'b')\n", - "plt.title('Left Riemann Sum')\n", - "plt.xlabel('x')\n", - "plt.ylabel('$f(x)$');" - ] - }, - { - "cell_type": "markdown", - "id": "8906e8ab-9aa5-45db-a683-cd40a6729575", - "metadata": {}, - "source": [ - "**The Right Riemann Method**\n", - "\n", - "Similar to the left Riemann sum, this method is also algebraically simple to implement, and can be better suited to some situations, depending on the type of function you are trying to approximate. In this case, the subintervals are defined using the right-hand endpoints from the function and is represented by \n", - "\n", - "$$I_{_{right}} \\approx \\sum_{i=1}^n f(x_i)\\Delta x$$\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "0bbf4b11", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 8:</b> \n", - "\n", - "Complete the code cell below for the right Riemman method.. \n", - "\n", - "Tip: Consult the Left Riemann implementation above as a guide.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3073db6e-430c-4f17-ad88-a4f2892a55f1", - "metadata": {}, - "outputs": [], - "source": [ - "I_right_riemann = sum( [YOUR_CODE_HERE for x in YOUR_CODE_HERE] ) \n", - "\n", - "print(f\"Right Riemann Sum: {I_right_riemann: 0.3f}\")" - ] - }, - { - "cell_type": "markdown", - "id": "0cf7e125", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 9:</b> \n", - "\n", - "Complete the code cell below to visualize the right Riemman method.\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c510d26b", - "metadata": {}, - "outputs": [], - "source": [ - "# Right Riemann sum visualization\n", - "plt.bar(x_values[YOUR_CODE_HERE],[f(x) for x in x_values[YOUR_CODE_HERE]],\n", - " width=YOUR_CODE_HERE, alpha=0.5, align='edge',\n", - " edgecolor='black', linewidth=0.25)\n", - "plt.plot(x_values[YOUR_CODE_HERE],[f(x) for x in x_values[YOUR_CODE_HERE]],\n", - " '*', markersize='16', color='red')\n", - "#Plot \"continuous\" function\n", - "plt.plot(x_high_resolution, f_high_resolution, 'b')\n", - "plt.title('Right Riemann Sum')\n", - "plt.xlabel('x')\n", - "plt.ylabel('$f(x)$');" - ] - }, - { - "cell_type": "markdown", - "id": "24d26cbb-ab8f-435f-8238-0c22c0fce833", - "metadata": {}, - "source": [ - "**Midpoint Method Approximation**\n", - "\n", - "For a function defined with constant steps (uniform $\\Delta x$), the midpoint method approximates the integral taking the midpoint of the rectangle and splitting the width of the rectangle at this point. \n", - "\n", - "$$I_{_{mid}} \\approx \\sum_{i=0}^{n-1} f\\left(\\frac{x_i+x_{i+1}}{2}\\right)\\Delta x $$\n" - ] - }, - { - "cell_type": "markdown", - "id": "13d1d689", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 10:</b> \n", - "\n", - "Complete the code cell below to implement the midpoint sum below.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7ed26ad5-d2cb-450e-873d-5b21a596cedb", - "metadata": {}, - "outputs": [], - "source": [ - "I_midpoint = sum([f(YOUR_CODE_HERE)*dx for i in range(YOUR_CODE_HERE)])\n", - "print(f\"Midpoint Sum: {I_midpoint: 0.3e}\")\n", - "\n", - "I_midpoint = sum([f(x_at_the_middle)*dx for x_at_the_middle in YOUR_CODE_HERE ])\n", - "print(f\"Midpoint Sum: {I_midpoint: 0.3e}\")" - ] - }, - { - "cell_type": "markdown", - "id": "e685d8c3", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 11:</b> \n", - "\n", - "Complete the code cell below to visualize the midpoint method.\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "370672eb", - "metadata": {}, - "outputs": [], - "source": [ - "# Midpoint sum visualization\n", - "plt.bar(x_values[YOUR_CODE_HERE],[f(x_at_the_middle) for x_at_the_middle in YOUR_CODE_HERE ], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25)\n", - "plt.plot(x_values[YOUR_CODE_HERE],[f(x_at_the_middle) for x_at_the_middle in YOUR_CODE_HERE],'*',markersize='16', color='red')\n", - "#Plot \"continuous\" function\n", - "plt.plot(x_high_resolution, f_high_resolution, 'b')\n", - "plt.title('Midpoint Sum')\n", - "plt.xlabel('x')\n", - "plt.ylabel('$f(x)$');" - ] - }, - { - "cell_type": "markdown", - "id": "fcf6f8bc-5554-4309-81ce-0433fa947e34", - "metadata": {}, - "source": [ - "**Trapezoidal Rule**\n", - "\n", - "This method requires two evaluations of the function $f$ for each 'rectangle', at its left and right corners. In fact, it does not represent a 'rectangle anymore' but a trapezoid. For a 1D case, it is a rectangle with a triangle on top. \n", - "\n", - "$$I_{_{trapezoid}} \\approx \\sum_{i=0}^{n-1}\\frac{f(x_i)+f(x_{i+1})}{2}\\Delta x $$" - ] - }, - { - "cell_type": "markdown", - "id": "74bb23af", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 12:</b> \n", - "\n", - "Complete the following code to implement the trapezoidal rule for the sum. \n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b6e68930-f1d8-4d7e-8162-8cd59f985be0", - "metadata": {}, - "outputs": [], - "source": [ - "I_trapezoidal = sum([YOUR_CODE_HERE for i in range(len(x_values)-1)]) \n", - "print(f\"Trapezoidal Sum: {I_trapezoidal: 0.5e}\")" - ] - }, - { - "cell_type": "markdown", - "id": "5a3a195c", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 13:</b> \n", - "\n", - "To visualize the trapezoidal method a plt.bar is not used rather plt_fill_between. Revise the code cell below.\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "36cddace", - "metadata": {}, - "outputs": [], - "source": [ - "# Trapezoidal sum\n", - "for i in range(len(x_values)-1):\n", - " plt.fill_between([x_values[i], x_values[i+1]], \n", - " [f(x_values[i]), f(x_values[i+1])], \n", - " alpha=0.5)\n", - "\n", - "#Plot \"continuous\" function\n", - "plt.plot(x_high_resolution, f_high_resolution, 'b')\n", - "plt.title('Trapezoidal Sum')\n", - "plt.xlabel('x')\n", - "plt.ylabel('$f(x)$');\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "14295e08-e9db-4735-927d-715989b62b81", - "metadata": {}, - "source": [ - "**Absolute errors in integral**" - ] - }, - { - "cell_type": "markdown", - "id": "d6b0720c", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 14:</b> \n", - "\n", - "Compute the absolute errors of each method. Are they similar to your expectatations? (i.e. corresponding to the orders of magnitude).\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "582e66ed-2016-4a84-a5f4-6d01d49671dc", - "metadata": {}, - "outputs": [], - "source": [ - "# Calculate absolute errors\n", - "left_riemann_error = YOUR_CODE_HERE\n", - "right_riemann_error = YOUR_CODE_HERE\n", - "midpoint_error = YOUR_CODE_HERE\n", - "trapezoidal_error = YOUR_CODE_HERE\n", - "\n", - "# Print the results\n", - "print(f\"Left Riemann Error: {left_riemann_error: 0.3e}\")\n", - "print(f\"Right Riemann Error: {right_riemann_error: 0.3e}\")\n", - "print(f\"Midpoint Error: {midpoint_error: 0.3e}\")\n", - "print(f\"Trapezoidal Error: {trapezoidal_error: 0.3e}\")\n" - ] - }, - { - "cell_type": "markdown", - "id": "ddc2f16f-7065-4829-aafc-91c95cc93aaf", - "metadata": {}, - "source": [ - "**Simpson's Rule**\n", - "\n", - "Simpson's rule is a method that uses a quadratic approximation over an interval that allows the top bound of the area 'rectangle' to be defined by a polynomial. In general, it can be a better approximation for curved, but mathematically smooth functions. It also has the requirement that subintervals must be an even number, so this is something to be aware of when using it in practise. As a sum, it is defined as \n", - "\n", - "$$\\int^{b}_{a}f(x)\\mathrm{d}x\\approx \\sum_{i=1}^{n/2}\\frac{1}{3}(f(x_{2i-2})+4f(x_{2i-1})+f(x_{2i}))\\Delta x$$\n", - "\n", - "where $n$ must be an *even integer*.\n", - "\n", - " " - ] - }, - { - "cell_type": "markdown", - "id": "e0ed72e0-ced6-467c-8e01-a1b602a3613d", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Challenge</b>\n", - "\n", - "Take what you have seen in the other numerical implementation codes and implement Simpson's Rule for the same integral! A redefinition of x_values is done with 9 points instead of 10 as an uneven number of points is required to apply Simpson's Rule. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ae169f8e-2d5a-4449-8c53-c8ca399af184", - "metadata": {}, - "outputs": [], - "source": [ - "# Define Simpson's Rule here\n", - "x_values = np.linspace(YOUR_CODE_HERE)\n", - "dx = YOUR_CODE_HERE \n", - " \n", - "simpson_integral = sum([ YOUR_CODE_HERE ]) \n", - "\n", - "# Calculate the absolute error\n", - "simpson_error = YOUR_CODE_HERE\n", - "\n", - "# Print the result and error\n", - "print(f\"Simpson's Rule Integral: {simpson_integral: 0.5e}\")\n", - "print(f\"Simpson's Rule Absolute Error: {simpson_error: 0.5e}\")\n" - ] - }, - { - "cell_type": "markdown", - "id": "8ffe7a1f", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 15:</b> \n", - " \n", - " \n", - "Refine the number of points using the integration by left riemann until reaching a similar accuracy as for the trapezoidal rule. How much finer was your grid?\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "793cb6e5", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "23b8f21d", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc-sa/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\"/>\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\"/>\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2023 <a rel=\"MUDE Team\" href=\"https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=65595\">MUDE Teaching Team</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc-sa/4.0/\">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.6" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/synced_files/teachers/Week_1_5/WS_1_5_dont_integr_hate.md b/synced_files/teachers/Week_1_5/WS_1_5_dont_integr_hate.md deleted file mode 100644 index d757042067637017720023d66930276f7e558180..0000000000000000000000000000000000000000 --- a/synced_files/teachers/Week_1_5/WS_1_5_dont_integr_hate.md +++ /dev/null @@ -1,497 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -# Workshop 5: Exploring Numerical Summing Schemes - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 90px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.5, Wednesday, Oct 4, 2024.* - -<!-- #region --> -## Problem definition: Numerical Integration - -Integration can be used to solve differential equations and to calculate relevant quantities in diverse engineering and scientific problems. When analyzing experiments or numerical models results, a desired physical quantity may be expressed as an integral of measured/model quantities. Sometimes the analytical integration is known, then this is the most accurate and fastest solution, certainly better than computing it numerically. However, it is common that the analytic solution is unknown, then numerical integration is the way to go. - - -You will use a function with a known integral to evaluate how precise numerical integration can be. -<!-- #endregion --> - -```python -import numpy as np -import matplotlib.pyplot as plt -from scipy.interpolate import make_interp_spline - - -plt.rcParams['figure.figsize'] = (15, 5) # Set the width and height of plots in inches -plt.rcParams.update({'font.size': 13}) # Change this value to your desired font size -``` - - - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 1:</b> - -Calculate and evaluate the following integral by hand: - -$$I=\int_a^{b} f\left(x\right)\mathrm{d}x = \int_0^{3\pi} \left(20 \cos(x)+3x^2\right)\mathrm{d}x.$$ - -The result will be later used to explore how diverse numerical integration techniques work and their accuracy. - -</p> -</div> - -<!-- #region --> -**Function definition** - -Let's define the python function - - -$$f\left(x\right) = \left(20 \cos x+3x^2\right)$$ -<!-- #endregion --> - -```python -# Define the function to be later integrated -def f(x): - return 20*np.cos(x)+3*x**2 -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 2:</b> - -Below, call the function f written above to evaluate it at x=0. -</p> -</div> - -```python -f_at_x_equal_0 = YOUR_CODE_HERE - -print("f evaluated at x=0 is:" , f_at_x_equal_0) -``` - -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>NOTE:</b> Calling f(x) is equivalent to evaluating it! - -</p> -</div> - - -**Define an x vector to evaluate the function** - -The function `f(x)` exists in "all space". However, the integration is bounded to the limits `a to b`, $I=\int_a^{b} f\left(x\right)\mathrm{d}x = \int_0^{3\pi} \left(20 \cos(x)+3x^2\right)\mathrm{d}x$. - -<br><br> -Use those limits to create an x array using `linspace(a,b,n)`, where `a` is the limit to the left, `b` is the limit to the right and `n` is the number of points. Below you see the case with 5 points. - -<img src="linspace.jpg" style="height:100px" /> - - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 3:</b> - -Define the intervals `a,b` and the number of points needed to have a subinterval length $\Delta x=\pi$. -</p> -</div> - -```python -a = YOUR_CODE_HERE -b = YOUR_CODE_HERE -number_of_points = YOUR_CODE_HERE - -x_values = np.linspace(YOUR_CODE_HERE) -dx = x_values[1]-x_values[0] - -print("x = ",x_values) - - - -# test dx value -assert abs(dx - np.pi)<1e-5, "Oops! dx is not equal to pi. Please check your values for a, b and number of points." -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 4:</b> - -How do the number of points and number of subintervals relate? Write a brief answer below. -</p> -</div> - - -**answer**: - - -**Visualize a "continuous" function and list comprehension** - -For visualization purposes in the rest of the notebook, `f(x)` is here evaluated with high resolution. A "list comprehension" method is used for this purpose. **Understanding "list comprehensions" is essential to solve the rest of the notebook**. - - - -**Visualize a "continuous" function and list comprehension** - -For visualization purposes in the rest of the notebook, `f(x)` is here evaluated with high resolution. A "list comprehension" method is used for this purpose, which is a special feature of the Python programming language (you learned about it in the PA!). - - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 5:</b> - -Three equivalent solutions to define <code>f_high_resolution</code> are shown below. The first one loops <code>x_high_resolution</code> and assigns its values to x, which is then used to evaluate f. - -The second one creates an index list based on the number of points contained in <code>x_high_resolution</code>, then loops it to evaluate f at each element of <code>x_high_resolution</code>. - -The third simply uses a function to evaluate the values. - -Which method do you find easier to read/write? -</p> -</div> - - -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>NOTE:</b> although list comprehensions may look more cumbersome here, it is important tool to learn, as in more complex code it can help make the algorithm easier to read and write. In terms of computation time, list comprehensions are faster than "regular" for loops (both are native Python features), However, the third approach is actually the fastest in terms of numerical computation time, because Numpy ndarrays (not native Python) are optimized for efficient computation. - -</p> -</div> - -```python -# To plot a smooth graph of the function -x_high_resolution = np.linspace(a, b, 50) - -f_high_resolution = [ f(x) for x in x_high_resolution ] #first solution - -f_high_resolution = [ f(x_high_resolution[i]) for i in range(len(x_high_resolution))] #second solution - - -# Plotting -plt.plot(x_high_resolution, f_high_resolution, '+', markersize='12', color='black') -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.legend(['Points evaluated','Continuous function representation']) -plt.title('Function for approximation') -plt.xlabel('x') -plt.ylabel('$f(x)$'); -``` - -<b>The Left Riemann Sum</b> - -This method approximates an integral by summing the area of rectangles defined with left points of the function: - -$$I_{_{left}} \approx \sum_{i=0}^{n-1} f(x_i)\Delta x$$ - -From now on, you will use ten points to define the function. -<br><br> - -Let's look at the implementation of the Left Riemann sum following the same methods described in task 5. The differences are that (i) the index of the vector x ignores the last point, (ii) the multiplication by $\Delta x$ and (iii) the sum of the vector. Thus the result is not an array but a single number. -<br><br> - - - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 6:</b> - -Scrutinize the correct implementations below. Why is it necessary to ignore the last point in x_values? What would happen if you include it? -</p> -</div> - -```python - -x_values = np.linspace(a, b, 10) -dx = x_values[1]-x_values[0] - -# Left Riemann summation: 1st option -I_left_riemann = sum( [f(x)*dx for x in x_values[:-1]] ) #method 1 -print(f"Left Riemann Sum: {I_left_riemann: 0.3f}") - -# Left Riemann summation: 2nd option -I_left_riemann = sum( [ f(x_values[i])*dx for i in range(len(x_values)-1) ] ) #method 2 -print(f"Left Riemann Sum: {I_left_riemann: 0.3f}") -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 7:</b> - -Scrutinize the correct implementation below to visualize the bar plot (plt.bar) and location of the points (plt.plot with '*', in the line code below plt.bar) that define the height of each rectangle. -<br> -<br> -Tip: The bar plot requires one less element than the total number of points defining the function. -</p> -</div> - -```python -# Visualization -# Plot the rectangles and left corners of the elements in the riemann sum -plt.bar(x_values[:-1],[f(x) for x in x_values[:-1]], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25) -plt.plot(x_values[:-1],[f(x) for x in x_values[:-1]], '*', markersize='16', color='red') - -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Left Riemann Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); -``` - -**The Right Riemann Method** - -Similar to the left Riemann sum, this method is also algebraically simple to implement, and can be better suited to some situations, depending on the type of function you are trying to approximate. In this case, the subintervals are defined using the right-hand endpoints from the function and is represented by - -$$I_{_{right}} \approx \sum_{i=1}^n f(x_i)\Delta x$$ - - - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 8:</b> - -Complete the code cell below for the right Riemman method.. - -Tip: Consult the Left Riemann implementation above as a guide. -</p> -</div> - -```python -I_right_riemann = sum( [YOUR_CODE_HERE for x in YOUR_CODE_HERE] ) - -print(f"Right Riemann Sum: {I_right_riemann: 0.3f}") -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 9:</b> - -Complete the code cell below to visualize the right Riemman method. - -</p> -</div> - -```python -# Right Riemann sum visualization -plt.bar(x_values[YOUR_CODE_HERE],[f(x) for x in x_values[YOUR_CODE_HERE]], - width=YOUR_CODE_HERE, alpha=0.5, align='edge', - edgecolor='black', linewidth=0.25) -plt.plot(x_values[YOUR_CODE_HERE],[f(x) for x in x_values[YOUR_CODE_HERE]], - '*', markersize='16', color='red') -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Right Riemann Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); -``` - -**Midpoint Method Approximation** - -For a function defined with constant steps (uniform $\Delta x$), the midpoint method approximates the integral taking the midpoint of the rectangle and splitting the width of the rectangle at this point. - -$$I_{_{mid}} \approx \sum_{i=0}^{n-1} f\left(\frac{x_i+x_{i+1}}{2}\right)\Delta x $$ - - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 10:</b> - -Complete the code cell below to implement the midpoint sum below. -</p> -</div> - -```python -I_midpoint = sum([f(YOUR_CODE_HERE)*dx for i in range(YOUR_CODE_HERE)]) -print(f"Midpoint Sum: {I_midpoint: 0.3e}") - -I_midpoint = sum([f(x_at_the_middle)*dx for x_at_the_middle in YOUR_CODE_HERE ]) -print(f"Midpoint Sum: {I_midpoint: 0.3e}") -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 11:</b> - -Complete the code cell below to visualize the midpoint method. - -</p> -</div> - -```python -# Midpoint sum visualization -plt.bar(x_values[YOUR_CODE_HERE],[f(x_at_the_middle) for x_at_the_middle in YOUR_CODE_HERE ], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25) -plt.plot(x_values[YOUR_CODE_HERE],[f(x_at_the_middle) for x_at_the_middle in YOUR_CODE_HERE],'*',markersize='16', color='red') -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Midpoint Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); -``` - -**Trapezoidal Rule** - -This method requires two evaluations of the function $f$ for each 'rectangle', at its left and right corners. In fact, it does not represent a 'rectangle anymore' but a trapezoid. For a 1D case, it is a rectangle with a triangle on top. - -$$I_{_{trapezoid}} \approx \sum_{i=0}^{n-1}\frac{f(x_i)+f(x_{i+1})}{2}\Delta x $$ - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 12:</b> - -Complete the following code to implement the trapezoidal rule for the sum. - -</p> -</div> - -```python -I_trapezoidal = sum([YOUR_CODE_HERE for i in range(len(x_values)-1)]) -print(f"Trapezoidal Sum: {I_trapezoidal: 0.5e}") -``` - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 13:</b> - -To visualize the trapezoidal method a plt.bar is not used rather plt_fill_between. Revise the code cell below. - -</p> -</div> - -```python -# Trapezoidal sum -for i in range(len(x_values)-1): - plt.fill_between([x_values[i], x_values[i+1]], - [f(x_values[i]), f(x_values[i+1])], - alpha=0.5) - -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Trapezoidal Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - - -``` - -**Absolute errors in integral** - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 14:</b> - -Compute the absolute errors of each method. Are they similar to your expectatations? (i.e. corresponding to the orders of magnitude). - -</p> -</div> - -```python -# Calculate absolute errors -left_riemann_error = YOUR_CODE_HERE -right_riemann_error = YOUR_CODE_HERE -midpoint_error = YOUR_CODE_HERE -trapezoidal_error = YOUR_CODE_HERE - -# Print the results -print(f"Left Riemann Error: {left_riemann_error: 0.3e}") -print(f"Right Riemann Error: {right_riemann_error: 0.3e}") -print(f"Midpoint Error: {midpoint_error: 0.3e}") -print(f"Trapezoidal Error: {trapezoidal_error: 0.3e}") - -``` - -**Simpson's Rule** - -Simpson's rule is a method that uses a quadratic approximation over an interval that allows the top bound of the area 'rectangle' to be defined by a polynomial. In general, it can be a better approximation for curved, but mathematically smooth functions. It also has the requirement that subintervals must be an even number, so this is something to be aware of when using it in practise. As a sum, it is defined as - -$$\int^{b}_{a}f(x)\mathrm{d}x\approx \sum_{i=1}^{n/2}\frac{1}{3}(f(x_{2i-2})+4f(x_{2i-1})+f(x_{2i}))\Delta x$$ - -where $n$ must be an *even integer*. - - - - -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Challenge</b> - -Take what you have seen in the other numerical implementation codes and implement Simpson's Rule for the same integral! A redefinition of x_values is done with 9 points instead of 10 as an uneven number of points is required to apply Simpson's Rule. -</p> -</div> - -```python -# Define Simpson's Rule here -x_values = np.linspace(YOUR_CODE_HERE) -dx = YOUR_CODE_HERE - -simpson_integral = sum([ YOUR_CODE_HERE ]) - -# Calculate the absolute error -simpson_error = YOUR_CODE_HERE - -# Print the result and error -print(f"Simpson's Rule Integral: {simpson_integral: 0.5e}") -print(f"Simpson's Rule Absolute Error: {simpson_error: 0.5e}") - -``` - -<!-- #region --> -<div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Task 15:</b> - - -Refine the number of points using the integration by left riemann until reaching a similar accuracy as for the trapezoidal rule. How much finer was your grid? - -</p> -</div> -<!-- #endregion --> - - - - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png"/> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png"/> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2023 <a rel="MUDE Team" href="https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=65595">MUDE Teaching Team</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>. diff --git a/synced_files/teachers/Week_1_5/WS_1_5_dont_integr_hate.py b/synced_files/teachers/Week_1_5/WS_1_5_dont_integr_hate.py deleted file mode 100644 index 3a9cae8d11fcdec1af30e467e273330d2ca567b6..0000000000000000000000000000000000000000 --- a/synced_files/teachers/Week_1_5/WS_1_5_dont_integr_hate.py +++ /dev/null @@ -1,497 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: Python 3 (ipykernel) -# language: python -# name: python3 -# --- - -# %% [markdown] -# # Workshop 5: Exploring Numerical Summing Schemes -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 90px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.5, Wednesday, Oct 4, 2024.* - -# %% [markdown] -# ## Problem definition: Numerical Integration -# -# Integration can be used to solve differential equations and to calculate relevant quantities in diverse engineering and scientific problems. When analyzing experiments or numerical models results, a desired physical quantity may be expressed as an integral of measured/model quantities. Sometimes the analytical integration is known, then this is the most accurate and fastest solution, certainly better than computing it numerically. However, it is common that the analytic solution is unknown, then numerical integration is the way to go. -# -# -# You will use a function with a known integral to evaluate how precise numerical integration can be. - -# %% -import numpy as np -import matplotlib.pyplot as plt -from scipy.interpolate import make_interp_spline - - -plt.rcParams['figure.figsize'] = (15, 5) # Set the width and height of plots in inches -plt.rcParams.update({'font.size': 13}) # Change this value to your desired font size - - -# %% [markdown] -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 1:</b> -# -# Calculate and evaluate the following integral by hand: -# -# $$I=\int_a^{b} f\left(x\right)\mathrm{d}x = \int_0^{3\pi} \left(20 \cos(x)+3x^2\right)\mathrm{d}x.$$ -# -# The result will be later used to explore how diverse numerical integration techniques work and their accuracy. -# -# </p> -# </div> - -# %% [markdown] -# **Function definition** -# -# Let's define the python function -# -# -# $$f\left(x\right) = \left(20 \cos x+3x^2\right)$$ - -# %% -# Define the function to be later integrated -def f(x): - return 20*np.cos(x)+3*x**2 - - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 2:</b> -# -# Below, call the function f written above to evaluate it at x=0. -# </p> -# </div> - -# %% -f_at_x_equal_0 = YOUR_CODE_HERE - -print("f evaluated at x=0 is:" , f_at_x_equal_0) - -# %% [markdown] -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>NOTE:</b> Calling f(x) is equivalent to evaluating it! -# -# </p> -# </div> - -# %% [markdown] -# **Define an x vector to evaluate the function** -# -# The function `f(x)` exists in "all space". However, the integration is bounded to the limits `a to b`, $I=\int_a^{b} f\left(x\right)\mathrm{d}x = \int_0^{3\pi} \left(20 \cos(x)+3x^2\right)\mathrm{d}x$. -# -# <br><br> -# Use those limits to create an x array using `linspace(a,b,n)`, where `a` is the limit to the left, `b` is the limit to the right and `n` is the number of points. Below you see the case with 5 points. -# -# <img src="linspace.jpg" style="height:100px" /> -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 3:</b> -# -# Define the intervals `a,b` and the number of points needed to have a subinterval length $\Delta x=\pi$. -# </p> -# </div> - -# %% -a = YOUR_CODE_HERE -b = YOUR_CODE_HERE -number_of_points = YOUR_CODE_HERE - -x_values = np.linspace(YOUR_CODE_HERE) -dx = x_values[1]-x_values[0] - -print("x = ",x_values) - - - -# test dx value -assert abs(dx - np.pi)<1e-5, "Oops! dx is not equal to pi. Please check your values for a, b and number of points." - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 4:</b> -# -# How do the number of points and number of subintervals relate? Write a brief answer below. -# </p> -# </div> - -# %% [markdown] -# **answer**: - -# %% [markdown] -# **Visualize a "continuous" function and list comprehension** -# -# For visualization purposes in the rest of the notebook, `f(x)` is here evaluated with high resolution. A "list comprehension" method is used for this purpose. **Understanding "list comprehensions" is essential to solve the rest of the notebook**. -# - -# %% [markdown] -# **Visualize a "continuous" function and list comprehension** -# -# For visualization purposes in the rest of the notebook, `f(x)` is here evaluated with high resolution. A "list comprehension" method is used for this purpose, which is a special feature of the Python programming language (you learned about it in the PA!). -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 5:</b> -# -# Three equivalent solutions to define <code>f_high_resolution</code> are shown below. The first one loops <code>x_high_resolution</code> and assigns its values to x, which is then used to evaluate f. -# -# The second one creates an index list based on the number of points contained in <code>x_high_resolution</code>, then loops it to evaluate f at each element of <code>x_high_resolution</code>. -# -# The third simply uses a function to evaluate the values. -# -# Which method do you find easier to read/write? -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>NOTE:</b> although list comprehensions may look more cumbersome here, it is important tool to learn, as in more complex code it can help make the algorithm easier to read and write. In terms of computation time, list comprehensions are faster than "regular" for loops (both are native Python features), However, the third approach is actually the fastest in terms of numerical computation time, because Numpy ndarrays (not native Python) are optimized for efficient computation. -# -# </p> -# </div> - -# %% -# To plot a smooth graph of the function -x_high_resolution = np.linspace(a, b, 50) - -f_high_resolution = [ f(x) for x in x_high_resolution ] #first solution - -f_high_resolution = [ f(x_high_resolution[i]) for i in range(len(x_high_resolution))] #second solution - - -# Plotting -plt.plot(x_high_resolution, f_high_resolution, '+', markersize='12', color='black') -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.legend(['Points evaluated','Continuous function representation']) -plt.title('Function for approximation') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - -# %% [markdown] -# <b>The Left Riemann Sum</b> -# -# This method approximates an integral by summing the area of rectangles defined with left points of the function: -# -# $$I_{_{left}} \approx \sum_{i=0}^{n-1} f(x_i)\Delta x$$ -# -# From now on, you will use ten points to define the function. -# <br><br> -# -# Let's look at the implementation of the Left Riemann sum following the same methods described in task 5. The differences are that (i) the index of the vector x ignores the last point, (ii) the multiplication by $\Delta x$ and (iii) the sum of the vector. Thus the result is not an array but a single number. -# <br><br> -# -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 6:</b> -# -# Scrutinize the correct implementations below. Why is it necessary to ignore the last point in x_values? What would happen if you include it? -# </p> -# </div> - -# %% - -x_values = np.linspace(a, b, 10) -dx = x_values[1]-x_values[0] - -# Left Riemann summation: 1st option -I_left_riemann = sum( [f(x)*dx for x in x_values[:-1]] ) #method 1 -print(f"Left Riemann Sum: {I_left_riemann: 0.3f}") - -# Left Riemann summation: 2nd option -I_left_riemann = sum( [ f(x_values[i])*dx for i in range(len(x_values)-1) ] ) #method 2 -print(f"Left Riemann Sum: {I_left_riemann: 0.3f}") - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 7:</b> -# -# Scrutinize the correct implementation below to visualize the bar plot (plt.bar) and location of the points (plt.plot with '*', in the line code below plt.bar) that define the height of each rectangle. -# <br> -# <br> -# Tip: The bar plot requires one less element than the total number of points defining the function. -# </p> -# </div> - -# %% -# Visualization -# Plot the rectangles and left corners of the elements in the riemann sum -plt.bar(x_values[:-1],[f(x) for x in x_values[:-1]], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25) -plt.plot(x_values[:-1],[f(x) for x in x_values[:-1]], '*', markersize='16', color='red') - -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Left Riemann Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - -# %% [markdown] -# **The Right Riemann Method** -# -# Similar to the left Riemann sum, this method is also algebraically simple to implement, and can be better suited to some situations, depending on the type of function you are trying to approximate. In this case, the subintervals are defined using the right-hand endpoints from the function and is represented by -# -# $$I_{_{right}} \approx \sum_{i=1}^n f(x_i)\Delta x$$ -# -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 8:</b> -# -# Complete the code cell below for the right Riemman method.. -# -# Tip: Consult the Left Riemann implementation above as a guide. -# </p> -# </div> - -# %% -I_right_riemann = sum( [YOUR_CODE_HERE for x in YOUR_CODE_HERE] ) - -print(f"Right Riemann Sum: {I_right_riemann: 0.3f}") - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 9:</b> -# -# Complete the code cell below to visualize the right Riemman method. -# -# </p> -# </div> - -# %% -# Right Riemann sum visualization -plt.bar(x_values[YOUR_CODE_HERE],[f(x) for x in x_values[YOUR_CODE_HERE]], - width=YOUR_CODE_HERE, alpha=0.5, align='edge', - edgecolor='black', linewidth=0.25) -plt.plot(x_values[YOUR_CODE_HERE],[f(x) for x in x_values[YOUR_CODE_HERE]], - '*', markersize='16', color='red') -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Right Riemann Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - -# %% [markdown] -# **Midpoint Method Approximation** -# -# For a function defined with constant steps (uniform $\Delta x$), the midpoint method approximates the integral taking the midpoint of the rectangle and splitting the width of the rectangle at this point. -# -# $$I_{_{mid}} \approx \sum_{i=0}^{n-1} f\left(\frac{x_i+x_{i+1}}{2}\right)\Delta x $$ -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 10:</b> -# -# Complete the code cell below to implement the midpoint sum below. -# </p> -# </div> - -# %% -I_midpoint = sum([f(YOUR_CODE_HERE)*dx for i in range(YOUR_CODE_HERE)]) -print(f"Midpoint Sum: {I_midpoint: 0.3e}") - -I_midpoint = sum([f(x_at_the_middle)*dx for x_at_the_middle in YOUR_CODE_HERE ]) -print(f"Midpoint Sum: {I_midpoint: 0.3e}") - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 11:</b> -# -# Complete the code cell below to visualize the midpoint method. -# -# </p> -# </div> - -# %% -# Midpoint sum visualization -plt.bar(x_values[YOUR_CODE_HERE],[f(x_at_the_middle) for x_at_the_middle in YOUR_CODE_HERE ], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25) -plt.plot(x_values[YOUR_CODE_HERE],[f(x_at_the_middle) for x_at_the_middle in YOUR_CODE_HERE],'*',markersize='16', color='red') -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Midpoint Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - -# %% [markdown] -# **Trapezoidal Rule** -# -# This method requires two evaluations of the function $f$ for each 'rectangle', at its left and right corners. In fact, it does not represent a 'rectangle anymore' but a trapezoid. For a 1D case, it is a rectangle with a triangle on top. -# -# $$I_{_{trapezoid}} \approx \sum_{i=0}^{n-1}\frac{f(x_i)+f(x_{i+1})}{2}\Delta x $$ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 12:</b> -# -# Complete the following code to implement the trapezoidal rule for the sum. -# -# </p> -# </div> - -# %% -I_trapezoidal = sum([YOUR_CODE_HERE for i in range(len(x_values)-1)]) -print(f"Trapezoidal Sum: {I_trapezoidal: 0.5e}") - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 13:</b> -# -# To visualize the trapezoidal method a plt.bar is not used rather plt_fill_between. Revise the code cell below. -# -# </p> -# </div> - -# %% -# Trapezoidal sum -for i in range(len(x_values)-1): - plt.fill_between([x_values[i], x_values[i+1]], - [f(x_values[i]), f(x_values[i+1])], - alpha=0.5) - -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Trapezoidal Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - - - -# %% [markdown] -# **Absolute errors in integral** - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 14:</b> -# -# Compute the absolute errors of each method. Are they similar to your expectatations? (i.e. corresponding to the orders of magnitude). -# -# </p> -# </div> - -# %% -# Calculate absolute errors -left_riemann_error = YOUR_CODE_HERE -right_riemann_error = YOUR_CODE_HERE -midpoint_error = YOUR_CODE_HERE -trapezoidal_error = YOUR_CODE_HERE - -# Print the results -print(f"Left Riemann Error: {left_riemann_error: 0.3e}") -print(f"Right Riemann Error: {right_riemann_error: 0.3e}") -print(f"Midpoint Error: {midpoint_error: 0.3e}") -print(f"Trapezoidal Error: {trapezoidal_error: 0.3e}") - - -# %% [markdown] -# **Simpson's Rule** -# -# Simpson's rule is a method that uses a quadratic approximation over an interval that allows the top bound of the area 'rectangle' to be defined by a polynomial. In general, it can be a better approximation for curved, but mathematically smooth functions. It also has the requirement that subintervals must be an even number, so this is something to be aware of when using it in practise. As a sum, it is defined as -# -# $$\int^{b}_{a}f(x)\mathrm{d}x\approx \sum_{i=1}^{n/2}\frac{1}{3}(f(x_{2i-2})+4f(x_{2i-1})+f(x_{2i}))\Delta x$$ -# -# where $n$ must be an *even integer*. -# -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Challenge</b> -# -# Take what you have seen in the other numerical implementation codes and implement Simpson's Rule for the same integral! A redefinition of x_values is done with 9 points instead of 10 as an uneven number of points is required to apply Simpson's Rule. -# </p> -# </div> - -# %% -# Define Simpson's Rule here -x_values = np.linspace(YOUR_CODE_HERE) -dx = YOUR_CODE_HERE - -simpson_integral = sum([ YOUR_CODE_HERE ]) - -# Calculate the absolute error -simpson_error = YOUR_CODE_HERE - -# Print the result and error -print(f"Simpson's Rule Integral: {simpson_integral: 0.5e}") -print(f"Simpson's Rule Absolute Error: {simpson_error: 0.5e}") - - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Task 15:</b> -# -# -# Refine the number of points using the integration by left riemann until reaching a similar accuracy as for the trapezoidal rule. How much finer was your grid? -# -# </p> -# </div> - -# %% [markdown] -# - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png"/> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png"/> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2023 <a rel="MUDE Team" href="https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=65595">MUDE Teaching Team</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>. diff --git a/synced_files/teachers/Week_1_5/WS_1_5_solution.ipynb b/synced_files/teachers/Week_1_5/WS_1_5_solution.ipynb deleted file mode 100644 index df1ae9a8ed9a0f47251c3c2c7e6e6f49660d19a2..0000000000000000000000000000000000000000 --- a/synced_files/teachers/Week_1_5/WS_1_5_solution.ipynb +++ /dev/null @@ -1,803 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "6cf87eaa-cae9-436c-86f5-b64181df5850", - "metadata": {}, - "source": [ - "# WS 1.5 Exploring Numerical Summing Schemes\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 90px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px\" />\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px\" />\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.5, Wednesday, Oct 4, 2023.*" - ] - }, - { - "cell_type": "markdown", - "id": "82cfc0b4", - "metadata": {}, - "source": [ - "## Problem definition: Numerical Integration\n", - "\n", - "Integration can be used to solve differential equations and to calculate relevant quantities in diverse engineering and scientific problems. When analyzing experiments or numerical models results, a desired physical quantity may be expressed as an integral of measured/model quantities. Sometimes the analytical integration is known, then this is the most accurate and fastest solution, certainly better than computing it numerically. However, it is common that the analytic solution is unknown, then numerical integration is the way to go. \n", - "\n", - "\n", - "You will use a function with a known integral to evaluate how precise numerical integration can be. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "caebff09-a533-40aa-9115-985c78e45693", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "from scipy.interpolate import make_interp_spline\n", - "\n", - "\n", - "plt.rcParams['figure.figsize'] = (15, 5) # Set the width and height of plots in inches\n", - "plt.rcParams.update({'font.size': 13}) # Change this value to your desired font size" - ] - }, - { - "cell_type": "markdown", - "id": "a6773319", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "352f1493", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1:</b> \n", - "\n", - "Calculate and evaluate the following integral by hand: \n", - "\n", - "$$I=\\int_a^{b} f\\left(x\\right)\\mathrm{d}x = \\int_0^{3\\pi} \\left(20 \\cos(x)+3x^2\\right)\\mathrm{d}x.$$\n", - "\n", - "The result will be later used to explore how diverse numerical integration techniques work and their accuracy. \n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "80e263da", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "\n", - "# YOUR SOLUTION HERE\n", - "exact_integral_evaluated = 27*np.pi**3 #your integrated function here \n", - "\n", - "\n", - "\n", - "# Test your answer\n", - "assert abs(exact_integral_evaluated - 837.16947)< 1e-5, \"Oops it's incorrect. Please check your derivation the integral \"\n", - "print(\"The exact value of the integral is: \", exact_integral_evaluated)" - ] - }, - { - "cell_type": "markdown", - "id": "fea89e84", - "metadata": {}, - "source": [ - "**Function definition**\n", - "\n", - "Let's define the python function \n", - "\n", - "\n", - "$$f\\left(x\\right) = \\left(20 \\cos x+3x^2\\right)\\mathrm{d}x$$ " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "98e6e3b6", - "metadata": {}, - "outputs": [], - "source": [ - "# Define the function to be later integrated\n", - "def f(x):\n", - " return 20*np.cos(x)+3*x**2" - ] - }, - { - "cell_type": "markdown", - "id": "cd6b9447", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2:</b> \n", - "\n", - "Call the function f written below to evaluate it at x=0. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "de1759f8", - "metadata": {}, - "outputs": [], - "source": [ - "## YOUR CODE HERE\n", - "f_at_x_equal_0 = f(0)\n", - "\n", - "print(\"f evaluated at x=0 is:\" , f_at_x_equal_0)" - ] - }, - { - "cell_type": "markdown", - "id": "f3bbdf8c", - "metadata": {}, - "source": [ - "<div style=\"background-color:#facb8e; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>NOTE:</b> Calling f(x) is equivalent to evaluating it! \n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "1c3d671e", - "metadata": {}, - "source": [ - "**Define an x vector to evaluate the function**\n", - "\n", - "The function `f(x)` exists in \"all space\". However, the integration is bounded to the limits `a to b`, $I=\\int_a^{b} f\\left(x\\right)\\mathrm{d}x = \\int_0^{3\\pi} \\left(10 \\cos(x)+4x\\right)\\mathrm{d}x$. \n", - "\n", - "<br><br>\n", - "Use those limits to create an x array using `linspace(a,b,n)`, where `a` is the limit to the left, `b` is the limit to the right and `n` is the number of points. Below you see the case with 5 points.\n", - "\n", - "<img src=\"linspace.jpg\" style=\"height:100px\" />\n" - ] - }, - { - "cell_type": "markdown", - "id": "add4309b", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 3:</b> \n", - "\n", - "Define the intervals `a,b` and the number of points needed to have a subinterval length $\\Delta x=\\pi$. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4b85d2a4", - "metadata": {}, - "outputs": [], - "source": [ - "# YOUR CODE HERE\n", - "a = 0\n", - "b = 3*np.pi#\n", - "number_of_points = 4\n", - "\n", - "x_values = np.linspace(a, b, number_of_points)\n", - "dx = x_values[1]-x_values[0]\n", - "\n", - "print(\"x = \",x_values)\n", - "\n", - "\n", - "\n", - "# test dx value\n", - "assert abs(dx - np.pi)<1e-5, \"Oops! dx is not equal to pi. Please check your values for a, b and number of points.\"" - ] - }, - { - "cell_type": "markdown", - "id": "ec5511fb", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 4:</b> \n", - "\n", - "How do the number of points and number of subintervals relate? Write a brief answer below.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "098d751a", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "1049c443", - "metadata": {}, - "source": [ - "**Visualize a \"continuous\" function and list comprehension**\n", - "\n", - "For visualization purposes in the rest of the notebook, `f(x)` is here evaluated with high resolution. A \"list comprehension\" method is used for this purpose, which is a special feature of the Python programming language (you learned about it in the PA!).\n" - ] - }, - { - "cell_type": "markdown", - "id": "128a2522", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 5:</b> \n", - "\n", - "Three equivalent solutions to define <code>f_high_resolution</code> are shown below. The first one loops <code>x_high_resolution</code> and assigns its values to x, which is then used to evaluate f. \n", - "\n", - "The second one creates an index list based on the number of points contained in <code>x_high_resolution</code>, then loops it to evaluate f at each element of <code>x_high_resolution</code>.\n", - "\n", - "The third simply uses a function to evaluate the values.\n", - "\n", - "Which method do you find easier to read/write?\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "181e09c7", - "metadata": {}, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>NOTE:</b> although list comprehensions may look more cumbersome here, it is important tool to learn, as in more complex code it can help make the algorithm easier to read and write. In terms of computation time, list comprehensions are faster than \"regular\" for loops (both are native Python features), However, the third approach is actually the fastest in terms of numerical computation time, because Numpy ndarrays (not native Python) are optimized for efficient computation.\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "65878405", - "metadata": {}, - "outputs": [], - "source": [ - "# To plot a smooth graph of the function\n", - "x_high_resolution = np.linspace(a, b, 50)\n", - "\n", - "#first solution\n", - "f_high_resolution = [ f(x) for x in x_high_resolution ]\n", - "#second solution\n", - "f_high_resolution = [ f(x_high_resolution[i]) for i in range(len(x_high_resolution))] \n", - "#third solution\n", - "f_high_resolution = f(x_high_resolution)\n", - "\n", - "# Plotting\n", - "plt.plot(x_high_resolution, f_high_resolution, '+', markersize='12', color='black')\n", - "plt.plot(x_high_resolution, f_high_resolution, 'b')\n", - "plt.legend(['Points evaluated','continuous function representation'])\n", - "plt.title('Function for approximation')\n", - "plt.xlabel('x')\n", - "plt.ylabel('$f(x)$');" - ] - }, - { - "cell_type": "markdown", - "id": "a9ef5459-2ffb-4bde-830c-646264c3648a", - "metadata": {}, - "source": [ - "<b>The Left Riemann Sum</b>\n", - "\n", - "This method approximates an integral by summing the area of rectangles defined with left points of the function:\n", - "\n", - "$$I_{_{left}} \\approx \\sum_{i=0}^{n-1} f(x_i)\\Delta x$$\n", - "\n", - "From now on, you will use ten points to define the function.\n", - "<br><br>\n", - "\n", - "Let's look at the implementation of the Left Riemman sum following the same methods described in task 5. The differences are that (i) the index of the vector x ignores the last point, (2) the multiplication by $\\Delta x$ and (iii) the sum of the vector. Thus the result is not an array but a single number. \n", - "<br><br>\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "80eb6362", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 6:</b> \n", - "\n", - "Scrutinize the correct implementations below. Why is it necessary to ignore the last point in x_values? What would happen if you include it? \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d3a75fe0-017b-4e8a-b729-68412a492854", - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "x_values = np.linspace(a, b, 10) \n", - "dx = x_values[1]-x_values[0]\n", - "\n", - "# Left Riemann summation: 1st option\n", - "\n", - "I_left_riemann = sum( [f(x)*dx for x in x_values[:-1]] ) #method 1\n", - "print(f\"Left Riemann Sum: {I_left_riemann: 0.3f}\")\n", - "# Left Riemann summation: 2nd option\n", - "I_left_riemann = sum( [ f(x_values[i])*dx for i in range(len(x_values)-1) ] ) #method 2\n", - "print(f\"Left Riemann Sum: {I_left_riemann: 0.3f}\")" - ] - }, - { - "cell_type": "markdown", - "id": "409b0530", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 7:</b> \n", - "\n", - "Scrutinize the correct implementation below to visualize the bar plot (plt.bar) and location of the points (plt.plot with '*', in the line code below plt.bar) that define the height of each rectangle. \n", - "<br>\n", - "<br>\n", - "Tip: The bar plot requires one less element than the total number of points defining the function. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0c09dc12", - "metadata": {}, - "outputs": [], - "source": [ - "# Visualization\n", - "# Plot the rectangles and left corners of the elements in the riemann sum\n", - "plt.bar(x_values[:-1],[f(x) for x in x_values[:-1]], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25)\n", - "plt.plot(x_values[:-1],[f(x) for x in x_values[:-1]], '*', markersize='16', color='red')\n", - "\n", - "#Plot \"continous\" function\n", - "plt.plot(x_high_resolution, f_high_resolution, 'b')\n", - "plt.title('Left Riemann Sum')\n", - "plt.xlabel('x')\n", - "plt.ylabel('$f(x)$');" - ] - }, - { - "cell_type": "markdown", - "id": "8906e8ab-9aa5-45db-a683-cd40a6729575", - "metadata": {}, - "source": [ - "**The Right Riemann Method**\n", - "\n", - "Similar to the left Riemann sum, this method is also algebraically simple to implement, and can be better suited to some situations, depending on the type of function you are trying to approximate. In this case, the subintervals are defined using the right-hand endpoints from the function and is represented by \n", - "\n", - "$$I_{_{right}} \\approx \\sum_{i=1}^n f(x_i)\\Delta x$$\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "0bbf4b11", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 8:</b> \n", - "\n", - "Complete the code cell below for the right Riemman method.. \n", - "\n", - "Tip: Consult the Left Riemann implementation above as a guide.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3073db6e-430c-4f17-ad88-a4f2892a55f1", - "metadata": {}, - "outputs": [], - "source": [ - "I_right_riemann = sum( [f(x)*dx for x in x_values[1:]] ) \n", - "\n", - "print(f\"Right Riemann Sum: {I_right_riemann: 0.3f}\")" - ] - }, - { - "cell_type": "markdown", - "id": "0cf7e125", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 9:</b> \n", - "\n", - "Complete the code cell below to visualize the right Riemman method.\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "db67a64a", - "metadata": {}, - "source": [ - "<div style=\"background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>NOTE:</b> the plot here uses <code>-dx</code>, as done in the PA for this week to allow the <code>x_values</code> to remain consistent for each method (and with the analytic expressions).\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c510d26b", - "metadata": {}, - "outputs": [], - "source": [ - "# Right Riemann sum visualization\n", - "plt.bar(x_values[1:],[f(x) for x in x_values[1:]],\n", - " width=-dx, alpha=0.5, align='edge',\n", - " edgecolor='black', linewidth=0.25)\n", - "plt.plot(x_values[1:],[f(x) for x in x_values[1:]],\n", - " '*', markersize='16', color='red')\n", - "#Plot \"continuous\" function\n", - "plt.plot(x_high_resolution, f_high_resolution, 'b')\n", - "plt.title('Right Riemann Sum')\n", - "plt.xlabel('x')\n", - "plt.ylabel('$f(x)$');" - ] - }, - { - "cell_type": "markdown", - "id": "24d26cbb-ab8f-435f-8238-0c22c0fce833", - "metadata": {}, - "source": [ - "**Midpoint Method Approximation**\n", - "\n", - "For a function defined with constant steps (uniform $\\Delta x$), the midpoint method approximates the integral taking the midpoint of the rectangle and splitting the width of the rectangle at this point. \n", - "\n", - "$$I_{_{mid}} \\approx \\sum_{i=0}^{n-1} f\\left(\\frac{x_i+x_{i+1}}{2}\\right)\\Delta x $$\n" - ] - }, - { - "cell_type": "markdown", - "id": "13d1d689", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 10:</b> \n", - "\n", - "Complete the code cell below to implemen the midpoint sum below.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7ed26ad5-d2cb-450e-873d-5b21a596cedb", - "metadata": {}, - "outputs": [], - "source": [ - "I_midpoint = sum([f((x_values[i] + x_values[i+1]) / 2)*dx for i in range(len(x_values)-1)])\n", - "print(f\"Midpoint Sum: {I_midpoint: 0.3e}\")\n", - "\n", - "I_midpoint = sum([f(x_at_the_middle)*dx for x_at_the_middle in (x_values[:-1]+x_values[1:])/2 ])\n", - "print(f\"Midpoint Sum: {I_midpoint: 0.3e}\")" - ] - }, - { - "cell_type": "markdown", - "id": "e685d8c3", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 11:</b> \n", - "\n", - "Complete the code cell below to visualize the midpoint method.\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "370672eb", - "metadata": {}, - "outputs": [], - "source": [ - "# Midpoint sum visualization\n", - "plt.bar(x_values[:-1],[f(x_at_the_middle) for x_at_the_middle in (x_values[:-1]+x_values[1:])/2 ], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25)\n", - "plt.plot((x_values[:-1]+x_values[1:])/2,[f(x_at_the_middle) for x_at_the_middle in (x_values[:-1]+x_values[1:])/2 ],'*',markersize='16', color='red')\n", - "#Plot \"continous\" function\n", - "plt.plot(x_high_resolution, f_high_resolution, 'b')\n", - "plt.title('Midpoint Sum')\n", - "plt.xlabel('x')\n", - "plt.ylabel('$f(x)$');" - ] - }, - { - "cell_type": "markdown", - "id": "fcf6f8bc-5554-4309-81ce-0433fa947e34", - "metadata": {}, - "source": [ - "**Trapezoidal Rule**\n", - "\n", - "This method requires two evaluations of the function $f$ for each 'rectangle', at its left and right corners. In fact, it does not represent a 'rectangle anymore' but a trapezoid. For a 1D case, it is a rectangle with a triangle on top. \n", - "\n", - "$$I_{_{trapezoid}} \\approx \\sum_{i=0}^{n-1}\\frac{f(x_i)+f(x_{i+1})}{2}\\Delta x $$" - ] - }, - { - "cell_type": "markdown", - "id": "74bb23af", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 12:</b> \n", - "\n", - "Complete the following code to implement the trapezoidal rule for the sum. \n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b6e68930-f1d8-4d7e-8162-8cd59f985be0", - "metadata": {}, - "outputs": [], - "source": [ - "I_trapezoidal = sum([(f(x_values[i]) + f(x_values[i+1])) / 2 * dx for i in range(len(x_values)-1)]) \n", - "print(f\"Trapezoidal Sum: {I_trapezoidal: 0.5e}\")" - ] - }, - { - "cell_type": "markdown", - "id": "5a3a195c", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 13:</b> \n", - "\n", - "To visualize the trapezoidal method a plt.bar is not used rather plt_fill_between. Revise the code cell below.\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "36cddace", - "metadata": {}, - "outputs": [], - "source": [ - "# Trapezoidal sum\n", - "for i in range(len(x_values)-1):\n", - " plt.fill_between([x_values[i], x_values[i+1]], \n", - " [f(x_values[i]), f(x_values[i+1])], \n", - " alpha=0.5)\n", - "\n", - "#Plot \"continous\" function\n", - "plt.plot(x_high_resolution, f_high_resolution, 'b')\n", - "plt.title('Trapezoidal Sum')\n", - "plt.xlabel('x')\n", - "plt.ylabel('$f(x)$');\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "14295e08-e9db-4735-927d-715989b62b81", - "metadata": {}, - "source": [ - "**Absolute errors in integral**" - ] - }, - { - "cell_type": "markdown", - "id": "d6b0720c", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 14:</b> \n", - "\n", - "Compute the absolute errors of each method. Are they similar to your expectatations? (i.e. corresponding to the orders of magnitude).\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "582e66ed-2016-4a84-a5f4-6d01d49671dc", - "metadata": {}, - "outputs": [], - "source": [ - "# Calculate absolute errors\n", - "left_riemann_error = abs(exact_integral_evaluated - I_left_riemann)\n", - "right_riemann_error = abs(exact_integral_evaluated - I_right_riemann)\n", - "midpoint_error = abs(exact_integral_evaluated - I_midpoint)\n", - "trapezoidal_error = abs(exact_integral_evaluated - I_trapezoidal)\n", - "\n", - "# Print the results\n", - "print(f\"Left Riemann Error: {left_riemann_error: 0.3e}\")\n", - "print(f\"Right Riemann Error: {right_riemann_error: 0.3e}\")\n", - "print(f\"Midpoint Error: {midpoint_error: 0.3e}\")\n", - "print(f\"Trapezoidal Error: {trapezoidal_error: 0.3e}\")\n" - ] - }, - { - "cell_type": "markdown", - "id": "ddc2f16f-7065-4829-aafc-91c95cc93aaf", - "metadata": {}, - "source": [ - "**Simpson's Rule**\n", - "\n", - "Simpson's rule is a method that uses a quadratic approximation over an interval that allows the top bound of the area 'rectangle' to be defined by a polynomial. In general, it can be a better approximation for curved, but mathematically smooth functions. It also has the requirement that subintervals must be an even number, so this is something to be aware of when using it in practise. As a sum, it is defined as \n", - "\n", - "$$\\int^{b}_{a}f(x)\\mathrm{d}x\\approx \\sum_{i=1}^{n/2}\\frac{1}{3}(f(x_{2i-2})+4f(x_{2i-1})+f(x_{2i}))\\Delta x$$\n", - "\n", - "where $n$ must be an *even integer*.\n", - "\n", - " " - ] - }, - { - "cell_type": "markdown", - "id": "e0ed72e0-ced6-467c-8e01-a1b602a3613d", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Challenge</b>\n", - "\n", - "Take what you have seen in the other numerical implementation codes and implement Simpson's Rule for the same integral! A redefinition of x_values is done with 9 points instead of 10 as an uneven number of points is required to apply Simpson's Rule. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ae169f8e-2d5a-4449-8c53-c8ca399af184", - "metadata": {}, - "outputs": [], - "source": [ - "# Define Simpson's Rule here\n", - "x_values = np.linspace(a, b, 9)\n", - "dx = x_values[1]-x_values[0] \n", - " \n", - "simpson_integral = sum([(f(x_values[2*i-2]) + 4*f(x_values[2*i-1]) + f(x_values[2*i])) / 3 * dx for i in range(1,int(len(x_values)/2)+1)]) \n", - "\n", - "# Calculate the absolute error\n", - "simpson_error = abs(exact_integral_evaluated - simpson_integral)\n", - "\n", - "# Print the result and error\n", - "print(f\"Simpson's Rule Integral: {simpson_integral: 0.5e}\")\n", - "print(f\"Simpson's Rule Absolute Error: {simpson_error: 0.5e}\")\n" - ] - }, - { - "cell_type": "markdown", - "id": "8ffe7a1f", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 15:</b> \n", - " \n", - " \n", - "Refine the number of points using the integration by left riemmann until reaching a similar accuracy as for the trapezoidal rule. How much finer was your grid?\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "793cb6e5", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "6aced257", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" />\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" />\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2024 <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">MUDE</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">CC BY 4.0 License</a>." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.4" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/synced_files/teachers/Week_1_5/WS_1_5_solution.md b/synced_files/teachers/Week_1_5/WS_1_5_solution.md deleted file mode 100644 index 01437a814627f3ac39d72ac61bf4605287c26ade..0000000000000000000000000000000000000000 --- a/synced_files/teachers/Week_1_5/WS_1_5_solution.md +++ /dev/null @@ -1,515 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -# WS 1.5 Exploring Numerical Summing Schemes - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 90px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.5, Wednesday, Oct 4, 2023.* - -<!-- #region --> -## Problem definition: Numerical Integration - -Integration can be used to solve differential equations and to calculate relevant quantities in diverse engineering and scientific problems. When analyzing experiments or numerical models results, a desired physical quantity may be expressed as an integral of measured/model quantities. Sometimes the analytical integration is known, then this is the most accurate and fastest solution, certainly better than computing it numerically. However, it is common that the analytic solution is unknown, then numerical integration is the way to go. - - -You will use a function with a known integral to evaluate how precise numerical integration can be. -<!-- #endregion --> - -```python -import numpy as np -import matplotlib.pyplot as plt -from scipy.interpolate import make_interp_spline - - -plt.rcParams['figure.figsize'] = (15, 5) # Set the width and height of plots in inches -plt.rcParams.update({'font.size': 13}) # Change this value to your desired font size -``` - - - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1:</b> - -Calculate and evaluate the following integral by hand: - -$$I=\int_a^{b} f\left(x\right)\mathrm{d}x = \int_0^{3\pi} \left(20 \cos(x)+3x^2\right)\mathrm{d}x.$$ - -The result will be later used to explore how diverse numerical integration techniques work and their accuracy. - -</p> -</div> - -```python - -# YOUR SOLUTION HERE -exact_integral_evaluated = 27*np.pi**3 #your integrated function here - - - -# Test your answer -assert abs(exact_integral_evaluated - 837.16947)< 1e-5, "Oops it's incorrect. Please check your derivation the integral " -print("The exact value of the integral is: ", exact_integral_evaluated) -``` - -<!-- #region --> -**Function definition** - -Let's define the python function - - -$$f\left(x\right) = \left(20 \cos x+3x^2\right)\mathrm{d}x$$ -<!-- #endregion --> - -```python -# Define the function to be later integrated -def f(x): - return 20*np.cos(x)+3*x**2 -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2:</b> - -Call the function f written below to evaluate it at x=0. -</p> -</div> - -```python -## YOUR CODE HERE -f_at_x_equal_0 = f(0) - -print("f evaluated at x=0 is:" , f_at_x_equal_0) -``` - -<div style="background-color:#facb8e; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>NOTE:</b> Calling f(x) is equivalent to evaluating it! - -</p> -</div> - - -**Define an x vector to evaluate the function** - -The function `f(x)` exists in "all space". However, the integration is bounded to the limits `a to b`, $I=\int_a^{b} f\left(x\right)\mathrm{d}x = \int_0^{3\pi} \left(10 \cos(x)+4x\right)\mathrm{d}x$. - -<br><br> -Use those limits to create an x array using `linspace(a,b,n)`, where `a` is the limit to the left, `b` is the limit to the right and `n` is the number of points. Below you see the case with 5 points. - -<img src="linspace.jpg" style="height:100px" /> - - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 3:</b> - -Define the intervals `a,b` and the number of points needed to have a subinterval length $\Delta x=\pi$. -</p> -</div> - -```python -# YOUR CODE HERE -a = 0 -b = 3*np.pi# -number_of_points = 4 - -x_values = np.linspace(a, b, number_of_points) -dx = x_values[1]-x_values[0] - -print("x = ",x_values) - - - -# test dx value -assert abs(dx - np.pi)<1e-5, "Oops! dx is not equal to pi. Please check your values for a, b and number of points." -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 4:</b> - -How do the number of points and number of subintervals relate? Write a brief answer below. -</p> -</div> - - - - - -**Visualize a "continuous" function and list comprehension** - -For visualization purposes in the rest of the notebook, `f(x)` is here evaluated with high resolution. A "list comprehension" method is used for this purpose, which is a special feature of the Python programming language (you learned about it in the PA!). - - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 5:</b> - -Three equivalent solutions to define <code>f_high_resolution</code> are shown below. The first one loops <code>x_high_resolution</code> and assigns its values to x, which is then used to evaluate f. - -The second one creates an index list based on the number of points contained in <code>x_high_resolution</code>, then loops it to evaluate f at each element of <code>x_high_resolution</code>. - -The third simply uses a function to evaluate the values. - -Which method do you find easier to read/write? -</p> -</div> - - -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>NOTE:</b> although list comprehensions may look more cumbersome here, it is important tool to learn, as in more complex code it can help make the algorithm easier to read and write. In terms of computation time, list comprehensions are faster than "regular" for loops (both are native Python features), However, the third approach is actually the fastest in terms of numerical computation time, because Numpy ndarrays (not native Python) are optimized for efficient computation. - -</p> -</div> - -```python -# To plot a smooth graph of the function -x_high_resolution = np.linspace(a, b, 50) - -#first solution -f_high_resolution = [ f(x) for x in x_high_resolution ] -#second solution -f_high_resolution = [ f(x_high_resolution[i]) for i in range(len(x_high_resolution))] -#third solution -f_high_resolution = f(x_high_resolution) - -# Plotting -plt.plot(x_high_resolution, f_high_resolution, '+', markersize='12', color='black') -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.legend(['Points evaluated','continuous function representation']) -plt.title('Function for approximation') -plt.xlabel('x') -plt.ylabel('$f(x)$'); -``` - -<b>The Left Riemann Sum</b> - -This method approximates an integral by summing the area of rectangles defined with left points of the function: - -$$I_{_{left}} \approx \sum_{i=0}^{n-1} f(x_i)\Delta x$$ - -From now on, you will use ten points to define the function. -<br><br> - -Let's look at the implementation of the Left Riemman sum following the same methods described in task 5. The differences are that (i) the index of the vector x ignores the last point, (2) the multiplication by $\Delta x$ and (iii) the sum of the vector. Thus the result is not an array but a single number. -<br><br> - - - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 6:</b> - -Scrutinize the correct implementations below. Why is it necessary to ignore the last point in x_values? What would happen if you include it? -</p> -</div> - -```python - -x_values = np.linspace(a, b, 10) -dx = x_values[1]-x_values[0] - -# Left Riemann summation: 1st option - -I_left_riemann = sum( [f(x)*dx for x in x_values[:-1]] ) #method 1 -print(f"Left Riemann Sum: {I_left_riemann: 0.3f}") -# Left Riemann summation: 2nd option -I_left_riemann = sum( [ f(x_values[i])*dx for i in range(len(x_values)-1) ] ) #method 2 -print(f"Left Riemann Sum: {I_left_riemann: 0.3f}") -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 7:</b> - -Scrutinize the correct implementation below to visualize the bar plot (plt.bar) and location of the points (plt.plot with '*', in the line code below plt.bar) that define the height of each rectangle. -<br> -<br> -Tip: The bar plot requires one less element than the total number of points defining the function. -</p> -</div> - -```python -# Visualization -# Plot the rectangles and left corners of the elements in the riemann sum -plt.bar(x_values[:-1],[f(x) for x in x_values[:-1]], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25) -plt.plot(x_values[:-1],[f(x) for x in x_values[:-1]], '*', markersize='16', color='red') - -#Plot "continous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Left Riemann Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); -``` - -**The Right Riemann Method** - -Similar to the left Riemann sum, this method is also algebraically simple to implement, and can be better suited to some situations, depending on the type of function you are trying to approximate. In this case, the subintervals are defined using the right-hand endpoints from the function and is represented by - -$$I_{_{right}} \approx \sum_{i=1}^n f(x_i)\Delta x$$ - - - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 8:</b> - -Complete the code cell below for the right Riemman method.. - -Tip: Consult the Left Riemann implementation above as a guide. -</p> -</div> - -```python -I_right_riemann = sum( [f(x)*dx for x in x_values[1:]] ) - -print(f"Right Riemann Sum: {I_right_riemann: 0.3f}") -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 9:</b> - -Complete the code cell below to visualize the right Riemman method. - -</p> -</div> - - -<div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>NOTE:</b> the plot here uses <code>-dx</code>, as done in the PA for this week to allow the <code>x_values</code> to remain consistent for each method (and with the analytic expressions). - -</p> -</div> - -```python -# Right Riemann sum visualization -plt.bar(x_values[1:],[f(x) for x in x_values[1:]], - width=-dx, alpha=0.5, align='edge', - edgecolor='black', linewidth=0.25) -plt.plot(x_values[1:],[f(x) for x in x_values[1:]], - '*', markersize='16', color='red') -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Right Riemann Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); -``` - -**Midpoint Method Approximation** - -For a function defined with constant steps (uniform $\Delta x$), the midpoint method approximates the integral taking the midpoint of the rectangle and splitting the width of the rectangle at this point. - -$$I_{_{mid}} \approx \sum_{i=0}^{n-1} f\left(\frac{x_i+x_{i+1}}{2}\right)\Delta x $$ - - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 10:</b> - -Complete the code cell below to implemen the midpoint sum below. -</p> -</div> - -```python -I_midpoint = sum([f((x_values[i] + x_values[i+1]) / 2)*dx for i in range(len(x_values)-1)]) -print(f"Midpoint Sum: {I_midpoint: 0.3e}") - -I_midpoint = sum([f(x_at_the_middle)*dx for x_at_the_middle in (x_values[:-1]+x_values[1:])/2 ]) -print(f"Midpoint Sum: {I_midpoint: 0.3e}") -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 11:</b> - -Complete the code cell below to visualize the midpoint method. - -</p> -</div> - -```python -# Midpoint sum visualization -plt.bar(x_values[:-1],[f(x_at_the_middle) for x_at_the_middle in (x_values[:-1]+x_values[1:])/2 ], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25) -plt.plot((x_values[:-1]+x_values[1:])/2,[f(x_at_the_middle) for x_at_the_middle in (x_values[:-1]+x_values[1:])/2 ],'*',markersize='16', color='red') -#Plot "continous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Midpoint Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); -``` - -**Trapezoidal Rule** - -This method requires two evaluations of the function $f$ for each 'rectangle', at its left and right corners. In fact, it does not represent a 'rectangle anymore' but a trapezoid. For a 1D case, it is a rectangle with a triangle on top. - -$$I_{_{trapezoid}} \approx \sum_{i=0}^{n-1}\frac{f(x_i)+f(x_{i+1})}{2}\Delta x $$ - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 12:</b> - -Complete the following code to implement the trapezoidal rule for the sum. - -</p> -</div> - -```python -I_trapezoidal = sum([(f(x_values[i]) + f(x_values[i+1])) / 2 * dx for i in range(len(x_values)-1)]) -print(f"Trapezoidal Sum: {I_trapezoidal: 0.5e}") -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 13:</b> - -To visualize the trapezoidal method a plt.bar is not used rather plt_fill_between. Revise the code cell below. - -</p> -</div> - -```python -# Trapezoidal sum -for i in range(len(x_values)-1): - plt.fill_between([x_values[i], x_values[i+1]], - [f(x_values[i]), f(x_values[i+1])], - alpha=0.5) - -#Plot "continous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Trapezoidal Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - - -``` - -**Absolute errors in integral** - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 14:</b> - -Compute the absolute errors of each method. Are they similar to your expectatations? (i.e. corresponding to the orders of magnitude). - -</p> -</div> - -```python -# Calculate absolute errors -left_riemann_error = abs(exact_integral_evaluated - I_left_riemann) -right_riemann_error = abs(exact_integral_evaluated - I_right_riemann) -midpoint_error = abs(exact_integral_evaluated - I_midpoint) -trapezoidal_error = abs(exact_integral_evaluated - I_trapezoidal) - -# Print the results -print(f"Left Riemann Error: {left_riemann_error: 0.3e}") -print(f"Right Riemann Error: {right_riemann_error: 0.3e}") -print(f"Midpoint Error: {midpoint_error: 0.3e}") -print(f"Trapezoidal Error: {trapezoidal_error: 0.3e}") - -``` - -**Simpson's Rule** - -Simpson's rule is a method that uses a quadratic approximation over an interval that allows the top bound of the area 'rectangle' to be defined by a polynomial. In general, it can be a better approximation for curved, but mathematically smooth functions. It also has the requirement that subintervals must be an even number, so this is something to be aware of when using it in practise. As a sum, it is defined as - -$$\int^{b}_{a}f(x)\mathrm{d}x\approx \sum_{i=1}^{n/2}\frac{1}{3}(f(x_{2i-2})+4f(x_{2i-1})+f(x_{2i}))\Delta x$$ - -where $n$ must be an *even integer*. - - - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Challenge</b> - -Take what you have seen in the other numerical implementation codes and implement Simpson's Rule for the same integral! A redefinition of x_values is done with 9 points instead of 10 as an uneven number of points is required to apply Simpson's Rule. -</p> -</div> - -```python -# Define Simpson's Rule here -x_values = np.linspace(a, b, 9) -dx = x_values[1]-x_values[0] - -simpson_integral = sum([(f(x_values[2*i-2]) + 4*f(x_values[2*i-1]) + f(x_values[2*i])) / 3 * dx for i in range(1,int(len(x_values)/2)+1)]) - -# Calculate the absolute error -simpson_error = abs(exact_integral_evaluated - simpson_integral) - -# Print the result and error -print(f"Simpson's Rule Integral: {simpson_integral: 0.5e}") -print(f"Simpson's Rule Absolute Error: {simpson_error: 0.5e}") - -``` - -<!-- #region --> -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 15:</b> - - -Refine the number of points using the integration by left riemmann until reaching a similar accuracy as for the trapezoidal rule. How much finer was your grid? - -</p> -</div> -<!-- #endregion --> - - - - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/teachers/Week_1_5/WS_1_5_solution.py b/synced_files/teachers/Week_1_5/WS_1_5_solution.py deleted file mode 100644 index 01192bec21bf462280d7bc6c69097fbcbcb66cfd..0000000000000000000000000000000000000000 --- a/synced_files/teachers/Week_1_5/WS_1_5_solution.py +++ /dev/null @@ -1,514 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: Python 3 (ipykernel) -# language: python -# name: python3 -# --- - -# %% [markdown] -# # WS 1.5 Exploring Numerical Summing Schemes -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 90px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.5, Wednesday, Oct 4, 2023.* - -# %% [markdown] -# ## Problem definition: Numerical Integration -# -# Integration can be used to solve differential equations and to calculate relevant quantities in diverse engineering and scientific problems. When analyzing experiments or numerical models results, a desired physical quantity may be expressed as an integral of measured/model quantities. Sometimes the analytical integration is known, then this is the most accurate and fastest solution, certainly better than computing it numerically. However, it is common that the analytic solution is unknown, then numerical integration is the way to go. -# -# -# You will use a function with a known integral to evaluate how precise numerical integration can be. - -# %% -import numpy as np -import matplotlib.pyplot as plt -from scipy.interpolate import make_interp_spline - - -plt.rcParams['figure.figsize'] = (15, 5) # Set the width and height of plots in inches -plt.rcParams.update({'font.size': 13}) # Change this value to your desired font size - -# %% [markdown] -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1:</b> -# -# Calculate and evaluate the following integral by hand: -# -# $$I=\int_a^{b} f\left(x\right)\mathrm{d}x = \int_0^{3\pi} \left(20 \cos(x)+3x^2\right)\mathrm{d}x.$$ -# -# The result will be later used to explore how diverse numerical integration techniques work and their accuracy. -# -# </p> -# </div> - -# %% - -# YOUR SOLUTION HERE -exact_integral_evaluated = 27*np.pi**3 #your integrated function here - - - -# Test your answer -assert abs(exact_integral_evaluated - 837.16947)< 1e-5, "Oops it's incorrect. Please check your derivation the integral " -print("The exact value of the integral is: ", exact_integral_evaluated) - - -# %% [markdown] -# **Function definition** -# -# Let's define the python function -# -# -# $$f\left(x\right) = \left(20 \cos x+3x^2\right)\mathrm{d}x$$ - -# %% -# Define the function to be later integrated -def f(x): - return 20*np.cos(x)+3*x**2 - - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2:</b> -# -# Call the function f written below to evaluate it at x=0. -# </p> -# </div> - -# %% -## YOUR CODE HERE -f_at_x_equal_0 = f(0) - -print("f evaluated at x=0 is:" , f_at_x_equal_0) - -# %% [markdown] -# <div style="background-color:#facb8e; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>NOTE:</b> Calling f(x) is equivalent to evaluating it! -# -# </p> -# </div> - -# %% [markdown] -# **Define an x vector to evaluate the function** -# -# The function `f(x)` exists in "all space". However, the integration is bounded to the limits `a to b`, $I=\int_a^{b} f\left(x\right)\mathrm{d}x = \int_0^{3\pi} \left(10 \cos(x)+4x\right)\mathrm{d}x$. -# -# <br><br> -# Use those limits to create an x array using `linspace(a,b,n)`, where `a` is the limit to the left, `b` is the limit to the right and `n` is the number of points. Below you see the case with 5 points. -# -# <img src="linspace.jpg" style="height:100px" /> -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 3:</b> -# -# Define the intervals `a,b` and the number of points needed to have a subinterval length $\Delta x=\pi$. -# </p> -# </div> - -# %% -# YOUR CODE HERE -a = 0 -b = 3*np.pi# -number_of_points = 4 - -x_values = np.linspace(a, b, number_of_points) -dx = x_values[1]-x_values[0] - -print("x = ",x_values) - - - -# test dx value -assert abs(dx - np.pi)<1e-5, "Oops! dx is not equal to pi. Please check your values for a, b and number of points." - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 4:</b> -# -# How do the number of points and number of subintervals relate? Write a brief answer below. -# </p> -# </div> - -# %% [markdown] -# - -# %% [markdown] -# **Visualize a "continuous" function and list comprehension** -# -# For visualization purposes in the rest of the notebook, `f(x)` is here evaluated with high resolution. A "list comprehension" method is used for this purpose, which is a special feature of the Python programming language (you learned about it in the PA!). -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 5:</b> -# -# Three equivalent solutions to define <code>f_high_resolution</code> are shown below. The first one loops <code>x_high_resolution</code> and assigns its values to x, which is then used to evaluate f. -# -# The second one creates an index list based on the number of points contained in <code>x_high_resolution</code>, then loops it to evaluate f at each element of <code>x_high_resolution</code>. -# -# The third simply uses a function to evaluate the values. -# -# Which method do you find easier to read/write? -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>NOTE:</b> although list comprehensions may look more cumbersome here, it is important tool to learn, as in more complex code it can help make the algorithm easier to read and write. In terms of computation time, list comprehensions are faster than "regular" for loops (both are native Python features), However, the third approach is actually the fastest in terms of numerical computation time, because Numpy ndarrays (not native Python) are optimized for efficient computation. -# -# </p> -# </div> - -# %% -# To plot a smooth graph of the function -x_high_resolution = np.linspace(a, b, 50) - -#first solution -f_high_resolution = [ f(x) for x in x_high_resolution ] -#second solution -f_high_resolution = [ f(x_high_resolution[i]) for i in range(len(x_high_resolution))] -#third solution -f_high_resolution = f(x_high_resolution) - -# Plotting -plt.plot(x_high_resolution, f_high_resolution, '+', markersize='12', color='black') -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.legend(['Points evaluated','continuous function representation']) -plt.title('Function for approximation') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - -# %% [markdown] -# <b>The Left Riemann Sum</b> -# -# This method approximates an integral by summing the area of rectangles defined with left points of the function: -# -# $$I_{_{left}} \approx \sum_{i=0}^{n-1} f(x_i)\Delta x$$ -# -# From now on, you will use ten points to define the function. -# <br><br> -# -# Let's look at the implementation of the Left Riemman sum following the same methods described in task 5. The differences are that (i) the index of the vector x ignores the last point, (2) the multiplication by $\Delta x$ and (iii) the sum of the vector. Thus the result is not an array but a single number. -# <br><br> -# -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 6:</b> -# -# Scrutinize the correct implementations below. Why is it necessary to ignore the last point in x_values? What would happen if you include it? -# </p> -# </div> - -# %% - -x_values = np.linspace(a, b, 10) -dx = x_values[1]-x_values[0] - -# Left Riemann summation: 1st option - -I_left_riemann = sum( [f(x)*dx for x in x_values[:-1]] ) #method 1 -print(f"Left Riemann Sum: {I_left_riemann: 0.3f}") -# Left Riemann summation: 2nd option -I_left_riemann = sum( [ f(x_values[i])*dx for i in range(len(x_values)-1) ] ) #method 2 -print(f"Left Riemann Sum: {I_left_riemann: 0.3f}") - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 7:</b> -# -# Scrutinize the correct implementation below to visualize the bar plot (plt.bar) and location of the points (plt.plot with '*', in the line code below plt.bar) that define the height of each rectangle. -# <br> -# <br> -# Tip: The bar plot requires one less element than the total number of points defining the function. -# </p> -# </div> - -# %% -# Visualization -# Plot the rectangles and left corners of the elements in the riemann sum -plt.bar(x_values[:-1],[f(x) for x in x_values[:-1]], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25) -plt.plot(x_values[:-1],[f(x) for x in x_values[:-1]], '*', markersize='16', color='red') - -#Plot "continous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Left Riemann Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - -# %% [markdown] -# **The Right Riemann Method** -# -# Similar to the left Riemann sum, this method is also algebraically simple to implement, and can be better suited to some situations, depending on the type of function you are trying to approximate. In this case, the subintervals are defined using the right-hand endpoints from the function and is represented by -# -# $$I_{_{right}} \approx \sum_{i=1}^n f(x_i)\Delta x$$ -# -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 8:</b> -# -# Complete the code cell below for the right Riemman method.. -# -# Tip: Consult the Left Riemann implementation above as a guide. -# </p> -# </div> - -# %% -I_right_riemann = sum( [f(x)*dx for x in x_values[1:]] ) - -print(f"Right Riemann Sum: {I_right_riemann: 0.3f}") - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 9:</b> -# -# Complete the code cell below to visualize the right Riemman method. -# -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#facb8e; color: black; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>NOTE:</b> the plot here uses <code>-dx</code>, as done in the PA for this week to allow the <code>x_values</code> to remain consistent for each method (and with the analytic expressions). -# -# </p> -# </div> - -# %% -# Right Riemann sum visualization -plt.bar(x_values[1:],[f(x) for x in x_values[1:]], - width=-dx, alpha=0.5, align='edge', - edgecolor='black', linewidth=0.25) -plt.plot(x_values[1:],[f(x) for x in x_values[1:]], - '*', markersize='16', color='red') -#Plot "continuous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Right Riemann Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - -# %% [markdown] -# **Midpoint Method Approximation** -# -# For a function defined with constant steps (uniform $\Delta x$), the midpoint method approximates the integral taking the midpoint of the rectangle and splitting the width of the rectangle at this point. -# -# $$I_{_{mid}} \approx \sum_{i=0}^{n-1} f\left(\frac{x_i+x_{i+1}}{2}\right)\Delta x $$ -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 10:</b> -# -# Complete the code cell below to implemen the midpoint sum below. -# </p> -# </div> - -# %% -I_midpoint = sum([f((x_values[i] + x_values[i+1]) / 2)*dx for i in range(len(x_values)-1)]) -print(f"Midpoint Sum: {I_midpoint: 0.3e}") - -I_midpoint = sum([f(x_at_the_middle)*dx for x_at_the_middle in (x_values[:-1]+x_values[1:])/2 ]) -print(f"Midpoint Sum: {I_midpoint: 0.3e}") - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 11:</b> -# -# Complete the code cell below to visualize the midpoint method. -# -# </p> -# </div> - -# %% -# Midpoint sum visualization -plt.bar(x_values[:-1],[f(x_at_the_middle) for x_at_the_middle in (x_values[:-1]+x_values[1:])/2 ], width=dx, alpha=0.5, align='edge', edgecolor='black', linewidth=0.25) -plt.plot((x_values[:-1]+x_values[1:])/2,[f(x_at_the_middle) for x_at_the_middle in (x_values[:-1]+x_values[1:])/2 ],'*',markersize='16', color='red') -#Plot "continous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Midpoint Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - -# %% [markdown] -# **Trapezoidal Rule** -# -# This method requires two evaluations of the function $f$ for each 'rectangle', at its left and right corners. In fact, it does not represent a 'rectangle anymore' but a trapezoid. For a 1D case, it is a rectangle with a triangle on top. -# -# $$I_{_{trapezoid}} \approx \sum_{i=0}^{n-1}\frac{f(x_i)+f(x_{i+1})}{2}\Delta x $$ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 12:</b> -# -# Complete the following code to implement the trapezoidal rule for the sum. -# -# </p> -# </div> - -# %% -I_trapezoidal = sum([(f(x_values[i]) + f(x_values[i+1])) / 2 * dx for i in range(len(x_values)-1)]) -print(f"Trapezoidal Sum: {I_trapezoidal: 0.5e}") - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 13:</b> -# -# To visualize the trapezoidal method a plt.bar is not used rather plt_fill_between. Revise the code cell below. -# -# </p> -# </div> - -# %% -# Trapezoidal sum -for i in range(len(x_values)-1): - plt.fill_between([x_values[i], x_values[i+1]], - [f(x_values[i]), f(x_values[i+1])], - alpha=0.5) - -#Plot "continous" function -plt.plot(x_high_resolution, f_high_resolution, 'b') -plt.title('Trapezoidal Sum') -plt.xlabel('x') -plt.ylabel('$f(x)$'); - - - -# %% [markdown] -# **Absolute errors in integral** - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 14:</b> -# -# Compute the absolute errors of each method. Are they similar to your expectatations? (i.e. corresponding to the orders of magnitude). -# -# </p> -# </div> - -# %% -# Calculate absolute errors -left_riemann_error = abs(exact_integral_evaluated - I_left_riemann) -right_riemann_error = abs(exact_integral_evaluated - I_right_riemann) -midpoint_error = abs(exact_integral_evaluated - I_midpoint) -trapezoidal_error = abs(exact_integral_evaluated - I_trapezoidal) - -# Print the results -print(f"Left Riemann Error: {left_riemann_error: 0.3e}") -print(f"Right Riemann Error: {right_riemann_error: 0.3e}") -print(f"Midpoint Error: {midpoint_error: 0.3e}") -print(f"Trapezoidal Error: {trapezoidal_error: 0.3e}") - - -# %% [markdown] -# **Simpson's Rule** -# -# Simpson's rule is a method that uses a quadratic approximation over an interval that allows the top bound of the area 'rectangle' to be defined by a polynomial. In general, it can be a better approximation for curved, but mathematically smooth functions. It also has the requirement that subintervals must be an even number, so this is something to be aware of when using it in practise. As a sum, it is defined as -# -# $$\int^{b}_{a}f(x)\mathrm{d}x\approx \sum_{i=1}^{n/2}\frac{1}{3}(f(x_{2i-2})+4f(x_{2i-1})+f(x_{2i}))\Delta x$$ -# -# where $n$ must be an *even integer*. -# -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Challenge</b> -# -# Take what you have seen in the other numerical implementation codes and implement Simpson's Rule for the same integral! A redefinition of x_values is done with 9 points instead of 10 as an uneven number of points is required to apply Simpson's Rule. -# </p> -# </div> - -# %% -# Define Simpson's Rule here -x_values = np.linspace(a, b, 9) -dx = x_values[1]-x_values[0] - -simpson_integral = sum([(f(x_values[2*i-2]) + 4*f(x_values[2*i-1]) + f(x_values[2*i])) / 3 * dx for i in range(1,int(len(x_values)/2)+1)]) - -# Calculate the absolute error -simpson_error = abs(exact_integral_evaluated - simpson_integral) - -# Print the result and error -print(f"Simpson's Rule Integral: {simpson_integral: 0.5e}") -print(f"Simpson's Rule Absolute Error: {simpson_error: 0.5e}") - - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 15:</b> -# -# -# Refine the number of points using the integration by left riemmann until reaching a similar accuracy as for the trapezoidal rule. How much finer was your grid? -# -# </p> -# </div> - -# %% [markdown] -# - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/teachers/Week_1_6/WS_1_6_time_to_c_ode.ipynb b/synced_files/teachers/Week_1_6/WS_1_6_time_to_c_ode.ipynb deleted file mode 100644 index e2c18d9c1476bd3b0250199b3125ea8c44444931..0000000000000000000000000000000000000000 --- a/synced_files/teachers/Week_1_6/WS_1_6_time_to_c_ode.ipynb +++ /dev/null @@ -1,861 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "1d48ad6c", - "metadata": { - "id": "9adbf457-797f-45b7-8f8b-0e46e0e2f5ff" - }, - "source": [ - "# WS 1.6: Understanding Ordinary Differential Equation\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px\" />\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px\" />\n", - "\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.6. For: 9th October, 2024.*" - ] - }, - { - "cell_type": "markdown", - "id": "366ef404", - "metadata": {}, - "source": [ - "## Overview\n", - "\n", - "\n", - "This assignment is aimed to develop an understanding of the **Ordinary Differential Equation (ODE)**. There will be two sections about cooling and heating scenerios, corresponding to the first-order and the second-order ODEs. Please go through the text that follows and perform all steps outlined therein.\n", - "\n", - "## Part 1: First-order ODE\n", - "\n", - "In the study of heat transfer, **Newton's law of cooling** is a physical law which states that the rate of heat loss of a body is directly proportional to the difference in the temperatures between the body and its environment. It can be expressed in the form of ODE, as below:\n", - "\n", - "$$\\frac{dT}{dt}=-k(T - T_s)$$\n", - "\n", - "where $T$ is the temperature of the object at time $t$, $T_s$ is the temperature of the surrounding and assumed to be constant, and $k$ is the constant that characterizes the ability of the object to exchange the\n", - "heat energy (unit 1/s), which depends on the specific material properties.\n", - "\n", - "\n", - "Now, Let's consider an object with the initial temperature of 50°C in a surrounding environment with constant temperature at 20°C. The constant of heat exchange between the object and the environment is 0.5 $s^{-1}$.\n" - ] - }, - { - "cell_type": "markdown", - "id": "73781a3c", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.1:</b>\n", - " \n", - "Suppose the considered period of time is long enough (bring it to steady state), what will be the final temperature of the object? \n", - " \n", - "**Write your answer in the following markdown cell.**\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "3081d88d", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "06320ed9", - "metadata": {}, - "source": [ - "Next, let's evaluate the temperature of the object by checking it at a series of time points." - ] - }, - { - "cell_type": "markdown", - "id": "18cbde20", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.2:</b>\n", - "\n", - "Write the algebraic representation of the ODE using Explicit Euler.\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "bec070a5", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "579a9440", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3:</b>\n", - "\n", - "Compute the temperature evolution in the next 60 seconds.\n", - "\n", - "**Please complete the missing parts of the code in each step below, which is divided into 5 substeps (a through e).**\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "88b861bc", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3a:</b> \n", - "\n", - "The time step of 5 seconds is constant. Discretize the time points, the solution vector $T$ and define the initial condition.\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b44aa057", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "\n", - "dt =YOUR_CODE_HERE \n", - "t_end =YOUR_CODE_HERE \n", - "Ts = 20 # [C] \n", - "k = 0.5 # [s^-1]\n", - "\n", - "t = YOUR_CODE_HERE\n", - "n = YOUR_CODE_HERE\n", - "T = YOUR_CODE_HERE\n", - "T[0] = YOUR_CODE_HERE\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "4586d4b6", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3b:</b> \n", - "\n", - "Implement your time discretization and find the solution from $t=0$ until $t=60$ sec. \n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0bf8247e", - "metadata": {}, - "outputs": [], - "source": [ - "for i in range(n-1):\n", - " T[i+1] = YOUR_CODE_HERE\n", - " \n", - "plt.plot(t, T, 'o-')\n", - "plt.xlabel('t (s)')\n", - "plt.ylabel('T (deg)')\n", - "plt.grid()" - ] - }, - { - "cell_type": "markdown", - "id": "ffb4547f", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3c:</b>\n", - "\n", - "Try different time steps to check the stability of the calculation. At which value the solution is stable?\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "59bcbb0a", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "8a907a09", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3d:</b>\n", - "\n", - "Obtain the mathematical expression that proves your stability criteria.\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "eb00c9ab", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "1ff1e4fe", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3e:</b>\n", - "\n", - "Now, discretize the equation using Implicit (Backward) Euler. Can you find a time step that makes the problem unstable?\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "18c73272", - "metadata": {}, - "outputs": [], - "source": [ - "dt = YOUR_CODE_HERE \n", - "t_end = 60 \n", - "Ts = 20 # [C] \n", - "k = 0.5 # [s^-1]\n", - "\n", - "t = YOUR_CODE_HERE\n", - "n = YOUR_CODE_HERE\n", - "T = YOUR_CODE_HERE\n", - "T[0] = YOUR_CODE_HERE\n", - "\n", - "for i in range(n-1):\n", - " T[i+1] = YOUR_CODE_HERE \n", - " \n", - "plt.plot(t, T, 'o-')\n", - "plt.xlabel('t (s)')\n", - "plt.ylabel('T (deg)')\n", - "plt.grid()" - ] - }, - { - "cell_type": "markdown", - "id": "2109f010", - "metadata": {}, - "source": [ - "## Part 2: Second-order ODE\n", - "\n", - "The following 1D equation describes the steady state solution of the temperature along a pin that sticks out of a furnace. The rest of the pin is exposed to the ambient. \n", - "\n", - "$$\n", - "\\frac{d^2T}{dx^2} -\\alpha(T-T_s)=0\n", - "$$\n", - "\n", - "The ambient temperature is $T_s= 30^o$ C and the temperature at the wall is $250^o$ C. The length of the pin is 0.1m. Your grid should have a spatial step of 0.02 m. Finally, $\\alpha=500$." - ] - }, - { - "cell_type": "markdown", - "id": "5bf9639d", - "metadata": {}, - "source": [ - "\n", - "The solution includes the steps:\n", - "1. Use the Taylor series to obtain an approximation for the derivatives;\n", - "2. Discretize the equation;\n", - "3. Define parameters and grid;\n", - "4. Provide boundary conditions;\n", - "5. Build matrix with solution $AT=b$\n", - "6. Solve the matrix" - ] - }, - { - "cell_type": "markdown", - "id": "babd0424", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.1:</b>\n", - "\n", - "This task has three parts: a) discretize the analytic expression into a system of equations using central differences, b) write the system of equations by hand (e.g., the matrices), and c) implement the discretized system of equations in a code cell.\n", - "\n", - "<em>Parts 2.1b and 2.1c do not need to be completed in order; in fact, it may be useful to go back and forth between the two in order to understand the problem.</em> \n", - " \n" - ] - }, - { - "cell_type": "markdown", - "id": "1f70b8e9", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.1a:</b>\n", - "\n", - "Discretize the analytic expression into a system of equations for a grid with 6 points using central differences.\n", - "\n", - "<em>Write your answer by hand using paper/tablet and include the image below.</em>\n", - " \n" - ] - }, - { - "cell_type": "markdown", - "id": "81a5f165", - "metadata": {}, - "source": [ - "_Your answer here._" - ] - }, - { - "cell_type": "markdown", - "id": "c513ff65", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.1b:</b>\n", - "\n", - "Write the system of equations by hand for a grid with 6 points. In other words, construct the matrix A and vectors T and b.\n", - "\n", - "<em>Write your answer by hand using paper/tablet and include the image below.</em>\n", - " \n" - ] - }, - { - "cell_type": "markdown", - "id": "cb9ff085", - "metadata": {}, - "source": [ - "_Your answer here._" - ] - }, - { - "cell_type": "markdown", - "id": "fae61d18", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.1c:</b>\n", - "\n", - "Implement the discretized system of equations in a code cell.\n", - "\n", - "<em>We have already done this for you! Your task is to read the cell and make sure you understand how the matrices are implemented. Reading the code should help you formulate the matrices in Task 2.1b.</em>\n", - " \n" - ] - }, - { - "cell_type": "markdown", - "id": "89fd190c", - "metadata": {}, - "source": [ - "_Add your image here._" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "53fb4f99", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np \n", - "import matplotlib.pyplot as plt\n", - "\n", - "Ts = 30\n", - "alpha = 500\n", - "dx=0.02\n", - "\n", - "# grid creation\n", - "x = np.arange(0,0.1+dx,dx)\n", - "T = np.zeros(x.shape)\n", - "n=len(x)\n", - "\n", - "# boundary conditions\n", - "T[0] = 250\n", - "T[-1] = Ts\n", - "\n", - "# Building matrix A\n", - "matrix_element = -(2+dx**2*alpha)\n", - "A = np.zeros((len(x)-2,len(x)-2))\n", - "np.fill_diagonal(A, matrix_element)\n", - "A[np.arange(n-3), np.arange(1, n-2)] = 1 # Upper diagonal\n", - "A[np.arange(1, n-2), np.arange(n-3)] = 1 # Lower diagonal\n", - "print(A.shape)\n", - "# Building vector b\n", - "b_element = -dx**2*alpha*Ts\n", - "b = np.zeros(len(x)-2) + b_element\n", - "b[0] = b[0] - T[0]\n", - "b[-1] = b[-1] - T[-1]\n", - "\n", - "# Solving the system\n", - "T[1:-1] = np.linalg.solve(A,b)\n", - "\n", - "plt.plot(x,T,'*',label='Estimated solution')\n", - "plt.xlabel('x')\n", - "plt.ylabel('T')\n", - "plt.title('Estimated solution using Central Difference method')\n", - "plt.legend()\n", - "plt.show()\n", - "\n", - "print(f'The estimated temperature at the nodes are: {[f\"{temp:.2f}\" for temp in T]} [C]')" - ] - }, - { - "cell_type": "markdown", - "id": "fab32745", - "metadata": {}, - "source": [ - "\n", - "\n", - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.2:</b>\n", - "\n", - "This task will adapt the problem from 2.1 to incorporate Neumann boundary conditions in three steps: a) writing the new matrix by hand, b) adapting the code from 2.1c, c) reflecting on what this represents physically.\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "97594dc4", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.2a:</b>\n", - "\n", - "Write the system of equations by hand for a grid with 6 points, incorporating the Neumann condition.\n", - "\n", - "Approximate the Neuman boundary $\\frac{dT}{dx}=0$ by using the Backward difference for first order differential equation of first order accuracy.\n", - "\n", - "<em>Write your answer by hand using paper/tablet and include the image below.</em>\n", - " \n" - ] - }, - { - "cell_type": "markdown", - "id": "82e00391", - "metadata": {}, - "source": [ - "_Your answer here._" - ] - }, - { - "cell_type": "markdown", - "id": "5dbe120c", - "metadata": {}, - "source": [ - "\n", - "\n", - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.2b:</b>\n", - "\n", - "Now adapt the code from Task 2.1c and revise it to incorporate the Neumann boundary condition.\n", - "\n", - "<em>Copy and past the code from 2.1c below, then modify it.</em>\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ac2255d4", - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE" - ] - }, - { - "cell_type": "markdown", - "id": "cf1cd521", - "metadata": {}, - "source": [ - "\n", - "\n", - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.2c:</b>\n", - "\n", - "Reflect on the difference between the problem solved in Task 2.1 in comparison to 2.2. How are we changing the physics of the problem being solved by changing the boundary condition? What does this mean in reality for the temperature distribution in the bar over time?\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "891da8f3", - "metadata": {}, - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cfcd00f9", - "metadata": {}, - "outputs": [], - "source": [ - "Ts = 30\n", - "alpha = 500\n", - "dx=0.02\n", - " \n", - "# grid creation\n", - "x = np.arange(0,0.1+dx,dx)\n", - "T = np.zeros(x.shape)\n", - "n=len(x)\n", - " \n", - "# boundary conditions\n", - "T[0] = 250\n", - " \n", - " \n", - "# Building matrix A\n", - "matrix_element = -(2+dx**2*alpha)\n", - "A = np.zeros((len(x)-2,len(x)-2))\n", - "np.fill_diagonal(A, matrix_element)\n", - "A[np.arange(n-3), np.arange(1, n-2)] = 1 # Upper diagonal\n", - "A[np.arange(1, n-2), np.arange(n-3)] = 1 # Lower diagonal\n", - "print(A.shape)\n", - "A[-1,-1] = -(1+dx**2*alpha) #the matrix changes\n", - " \n", - "# Building vector b\n", - "b_element = -dx**2*alpha*Ts\n", - "b = np.zeros(len(x)-2) + b_element\n", - "b[0] = b[0] - T[0]\n", - "b[-1] = b[-1] #the vector b also changes\n", - " \n", - "# Solving the system\n", - "\n", - "T[1:-1] = np.linalg.solve(A,b)\n", - "T[-1] = T[-2] \n", - "\n", - "plt.plot(x,T,'*',label='Estimated solution')\n", - "plt.xlabel('x')\n", - "plt.ylabel('T')\n", - "plt.title('Estimated solution using Central Difference method')\n", - "plt.legend()\n", - "plt.show()\n", - " \n", - "print(f'The estimated temperature at the nodes are: {[f\"{temp:.2f}\" for temp in T]} [C]')" - ] - }, - { - "cell_type": "markdown", - "id": "57632792", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.3:</b>\n", - "\n", - "Just as we did in Task 2.1, this task has three parts: a) discretize the analytic expression into a system of equations using <b>forward differences</b>, b) write the system of equations by hand (e.g., the matrices), and c) implement the discretized system of equations in a code cell.\n", - "\n", - "Here we focus on <b>Dirichlet</b> conditions again.\n", - "</div> \n" - ] - }, - { - "cell_type": "markdown", - "id": "2d4b9fb9", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.3a:</b>\n", - "\n", - "Discretize the analytic expression into a system of equations for a grid with 6 points using <b>forward differences</b>.\n", - "\n", - "<em>Write your answer by hand using paper/tablet and include the image below.</em>\n", - " \n" - ] - }, - { - "cell_type": "markdown", - "id": "1c5ec2f2", - "metadata": {}, - "source": [ - "_Your answer here._" - ] - }, - { - "cell_type": "markdown", - "id": "361f1638", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.3b:</b>\n", - "\n", - "Write the system of equations by hand for a grid with 6 points. In other words, construct the matrix A and vectors T and b.\n", - "\n", - "<em>Write your answer by hand using paper/tablet and include the image below.</em>\n", - " \n" - ] - }, - { - "cell_type": "markdown", - "id": "047a38d3", - "metadata": {}, - "source": [ - "_Your answer here._" - ] - }, - { - "cell_type": "markdown", - "id": "3996b611", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.3c:</b>\n", - "\n", - "Implement the discretized system of equations in a code cell.\n", - "\n", - "<b>This time we did not do it for you!</b> Copy the code from Task 2.1c and revise it to solve the system of equations using <b>Forward Differences</b>. Keep the Dirichlet conditions.\n", - " \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1e783d3e", - "metadata": {}, - "outputs": [], - "source": [ - "YOUR_CODE_HERE" - ] - }, - { - "cell_type": "markdown", - "id": "bac6bb0f", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.4:</b>\n", - "\n", - "How much finer does your grid has to be in the forward difference implementation to get a similar value at x = 0.02 as in the central difference implementation? Vary your dx.\n", - "\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "dd2ead47", - "metadata": {}, - "source": [ - "_Your answer here._" - ] - }, - { - "cell_type": "markdown", - "id": "031dca37", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px\">\n", - "<p>\n", - "<b>Bonus Task</b> \n", - " \n", - "The matrix inversion using numpy is one way to solve the system, another is the <code>gauss_jordan</code> method, written below, and another one is the sparse matrix-based method in the cell afterwards. Here, we will just have a brief comparison to see how these solvers perform when the matrix is large. Change <code>dx</code> to 0.0002 of the original code that solves the second degree ODE and test the time it takes by each method.\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5f7cdec7", - "metadata": {}, - "outputs": [], - "source": [ - "def gauss_jordan(A, b):\n", - " \"\"\"\n", - " Solves the system of linear equations Ax = b using Gauss-Jordan elimination.\n", - " \n", - " Parameters:\n", - " A (numpy.ndarray): Coefficient matrix (n x n).\n", - " b (numpy.ndarray): Right-hand side vector (n).\n", - " \n", - " Returns:\n", - " numpy.ndarray: Solution vector (x) if the system has a unique solution.\n", - " \"\"\"\n", - " # Form the augmented matrix [A | b]\n", - " A = np.array(A, dtype=float)\n", - " b = np.array(b, dtype=float)\n", - " aug_matrix = np.hstack([A, b.reshape(-1, 1)])\n", - " \n", - " n = len(b) # Number of rows (or variables)\n", - " \n", - " for i in range(n):\n", - " # Partial pivoting to handle zero diagonal elements (optional, but more robust)\n", - " max_row = np.argmax(np.abs(aug_matrix[i:, i])) + i\n", - " if aug_matrix[max_row, i] == 0:\n", - " raise ValueError(\"The matrix is singular and cannot be solved.\")\n", - " if max_row != i:\n", - " aug_matrix[[i, max_row]] = aug_matrix[[max_row, i]]\n", - " \n", - " # Make the diagonal element 1\n", - " aug_matrix[i] = aug_matrix[i] / aug_matrix[i, i]\n", - " \n", - " # Make all other elements in the current column 0\n", - " for j in range(n):\n", - " if j != i:\n", - " aug_matrix[j] -= aug_matrix[j, i] * aug_matrix[i]\n", - " \n", - " # Extract the solution (last column of the augmented matrix)\n", - " return aug_matrix[:, -1]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fbd32c69", - "metadata": {}, - "outputs": [], - "source": [ - "import time\n", - "from scipy.sparse import csc_matrix\n", - "from scipy.sparse.linalg import spsolve\n", - "\n", - "# Inverted matrix solution\n", - "start_time = time.time()\n", - "A_inv = np.linalg.inv(A)\n", - "T[1:-1] = A_inv @ b\n", - "time_used_0 = time.time() - start_time\n", - "print(f\"The time used by direct matrix inversion solution is {time_used_0: 0.3e} sec\")\n", - "assert np.allclose(np.dot(A, T[1:-1]), b), \"Oops! The calculation is wrong..\"\n", - "\n", - "\n", - "# Gauss-jordan solution\n", - "start_time = time.time()\n", - "u1 = gauss_jordan(A, b)\n", - "time_used_1 = time.time() - start_time\n", - "print(f\"The time used by Gauss-jordan solution is {time_used_1: 0.3e} sec\")\n", - "#Check if the solution is correct:\n", - "assert np.allclose(np.dot(A, u1), b), \"Oops! The calculation is wrong..\"\n", - "\n", - "# Solution by a sparse matrix solver \n", - "start_time = time.time()\n", - "A_sparse = csc_matrix(A)# Convert A to a compressed sparse column (CSC) matrix\n", - "u2 = spsolve(A_sparse, b)\n", - "time_used_2 = time.time() - start_time\n", - "print(f\"The time used by the sparse matrix solver is {time_used_2: 0.3e} sec\")\n", - "#Check if the solution is correct:\n", - "assert np.allclose(np.dot(A, u2), b), \"Oops! The calculation is wrong..\"" - ] - }, - { - "cell_type": "markdown", - "id": "2921b3f2", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc-sa/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\"/>\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\"/>\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2023 <a rel=\"MUDE Team\" href=\"https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=65595\">MUDE Teaching Team</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc-sa/4.0/\">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "mude-base", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.4" - }, - "latex_envs": { - "LaTeX_envs_menu_present": true, - "autoclose": false, - "autocomplete": true, - "bibliofile": "biblio.bib", - "cite_by": "apalike", - "current_citInitial": 1, - "eqLabelWithNumbers": true, - "eqNumInitial": 1, - "hotkeys": { - "equation": "Ctrl-E", - "itemize": "Ctrl-I" - }, - "labels_anchors": false, - "latex_user_defs": false, - "report_style_numbering": false, - "user_envs_cfg": false - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/synced_files/teachers/Week_1_6/WS_1_6_time_to_c_ode.md b/synced_files/teachers/Week_1_6/WS_1_6_time_to_c_ode.md deleted file mode 100644 index 9a693687184a0fa895af202d674f9384a145d90d..0000000000000000000000000000000000000000 --- a/synced_files/teachers/Week_1_6/WS_1_6_time_to_c_ode.md +++ /dev/null @@ -1,586 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: mude-base - language: python - name: python3 ---- - -<!-- #region id="9adbf457-797f-45b7-8f8b-0e46e0e2f5ff" --> -# WS 1.6: Understanding Ordinary Differential Equation - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> - -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.6. For: 9th October, 2024.* -<!-- #endregion --> - -<!-- #region --> -## Overview - - -This assignment is aimed to develop an understanding of the **Ordinary Differential Equation (ODE)**. There will be two sections about cooling and heating scenerios, corresponding to the first-order and the second-order ODEs. Please go through the text that follows and perform all steps outlined therein. - -## Part 1: First-order ODE - -In the study of heat transfer, **Newton's law of cooling** is a physical law which states that the rate of heat loss of a body is directly proportional to the difference in the temperatures between the body and its environment. It can be expressed in the form of ODE, as below: - -$$\frac{dT}{dt}=-k(T - T_s)$$ - -where $T$ is the temperature of the object at time $t$, $T_s$ is the temperature of the surrounding and assumed to be constant, and $k$ is the constant that characterizes the ability of the object to exchange the -heat energy (unit 1/s), which depends on the specific material properties. - - -Now, Let's consider an object with the initial temperature of 50°C in a surrounding environment with constant temperature at 20°C. The constant of heat exchange between the object and the environment is 0.5 $s^{-1}$. - -<!-- #endregion --> - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.1:</b> - -Suppose the considered period of time is long enough (bring it to steady state), what will be the final temperature of the object? - -**Write your answer in the following markdown cell.** - -</p> -</div> - - - - - -Next, let's evaluate the temperature of the object by checking it at a series of time points. - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.2:</b> - -Write the algebraic representation of the ODE using Explicit Euler. - -</p> -</div> - - - - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3:</b> - -Compute the temperature evolution in the next 60 seconds. - -**Please complete the missing parts of the code in each step below, which is divided into 5 substeps (a through e).** - -</p> -</div> - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3a:</b> - -The time step of 5 seconds is constant. Discretize the time points, the solution vector $T$ and define the initial condition. - -</p> -</div> - -```python -import numpy as np -import matplotlib.pyplot as plt - -dt =YOUR_CODE_HERE -t_end =YOUR_CODE_HERE -Ts = 20 # [C] -k = 0.5 # [s^-1] - -t = YOUR_CODE_HERE -n = YOUR_CODE_HERE -T = YOUR_CODE_HERE -T[0] = YOUR_CODE_HERE - - -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3b:</b> - -Implement your time discretization and find the solution from $t=0$ until $t=60$ sec. - -</p> -</div> - -```python -for i in range(n-1): - T[i+1] = YOUR_CODE_HERE - -plt.plot(t, T, 'o-') -plt.xlabel('t (s)') -plt.ylabel('T (deg)') -plt.grid() -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3c:</b> - -Try different time steps to check the stability of the calculation. At which value the solution is stable? - -</p> -</div> - - - - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3d:</b> - -Obtain the mathematical expression that proves your stability criteria. - -</p> -</div> - - - - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3e:</b> - -Now, discretize the equation using Implicit (Backward) Euler. Can you find a time step that makes the problem unstable? - -</p> -</div> - -```python -dt = YOUR_CODE_HERE -t_end = 60 -Ts = 20 # [C] -k = 0.5 # [s^-1] - -t = YOUR_CODE_HERE -n = YOUR_CODE_HERE -T = YOUR_CODE_HERE -T[0] = YOUR_CODE_HERE - -for i in range(n-1): - T[i+1] = YOUR_CODE_HERE - -plt.plot(t, T, 'o-') -plt.xlabel('t (s)') -plt.ylabel('T (deg)') -plt.grid() -``` - -## Part 2: Second-order ODE - -The following 1D equation describes the steady state solution of the temperature along a pin that sticks out of a furnace. The rest of the pin is exposed to the ambient. - -$$ -\frac{d^2T}{dx^2} -\alpha(T-T_s)=0 -$$ - -The ambient temperature is $T_s= 30^o$ C and the temperature at the wall is $250^o$ C. The length of the pin is 0.1m. Your grid should have a spatial step of 0.02 m. Finally, $\alpha=500$. - - - -The solution includes the steps: -1. Use the Taylor series to obtain an approximation for the derivatives; -2. Discretize the equation; -3. Define parameters and grid; -4. Provide boundary conditions; -5. Build matrix with solution $AT=b$ -6. Solve the matrix - - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.1:</b> - -This task has three parts: a) discretize the analytic expression into a system of equations using central differences, b) write the system of equations by hand (e.g., the matrices), and c) implement the discretized system of equations in a code cell. - -<em>Parts 2.1b and 2.1c do not need to be completed in order; in fact, it may be useful to go back and forth between the two in order to understand the problem.</em> - - - - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.1a:</b> - -Discretize the analytic expression into a system of equations for a grid with 6 points using central differences. - -<em>Write your answer by hand using paper/tablet and include the image below.</em> - - - - -_Your answer here._ - - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.1b:</b> - -Write the system of equations by hand for a grid with 6 points. In other words, construct the matrix A and vectors T and b. - -<em>Write your answer by hand using paper/tablet and include the image below.</em> - - - - -_Your answer here._ - - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.1c:</b> - -Implement the discretized system of equations in a code cell. - -<em>We have already done this for you! Your task is to read the cell and make sure you understand how the matrices are implemented. Reading the code should help you formulate the matrices in Task 2.1b.</em> - - - - -_Add your image here._ - -```python -import numpy as np -import matplotlib.pyplot as plt - -Ts = 30 -alpha = 500 -dx=0.02 - -# grid creation -x = np.arange(0,0.1+dx,dx) -T = np.zeros(x.shape) -n=len(x) - -# boundary conditions -T[0] = 250 -T[-1] = Ts - -# Building matrix A -matrix_element = -(2+dx**2*alpha) -A = np.zeros((len(x)-2,len(x)-2)) -np.fill_diagonal(A, matrix_element) -A[np.arange(n-3), np.arange(1, n-2)] = 1 # Upper diagonal -A[np.arange(1, n-2), np.arange(n-3)] = 1 # Lower diagonal -print(A.shape) -# Building vector b -b_element = -dx**2*alpha*Ts -b = np.zeros(len(x)-2) + b_element -b[0] = b[0] - T[0] -b[-1] = b[-1] - T[-1] - -# Solving the system -T[1:-1] = np.linalg.solve(A,b) - -plt.plot(x,T,'*',label='Estimated solution') -plt.xlabel('x') -plt.ylabel('T') -plt.title('Estimated solution using Central Difference method') -plt.legend() -plt.show() - -print(f'The estimated temperature at the nodes are: {[f"{temp:.2f}" for temp in T]} [C]') -``` - -<!-- #region --> - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.2:</b> - -This task will adapt the problem from 2.1 to incorporate Neumann boundary conditions in three steps: a) writing the new matrix by hand, b) adapting the code from 2.1c, c) reflecting on what this represents physically. - -</p> -</div> -<!-- #endregion --> - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.2a:</b> - -Write the system of equations by hand for a grid with 6 points, incorporating the Neumann condition. - -Approximate the Neuman boundary $\frac{dT}{dx}=0$ by using the Backward difference for first order differential equation of first order accuracy. - -<em>Write your answer by hand using paper/tablet and include the image below.</em> - - - - -_Your answer here._ - -<!-- #region --> - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.2b:</b> - -Now adapt the code from Task 2.1c and revise it to incorporate the Neumann boundary condition. - -<em>Copy and past the code from 2.1c below, then modify it.</em> - -</p> -</div> -<!-- #endregion --> - -```python -YOUR_CODE_HERE -``` - -<!-- #region --> - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.2c:</b> - -Reflect on the difference between the problem solved in Task 2.1 in comparison to 2.2. How are we changing the physics of the problem being solved by changing the boundary condition? What does this mean in reality for the temperature distribution in the bar over time? - -</p> -</div> -<!-- #endregion --> - - - -```python -Ts = 30 -alpha = 500 -dx=0.02 - -# grid creation -x = np.arange(0,0.1+dx,dx) -T = np.zeros(x.shape) -n=len(x) - -# boundary conditions -T[0] = 250 - - -# Building matrix A -matrix_element = -(2+dx**2*alpha) -A = np.zeros((len(x)-2,len(x)-2)) -np.fill_diagonal(A, matrix_element) -A[np.arange(n-3), np.arange(1, n-2)] = 1 # Upper diagonal -A[np.arange(1, n-2), np.arange(n-3)] = 1 # Lower diagonal -print(A.shape) -A[-1,-1] = -(1+dx**2*alpha) #the matrix changes - -# Building vector b -b_element = -dx**2*alpha*Ts -b = np.zeros(len(x)-2) + b_element -b[0] = b[0] - T[0] -b[-1] = b[-1] #the vector b also changes - -# Solving the system - -T[1:-1] = np.linalg.solve(A,b) -T[-1] = T[-2] - -plt.plot(x,T,'*',label='Estimated solution') -plt.xlabel('x') -plt.ylabel('T') -plt.title('Estimated solution using Central Difference method') -plt.legend() -plt.show() - -print(f'The estimated temperature at the nodes are: {[f"{temp:.2f}" for temp in T]} [C]') -``` - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.3:</b> - -Just as we did in Task 2.1, this task has three parts: a) discretize the analytic expression into a system of equations using <b>forward differences</b>, b) write the system of equations by hand (e.g., the matrices), and c) implement the discretized system of equations in a code cell. - -Here we focus on <b>Dirichlet</b> conditions again. -</div> - - - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.3a:</b> - -Discretize the analytic expression into a system of equations for a grid with 6 points using <b>forward differences</b>. - -<em>Write your answer by hand using paper/tablet and include the image below.</em> - - - - -_Your answer here._ - - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.3b:</b> - -Write the system of equations by hand for a grid with 6 points. In other words, construct the matrix A and vectors T and b. - -<em>Write your answer by hand using paper/tablet and include the image below.</em> - - - - -_Your answer here._ - - -<div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.3c:</b> - -Implement the discretized system of equations in a code cell. - -<b>This time we did not do it for you!</b> Copy the code from Task 2.1c and revise it to solve the system of equations using <b>Forward Differences</b>. Keep the Dirichlet conditions. - - - -```python -YOUR_CODE_HERE -``` - -<!-- #region --> -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.4:</b> - -How much finer does your grid has to be in the forward difference implementation to get a similar value at x = 0.02 as in the central difference implementation? Vary your dx. - - -</p> -</div> -<!-- #endregion --> - -_Your answer here._ - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -<p> -<b>Bonus Task</b> - -The matrix inversion using numpy is one way to solve the system, another is the <code>gauss_jordan</code> method, written below, and another one is the sparse matrix-based method in the cell afterwards. Here, we will just have a brief comparison to see how these solvers perform when the matrix is large. Change <code>dx</code> to 0.0002 of the original code that solves the second degree ODE and test the time it takes by each method. - -</p> -</div> - -```python -def gauss_jordan(A, b): - """ - Solves the system of linear equations Ax = b using Gauss-Jordan elimination. - - Parameters: - A (numpy.ndarray): Coefficient matrix (n x n). - b (numpy.ndarray): Right-hand side vector (n). - - Returns: - numpy.ndarray: Solution vector (x) if the system has a unique solution. - """ - # Form the augmented matrix [A | b] - A = np.array(A, dtype=float) - b = np.array(b, dtype=float) - aug_matrix = np.hstack([A, b.reshape(-1, 1)]) - - n = len(b) # Number of rows (or variables) - - for i in range(n): - # Partial pivoting to handle zero diagonal elements (optional, but more robust) - max_row = np.argmax(np.abs(aug_matrix[i:, i])) + i - if aug_matrix[max_row, i] == 0: - raise ValueError("The matrix is singular and cannot be solved.") - if max_row != i: - aug_matrix[[i, max_row]] = aug_matrix[[max_row, i]] - - # Make the diagonal element 1 - aug_matrix[i] = aug_matrix[i] / aug_matrix[i, i] - - # Make all other elements in the current column 0 - for j in range(n): - if j != i: - aug_matrix[j] -= aug_matrix[j, i] * aug_matrix[i] - - # Extract the solution (last column of the augmented matrix) - return aug_matrix[:, -1] -``` - -```python -import time -from scipy.sparse import csc_matrix -from scipy.sparse.linalg import spsolve - -# Inverted matrix solution -start_time = time.time() -A_inv = np.linalg.inv(A) -T[1:-1] = A_inv @ b -time_used_0 = time.time() - start_time -print(f"The time used by direct matrix inversion solution is {time_used_0: 0.3e} sec") -assert np.allclose(np.dot(A, T[1:-1]), b), "Oops! The calculation is wrong.." - - -# Gauss-jordan solution -start_time = time.time() -u1 = gauss_jordan(A, b) -time_used_1 = time.time() - start_time -print(f"The time used by Gauss-jordan solution is {time_used_1: 0.3e} sec") -#Check if the solution is correct: -assert np.allclose(np.dot(A, u1), b), "Oops! The calculation is wrong.." - -# Solution by a sparse matrix solver -start_time = time.time() -A_sparse = csc_matrix(A)# Convert A to a compressed sparse column (CSC) matrix -u2 = spsolve(A_sparse, b) -time_used_2 = time.time() - start_time -print(f"The time used by the sparse matrix solver is {time_used_2: 0.3e} sec") -#Check if the solution is correct: -assert np.allclose(np.dot(A, u2), b), "Oops! The calculation is wrong.." -``` - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png"/> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png"/> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2023 <a rel="MUDE Team" href="https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=65595">MUDE Teaching Team</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>. diff --git a/synced_files/teachers/Week_1_6/WS_1_6_time_to_c_ode.py b/synced_files/teachers/Week_1_6/WS_1_6_time_to_c_ode.py deleted file mode 100644 index d057f05ea93d762304329617da61037001aedeb3..0000000000000000000000000000000000000000 --- a/synced_files/teachers/Week_1_6/WS_1_6_time_to_c_ode.py +++ /dev/null @@ -1,582 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: mude-base -# language: python -# name: python3 -# --- - -# %% [markdown] id="9adbf457-797f-45b7-8f8b-0e46e0e2f5ff" -# # WS 1.6: Understanding Ordinary Differential Equation -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -# -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.6. For: 9th October, 2024.* - -# %% [markdown] -# ## Overview -# -# -# This assignment is aimed to develop an understanding of the **Ordinary Differential Equation (ODE)**. There will be two sections about cooling and heating scenerios, corresponding to the first-order and the second-order ODEs. Please go through the text that follows and perform all steps outlined therein. -# -# ## Part 1: First-order ODE -# -# In the study of heat transfer, **Newton's law of cooling** is a physical law which states that the rate of heat loss of a body is directly proportional to the difference in the temperatures between the body and its environment. It can be expressed in the form of ODE, as below: -# -# $$\frac{dT}{dt}=-k(T - T_s)$$ -# -# where $T$ is the temperature of the object at time $t$, $T_s$ is the temperature of the surrounding and assumed to be constant, and $k$ is the constant that characterizes the ability of the object to exchange the -# heat energy (unit 1/s), which depends on the specific material properties. -# -# -# Now, Let's consider an object with the initial temperature of 50°C in a surrounding environment with constant temperature at 20°C. The constant of heat exchange between the object and the environment is 0.5 $s^{-1}$. -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.1:</b> -# -# Suppose the considered period of time is long enough (bring it to steady state), what will be the final temperature of the object? -# -# **Write your answer in the following markdown cell.** -# -# </p> -# </div> - -# %% [markdown] -# - -# %% [markdown] -# Next, let's evaluate the temperature of the object by checking it at a series of time points. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.2:</b> -# -# Write the algebraic representation of the ODE using Explicit Euler. -# -# </p> -# </div> - -# %% [markdown] -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3:</b> -# -# Compute the temperature evolution in the next 60 seconds. -# -# **Please complete the missing parts of the code in each step below, which is divided into 5 substeps (a through e).** -# -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3a:</b> -# -# The time step of 5 seconds is constant. Discretize the time points, the solution vector $T$ and define the initial condition. -# -# </p> -# </div> - -# %% -import numpy as np -import matplotlib.pyplot as plt - -dt =YOUR_CODE_HERE -t_end =YOUR_CODE_HERE -Ts = 20 # [C] -k = 0.5 # [s^-1] - -t = YOUR_CODE_HERE -n = YOUR_CODE_HERE -T = YOUR_CODE_HERE -T[0] = YOUR_CODE_HERE - - - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3b:</b> -# -# Implement your time discretization and find the solution from $t=0$ until $t=60$ sec. -# -# </p> -# </div> - -# %% -for i in range(n-1): - T[i+1] = YOUR_CODE_HERE - -plt.plot(t, T, 'o-') -plt.xlabel('t (s)') -plt.ylabel('T (deg)') -plt.grid() - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3c:</b> -# -# Try different time steps to check the stability of the calculation. At which value the solution is stable? -# -# </p> -# </div> - -# %% [markdown] -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3d:</b> -# -# Obtain the mathematical expression that proves your stability criteria. -# -# </p> -# </div> - -# %% [markdown] -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3e:</b> -# -# Now, discretize the equation using Implicit (Backward) Euler. Can you find a time step that makes the problem unstable? -# -# </p> -# </div> - -# %% -dt = YOUR_CODE_HERE -t_end = 60 -Ts = 20 # [C] -k = 0.5 # [s^-1] - -t = YOUR_CODE_HERE -n = YOUR_CODE_HERE -T = YOUR_CODE_HERE -T[0] = YOUR_CODE_HERE - -for i in range(n-1): - T[i+1] = YOUR_CODE_HERE - -plt.plot(t, T, 'o-') -plt.xlabel('t (s)') -plt.ylabel('T (deg)') -plt.grid() - -# %% [markdown] -# ## Part 2: Second-order ODE -# -# The following 1D equation describes the steady state solution of the temperature along a pin that sticks out of a furnace. The rest of the pin is exposed to the ambient. -# -# $$ -# \frac{d^2T}{dx^2} -\alpha(T-T_s)=0 -# $$ -# -# The ambient temperature is $T_s= 30^o$ C and the temperature at the wall is $250^o$ C. The length of the pin is 0.1m. Your grid should have a spatial step of 0.02 m. Finally, $\alpha=500$. - -# %% [markdown] -# -# The solution includes the steps: -# 1. Use the Taylor series to obtain an approximation for the derivatives; -# 2. Discretize the equation; -# 3. Define parameters and grid; -# 4. Provide boundary conditions; -# 5. Build matrix with solution $AT=b$ -# 6. Solve the matrix - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.1:</b> -# -# This task has three parts: a) discretize the analytic expression into a system of equations using central differences, b) write the system of equations by hand (e.g., the matrices), and c) implement the discretized system of equations in a code cell. -# -# <em>Parts 2.1b and 2.1c do not need to be completed in order; in fact, it may be useful to go back and forth between the two in order to understand the problem.</em> -# -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.1a:</b> -# -# Discretize the analytic expression into a system of equations for a grid with 6 points using central differences. -# -# <em>Write your answer by hand using paper/tablet and include the image below.</em> -# -# - -# %% [markdown] -# _Your answer here._ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.1b:</b> -# -# Write the system of equations by hand for a grid with 6 points. In other words, construct the matrix A and vectors T and b. -# -# <em>Write your answer by hand using paper/tablet and include the image below.</em> -# -# - -# %% [markdown] -# _Your answer here._ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.1c:</b> -# -# Implement the discretized system of equations in a code cell. -# -# <em>We have already done this for you! Your task is to read the cell and make sure you understand how the matrices are implemented. Reading the code should help you formulate the matrices in Task 2.1b.</em> -# -# - -# %% [markdown] -# _Add your image here._ - -# %% -import numpy as np -import matplotlib.pyplot as plt - -Ts = 30 -alpha = 500 -dx=0.02 - -# grid creation -x = np.arange(0,0.1+dx,dx) -T = np.zeros(x.shape) -n=len(x) - -# boundary conditions -T[0] = 250 -T[-1] = Ts - -# Building matrix A -matrix_element = -(2+dx**2*alpha) -A = np.zeros((len(x)-2,len(x)-2)) -np.fill_diagonal(A, matrix_element) -A[np.arange(n-3), np.arange(1, n-2)] = 1 # Upper diagonal -A[np.arange(1, n-2), np.arange(n-3)] = 1 # Lower diagonal -print(A.shape) -# Building vector b -b_element = -dx**2*alpha*Ts -b = np.zeros(len(x)-2) + b_element -b[0] = b[0] - T[0] -b[-1] = b[-1] - T[-1] - -# Solving the system -T[1:-1] = np.linalg.solve(A,b) - -plt.plot(x,T,'*',label='Estimated solution') -plt.xlabel('x') -plt.ylabel('T') -plt.title('Estimated solution using Central Difference method') -plt.legend() -plt.show() - -print(f'The estimated temperature at the nodes are: {[f"{temp:.2f}" for temp in T]} [C]') - -# %% [markdown] -# -# -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.2:</b> -# -# This task will adapt the problem from 2.1 to incorporate Neumann boundary conditions in three steps: a) writing the new matrix by hand, b) adapting the code from 2.1c, c) reflecting on what this represents physically. -# -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.2a:</b> -# -# Write the system of equations by hand for a grid with 6 points, incorporating the Neumann condition. -# -# Approximate the Neuman boundary $\frac{dT}{dx}=0$ by using the Backward difference for first order differential equation of first order accuracy. -# -# <em>Write your answer by hand using paper/tablet and include the image below.</em> -# -# - -# %% [markdown] -# _Your answer here._ - -# %% [markdown] -# -# -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.2b:</b> -# -# Now adapt the code from Task 2.1c and revise it to incorporate the Neumann boundary condition. -# -# <em>Copy and past the code from 2.1c below, then modify it.</em> -# -# </p> -# </div> - -# %% -YOUR_CODE_HERE - -# %% [markdown] -# -# -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.2c:</b> -# -# Reflect on the difference between the problem solved in Task 2.1 in comparison to 2.2. How are we changing the physics of the problem being solved by changing the boundary condition? What does this mean in reality for the temperature distribution in the bar over time? -# -# </p> -# </div> - -# %% [markdown] -# - -# %% -Ts = 30 -alpha = 500 -dx=0.02 - -# grid creation -x = np.arange(0,0.1+dx,dx) -T = np.zeros(x.shape) -n=len(x) - -# boundary conditions -T[0] = 250 - - -# Building matrix A -matrix_element = -(2+dx**2*alpha) -A = np.zeros((len(x)-2,len(x)-2)) -np.fill_diagonal(A, matrix_element) -A[np.arange(n-3), np.arange(1, n-2)] = 1 # Upper diagonal -A[np.arange(1, n-2), np.arange(n-3)] = 1 # Lower diagonal -print(A.shape) -A[-1,-1] = -(1+dx**2*alpha) #the matrix changes - -# Building vector b -b_element = -dx**2*alpha*Ts -b = np.zeros(len(x)-2) + b_element -b[0] = b[0] - T[0] -b[-1] = b[-1] #the vector b also changes - -# Solving the system - -T[1:-1] = np.linalg.solve(A,b) -T[-1] = T[-2] - -plt.plot(x,T,'*',label='Estimated solution') -plt.xlabel('x') -plt.ylabel('T') -plt.title('Estimated solution using Central Difference method') -plt.legend() -plt.show() - -print(f'The estimated temperature at the nodes are: {[f"{temp:.2f}" for temp in T]} [C]') - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.3:</b> -# -# Just as we did in Task 2.1, this task has three parts: a) discretize the analytic expression into a system of equations using <b>forward differences</b>, b) write the system of equations by hand (e.g., the matrices), and c) implement the discretized system of equations in a code cell. -# -# Here we focus on <b>Dirichlet</b> conditions again. -# </div> -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.3a:</b> -# -# Discretize the analytic expression into a system of equations for a grid with 6 points using <b>forward differences</b>. -# -# <em>Write your answer by hand using paper/tablet and include the image below.</em> -# -# - -# %% [markdown] -# _Your answer here._ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.3b:</b> -# -# Write the system of equations by hand for a grid with 6 points. In other words, construct the matrix A and vectors T and b. -# -# <em>Write your answer by hand using paper/tablet and include the image below.</em> -# -# - -# %% [markdown] -# _Your answer here._ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%;vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.3c:</b> -# -# Implement the discretized system of equations in a code cell. -# -# <b>This time we did not do it for you!</b> Copy the code from Task 2.1c and revise it to solve the system of equations using <b>Forward Differences</b>. Keep the Dirichlet conditions. -# -# - -# %% -YOUR_CODE_HERE - - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.4:</b> -# -# How much finer does your grid has to be in the forward difference implementation to get a similar value at x = 0.02 as in the central difference implementation? Vary your dx. -# -# -# </p> -# </div> - -# %% [markdown] -# _Your answer here._ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; width:95%; border-radius: 10px"> -# <p> -# <b>Bonus Task</b> -# -# The matrix inversion using numpy is one way to solve the system, another is the <code>gauss_jordan</code> method, written below, and another one is the sparse matrix-based method in the cell afterwards. Here, we will just have a brief comparison to see how these solvers perform when the matrix is large. Change <code>dx</code> to 0.0002 of the original code that solves the second degree ODE and test the time it takes by each method. -# -# </p> -# </div> - -# %% -def gauss_jordan(A, b): - """ - Solves the system of linear equations Ax = b using Gauss-Jordan elimination. - - Parameters: - A (numpy.ndarray): Coefficient matrix (n x n). - b (numpy.ndarray): Right-hand side vector (n). - - Returns: - numpy.ndarray: Solution vector (x) if the system has a unique solution. - """ - # Form the augmented matrix [A | b] - A = np.array(A, dtype=float) - b = np.array(b, dtype=float) - aug_matrix = np.hstack([A, b.reshape(-1, 1)]) - - n = len(b) # Number of rows (or variables) - - for i in range(n): - # Partial pivoting to handle zero diagonal elements (optional, but more robust) - max_row = np.argmax(np.abs(aug_matrix[i:, i])) + i - if aug_matrix[max_row, i] == 0: - raise ValueError("The matrix is singular and cannot be solved.") - if max_row != i: - aug_matrix[[i, max_row]] = aug_matrix[[max_row, i]] - - # Make the diagonal element 1 - aug_matrix[i] = aug_matrix[i] / aug_matrix[i, i] - - # Make all other elements in the current column 0 - for j in range(n): - if j != i: - aug_matrix[j] -= aug_matrix[j, i] * aug_matrix[i] - - # Extract the solution (last column of the augmented matrix) - return aug_matrix[:, -1] - - -# %% -import time -from scipy.sparse import csc_matrix -from scipy.sparse.linalg import spsolve - -# Inverted matrix solution -start_time = time.time() -A_inv = np.linalg.inv(A) -T[1:-1] = A_inv @ b -time_used_0 = time.time() - start_time -print(f"The time used by direct matrix inversion solution is {time_used_0: 0.3e} sec") -assert np.allclose(np.dot(A, T[1:-1]), b), "Oops! The calculation is wrong.." - - -# Gauss-jordan solution -start_time = time.time() -u1 = gauss_jordan(A, b) -time_used_1 = time.time() - start_time -print(f"The time used by Gauss-jordan solution is {time_used_1: 0.3e} sec") -#Check if the solution is correct: -assert np.allclose(np.dot(A, u1), b), "Oops! The calculation is wrong.." - -# Solution by a sparse matrix solver -start_time = time.time() -A_sparse = csc_matrix(A)# Convert A to a compressed sparse column (CSC) matrix -u2 = spsolve(A_sparse, b) -time_used_2 = time.time() - start_time -print(f"The time used by the sparse matrix solver is {time_used_2: 0.3e} sec") -#Check if the solution is correct: -assert np.allclose(np.dot(A, u2), b), "Oops! The calculation is wrong.." - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png"/> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png"/> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2023 <a rel="MUDE Team" href="https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=65595">MUDE Teaching Team</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>. diff --git a/synced_files/test/Analysis_Solution.ipynb b/synced_files/test/Analysis_Solution.ipynb deleted file mode 100644 index 19f82586fc64efd2c2a7a775040f4f595f085b08..0000000000000000000000000000000000000000 --- a/synced_files/test/Analysis_Solution.ipynb +++ /dev/null @@ -1,1483 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "785b4e1d", - "metadata": {}, - "source": [ - "# GA 1.3: Modelling Road Deformation using Non-Linear Least-Squares test!\n", - "\n", - "<h1 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" style=\"width:100px\" />\n", - " <img src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" style=\"width:100px\" />\n", - "</h1>\n", - "<h2 style=\"height: 10px\">\n", - "</h2>\n", - "\n", - "*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.3. Due: Friday, September 20, 2024.*" - ] - }, - { - "cell_type": "markdown", - "id": "4ad8b9cb", - "metadata": {}, - "source": [ - "<div style=\"background-color:#ffa6a6; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%\"><p><b>Note:</b> don't forget to read the \"Assignment Context\" section of the README, it contains important information to understand this analysis.</p></div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "181ccfd5", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "from scipy import interpolate\n", - "from scipy.stats import norm\n", - "import pandas as pd\n", - "import matplotlib.pyplot as plt\n", - "\n", - "\n", - "from functions import *\n", - "\n", - "np.set_printoptions(precision=3)" - ] - }, - { - "cell_type": "markdown", - "id": "5ca94e0e", - "metadata": {}, - "source": [ - "## Part 0: Dictionary Review\n", - "\n", - "As described above, several functions in this assignment require the use of a Python dictionary to make it easier to keep track of important data, variables and results for the various _models_ we will be constructing and validating.\n", - "\n", - "_It may be useful to revisit PA 1.1, where there was a brief infroduction to dictionaires. That PA contains all the dictionary info you need for GA 1.3. A [read-only copy is here](https://mude.citg.tudelft.nl/2024/files/Week_1_1/PA_1_1_Catch_Them_All.html) and [the source code (notebook) is here](https://gitlab.tudelft.nl/mude/2024-week-1-1)._" - ] - }, - { - "cell_type": "markdown", - "id": "d8c39791", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Task 0.1}$ \n", - " \n", - "Read and run the cell below to make sure you remember how to use a dictionary.\n", - "\n", - "Modify the function to print some of the other key-value pairs of the dictionary.\n", - "\n", - "<em>It may also be useful to use the cell below when working on later tasks in this assignment.</em>\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8683b5ed", - "metadata": {}, - "outputs": [], - "source": [ - "my_dictionary = {'key1': 'value1',\n", - " 'key2': 'value2',\n", - " 'name': 'Dictionary Example',\n", - " 'a_list': [1, 2, 3],\n", - " 'an_array': np.array([1, 2, 3]),\n", - " 'a_string': 'hello'\n", - " }\n", - "\n", - "def function_that_uses_my_dictionary(d):\n", - " print(d['key1'])\n", - "\n", - " # SOLUTION:\n", - " print(d['name'])\n", - " print(d['a_list'])\n", - " print(d['an_array'])\n", - " print(d['a_string'])\n", - "\n", - " if 'new_key' in d:\n", - " print('new_key exists and has value:', d['new_key'])\n", - " return\n", - "\n", - "function_that_uses_my_dictionary(my_dictionary)" - ] - }, - { - "cell_type": "markdown", - "id": "86bc7f97", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Task 0.2}$ \n", - "\n", - "Test your knowledge by adding a new key <code>new_key</code> and then executing the function to print the value.\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "41c56f43", - "metadata": {}, - "outputs": [], - "source": [ - "# YOUR_CODE_HERE\n", - "# function_that_uses_my_dictionary(my_dictionary)\n", - "\n", - "# SOLUTION:\n", - "my_dictionary['new_key'] = 'new_value'\n", - "function_that_uses_my_dictionary(my_dictionary)" - ] - }, - { - "cell_type": "markdown", - "id": "160d6250", - "metadata": { - "id": "160d6250" - }, - "source": [ - "## Task 1: Preparing the data\n", - "\n", - "Within this assignment you will work with two types of data: InSAR data and GNSS data. The cell below will load the data and visualize the observed displacements time. In this task we use the package `pandas`, which is really useful for handling time series. We will learn how to use it later in the quarter; for now, you only need to recognize that it imports the data as a `dataframe` object, which we then convert into a numpy array using the code below." - ] - }, - { - "cell_type": "markdown", - "id": "02b12781", - "metadata": {}, - "source": [ - "<div style=\"background-color:#facb8e; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\"> <p>Tip: note that we have converted all observations to millimeters.</p></div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1f28eba3", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "gnss = pd.read_csv('./data/gnss_observations.csv')\n", - "times_gnss = pd.to_datetime(gnss['times'])\n", - "y_gnss = (gnss['observations[m]']).to_numpy()*1000\n", - "\n", - "insar = pd.read_csv('./data/insar_observations.csv')\n", - "times_insar = pd.to_datetime(insar['times'])\n", - "y_insar = (insar['observations[m]']).to_numpy()*1000\n", - "\n", - "gw = pd.read_csv('./data/groundwater_levels.csv')\n", - "times_gw = pd.to_datetime(gw['times'])\n", - "y_gw = (gw['observations[mm]']).to_numpy()" - ] - }, - { - "cell_type": "markdown", - "id": "aa8906a9-2ebe-4432-b4f3-8bf074d6b181", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.1:</b> \n", - " \n", - "Once you have used the cell above to import the data, investigate the data sets using the code cell below. Then provide some relevant summary information in the Markdown cell.\n", - "\n", - "<em>Hint: at the least, you should be able to tell how many data points are in each data set and get an understanding of the mean and standard deviation of each. Make sure you compare the different datasets and use consistent units.</em>\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "12321724-dc58-42ee-9bd5-44265d3bc921", - "metadata": { - "id": "0491cc69" - }, - "source": [ - "<div style=\"background-color:#facb8e; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\"> <p>The code below gives some examples of the quantitative and qualitative ways you could have looked at the data. It is more than you were expected to do; the important thing is that you showed the ability to learn something about the data and describe aspects that are relevant to our problem. We use a dictionary to easily access the different data series using their names, which are entered as the dictionary keys (also not expected of you, but it's hopefully fun to learn useful tricks).</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9f025cfc-4f89-492d-ac26-f5b6381d0c70", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# YOUR_CODE_HERE\n", - "\n", - "# SOLUTION:\n", - "data_list = ['y_gnss', 'y_insar', 'y_gw']\n", - "data_dict = {data_list[0]: y_gnss,\n", - " data_list[1]: y_insar,\n", - " data_list[2]: y_gw}\n", - "def print_summary(data):\n", - " '''Summarize an array with simple print statements.'''\n", - " print('Minimum = ', data.min())\n", - " print('Maximum = ', data.max())\n", - " print('Mean = ', data.mean())\n", - " print('Std dev = ', data.std())\n", - " print('Shape = ', data.shape)\n", - " print('First value = ', data[0])\n", - " print('Last value = ', data[-1])\n", - " print('\\n')\n", - " \n", - "for item in data_list:\n", - " print('Summary for array: ', item)\n", - " print('------------------------------------------------')\n", - " print_summary(data_dict[item])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "71cf2133-37a6-4536-82a6-42a46b8a1c66", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# SOLUTION:\n", - "times_dict = {data_list[0]: times_gnss,\n", - " data_list[1]: times_insar,\n", - " data_list[2]: times_gw}\n", - "def plot_data(times, data, label):\n", - " plt.figure(figsize=(15,4))\n", - " plt.plot(times, data, 'co', mec='black')\n", - " plt.title(label)\n", - " plt.xlabel('Times')\n", - " plt.ylabel('Data [mm]')\n", - " plt.show()\n", - "\n", - "plt.figure(figsize=(15,4))\n", - "for i in range(3):\n", - " plot_data(times_dict[data_list[i]],\n", - " data_dict[data_list[i]],\n", - " data_list[i])" - ] - }, - { - "cell_type": "markdown", - "id": "a9c02e8f-81f9-41a3-b894-c23dd9617207", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Solution}$ \n", - " \n", - "There are a lot more GNSS data points than InSAR or groundwater. The GNSS observations also have more noise, and what seem to be outliers. In this case the mean and standard deviation do not mean much, because there is clearly a trend with time. We can at least confirm that the time periods of measurements overlap, although the intervals between measurements is certainly not uniform (note that you don't need to do anything with the times, since they are pandas time series and we have not covered them yet).\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "9fe5a729", - "metadata": {}, - "source": [ - "You may have noticed that the groundwater data is available for different times than the GNSS and InSAR data. You will therefore have to *interpolate* the data to the same times for a further analysis. You can use the SciPy function ```interpolate.interp1d``` (read its [documentation](https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html)).\n", - "\n", - "The cells below do the following:\n", - "1. Define a function to convert the time unit\n", - "2. Convert the time stamps for all data\n", - "3. Use `interp1d` to interpolate the groundwater measurements at the time of the satellite measurements" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f02ed4c4", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "def to_days_years(times):\n", - " '''Convert the observation times to days and years.'''\n", - " \n", - " times_datetime = pd.to_datetime(times)\n", - " time_diff = (times_datetime - times_datetime[0])\n", - " days_diff = (time_diff / np.timedelta64(1,'D')).astype(int)\n", - " \n", - " days = days_diff.to_numpy()\n", - " years = days/365\n", - " \n", - " return days, years" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "edf14892", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "days_gnss, years_gnss = to_days_years(times_gnss)\n", - "days_insar, years_insar = to_days_years(times_insar)\n", - "days_gw, years_gw = to_days_years(times_gw)\n", - "\n", - "interp = interpolate.interp1d(days_gw, y_gw)\n", - "\n", - "GW_at_GNSS_times = interp(days_gnss)\n", - "GW_at_InSAR_times = interp(days_insar)" - ] - }, - { - "cell_type": "markdown", - "id": "16827704-4fc5-4afb-879e-0ceeac45eb18", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.2:</b> \n", - " \n", - "Answer/complete the code and Markdown cells below:\n", - "<ol>\n", - " <li>What is <code>interp</code>? (what kind of object is it, and how does it work?)</li>\n", - " <li>How did the groundwater observation array change? Be quantitative. </li>\n", - "</ol>\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6cdfb46b-1324-4c2b-8148-5a6a102ede2e", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# YOUR_CODE_HERE\n", - "\n", - "# SOLUTION:\n", - "print('array size of GW_at_GNSS_times', len(GW_at_GNSS_times))\n", - "print('array size of GW_at_InSAR_times', len(GW_at_InSAR_times))\n", - "print('array size of GW before interpolation', len(y_gw))\n", - "\n", - "print('\\nFirst values of times_gw:')\n", - "print(times_gw[0:2])\n", - "print('\\nFirst values of y_gw:')\n", - "print(y_gw[0:2])\n", - "print('\\nFirst values of times_gnss:')\n", - "print(times_gnss[0:2])\n", - "print('\\nFirst values of GW_at_GNSS_times:')\n", - "print(GW_at_GNSS_times[0:2])" - ] - }, - { - "cell_type": "markdown", - "id": "3b8c68eb-9774-4c3c-91da-f29f035b178c", - "metadata": {}, - "source": [ - "**Write your answer in this Markdown cell.**" - ] - }, - { - "cell_type": "markdown", - "id": "dcc0e2a3-3f34-4bde-af54-37923cb803cd", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Solution}$\n", - "<ol>\n", - " <li><code>interp</code> is a function that will return a value (gw level) for the input(s) (date(s)). The interpolated value is found by linearly interpolating between the two nearest times in the gw observations.</li>\n", - " <li>The observation arrays of <code>GW_at_GNSS_times</code> and <code>GW_at_INSAR_times</code> changed in size to match the size of the GNSS and InSAR observations, respectively.</li>\n", - "</ol> \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "349ebd38-d9e1-49b4-b6bd-f5dc399727e0", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.3:</b> \n", - " \n", - "Create a single plot to compare observed displacement for the GNSS and InSAR data sets.\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e868e488", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# plt.figure(figsize=(15,5))\n", - "# plt.plot(YOUR_CODE_HERE, YOUR_CODE_HERE,\n", - "# 'o', mec='black', label = 'GNSS')\n", - "# plt.plot(YOUR_CODE_HERE, YOUR_CODE_HERE,\n", - "# 'o', mec='black', label = 'InSAR')\n", - "# plt.legend()\n", - "# plt.ylabel('Displacement [mm]')\n", - "# plt.xlabel('Time')\n", - "# plt.show()\n", - "\n", - "# SOLUTION:\n", - "plt.figure(figsize=(15,5))\n", - "plt.plot(times_gnss, y_gnss, 'o', mec='black', label = 'GNSS')\n", - "plt.plot(times_insar, y_insar, 'o', mec='black', label = 'InSAR')\n", - "plt.legend()\n", - "plt.ylabel('Displacement [mm]')\n", - "plt.xlabel('Time')\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "c9b45b8e", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.4:</b> \n", - "Describe the datasets based on the figure above and your observations from the previous tasks. What kind of deformation do you see? And what are the differences between both datasets? Be quantitative.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "48bae179", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Solution}$ \n", - " \n", - "The points obviously show subsidence, the displacement shows a similar pattern for both datasets. The GNSS data is much noisier than InSAR (range is around 60 mm versus only a few mm), but has a higher sampling rate. Also there seem to be more outliers in the GNSS data compared to InSAR, especially at the start of the observation period. InSAR has only observations every 6 days but is less noisy. \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "f9a7bdd4", - "metadata": {}, - "source": [ - "Before we move on, it is time to do a little bit of housekeeping.\n", - "\n", - "Have you found it confusing to keep track of two sets of variables---one for each data type? Let's use a dictionary to store relevant information about each model. We will use this in the plotting functions for this task (and again next week), so make sure you take the time to see what is happening. Review also Part 0 at the top of this notebook if you need a refresher on dictionaries." - ] - }, - { - "cell_type": "markdown", - "id": "cdcf20f7", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 1.5:</b> \n", - " \n", - "Run the cell below to define a dictionary for storing information about the two (future) models.\n", - "\n", - "</p>\n", - "</div>\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2c27b4f3", - "metadata": {}, - "outputs": [], - "source": [ - "model_insar = {'data_type': 'InSAR',\n", - " 'y':y_insar,\n", - " 'times':times_insar,\n", - " 'groundwater': GW_at_InSAR_times\n", - " }\n", - "\n", - "model_gnss = {'data_type': 'GNSS',\n", - " 'y':y_gnss,\n", - " 'times':times_gnss,\n", - " 'groundwater': GW_at_GNSS_times\n", - " }" - ] - }, - { - "cell_type": "markdown", - "id": "76c9115b", - "metadata": { - "id": "76c9115b" - }, - "source": [ - "## Task 2: Set-up linear functional model\n", - "\n", - "We want to investigate how we could model the observed displacements of the road. Because the road is built in the Green Heart we expect that the observed displacements are related to the groundwater level. Furthermore, we assume that the displacements can be modeled using a constant velocity. The model is defined as \n", - "$$\n", - "d = d_0 + vt + k \\ \\textrm{GW},\n", - "$$\n", - "where $d$ is the displacement, $t$ is time and $\\textrm{GW}$ is the groundwater level (that we assume to be deterministic). \n", - "\n", - "Therefore, the model has 3 unknowns:\n", - "1. $d_0$, as the initial displacement at $t_0$;\n", - "2. $v$, as the displacement velocity;\n", - "3. $k$, as the 'groundwater factor', which can be seen as the response of the soil to changes in the groundwater level.\n", - "\n", - "\n", - "As a group you will construct the **functional model** that is defined as \n", - "$$\n", - "\\mathbb{E}(Y) = \\mathrm{A x}.\n", - "$$\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "f6aca691", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.1:</b> \n", - " \n", - "Construct the design matrix $A$ (for both InSAR and GNSS observations), then show the first 5 observations and confirm the dimensions of $A$.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3a3eb1a1", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# YOUR_CODE_HERE\n", - "\n", - "# SOLUTION:\n", - "A_insar = np.ones((len(times_insar), 3))\n", - "A_insar[:,1] = days_insar\n", - "A_insar[:,2] = GW_at_InSAR_times\n", - "\n", - "print ('The first 5 rows of the A matrix (InSAR) are:')\n", - "print (A_insar[0:5, :])\n", - "\n", - "print ('The first 5 observations [mm] of y_insar are:')\n", - "print (y_insar[0:5])\n", - "\n", - "m_insar = np.shape(A_insar)[0]\n", - "n_insar = np.shape(A_insar)[1]\n", - "print(f'm = {m_insar} and n = {n_insar}')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4bcd395d", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# YOUR_CODE_HERE\n", - "\n", - "# SOLUTION:\n", - "A_gnss = np.ones((len(times_gnss), 3))\n", - "A_gnss[:,1] = days_gnss\n", - "A_gnss[:,2] = GW_at_GNSS_times\n", - "\n", - "print ('The first 5 rows of the A matrix (GNSS) are:')\n", - "print (A_gnss[0:5, :])\n", - "\n", - "print ('\\nThe first 5 observations [mm] of y_gnss are:')\n", - "print (y_gnss[0:5])\n", - "\n", - "m_gnss = np.shape(A_gnss)[0]\n", - "n_gnss = np.shape(A_gnss)[1]\n", - "print(f'm = {m_gnss} and n = {n_gnss}')" - ] - }, - { - "cell_type": "markdown", - "id": "d390f466", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Task 2.2}$\n", - " \n", - "Answer the following questions:\n", - "\n", - "- What is the dimension of the observables' vector $Y$?\n", - "- What are the unknowns of the functional model?\n", - "- What is the redundancy for this model?\n", - "\n", - "</p>\n", - "</div>\n" - ] - }, - { - "cell_type": "markdown", - "id": "d40a0ecf", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Solution}$\n", - " \n", - "For InSAR:\n", - "<ol>\n", - " <li>The number of observations is 61.</li>\n", - " <li>The number of unknowns is 3.</li>\n", - " <li>The redundancy is 58.</li>\n", - "</ol>\n", - " \n", - "For GNSS:\n", - "<ol>\n", - " <li>The number of observations is 730.</li>\n", - " <li>The number of unknowns is 3.</li>\n", - " <li>The redundancy is 727.</li>\n", - "</ol> \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "cde2f4db", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 2.3:</b> \n", - " \n", - "Add the A matrix to the dictionaries for each model. This will be used to plot results later in the notebook.\n", - "\n", - "</p>\n", - "</div>\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "396ac3a5", - "metadata": {}, - "outputs": [], - "source": [ - "# model_insar['A'] = YOUR_CODE_HERE\n", - "# model_gnss['A'] = YOUR_CODE_HERE\n", - "\n", - "# SOLUTION:\n", - "model_insar['A'] = A_insar\n", - "model_gnss['A'] = A_gnss\n", - "\n", - "print(\"Keys and Values (type) for model_insar:\")\n", - "for key, value in model_insar.items():\n", - " print(f\"{key:16s} --> {type(value)}\")\n", - "print(\"\\nKeys and Values (type) for model_gnss:\")\n", - "for key, value in model_gnss.items():\n", - " print(f\"{key:16s} --> {type(value)}\")" - ] - }, - { - "cell_type": "markdown", - "id": "9325d32b", - "metadata": { - "id": "9325d32b", - "tags": [] - }, - "source": [ - "## 3. Set-up stochastic model\n", - "\n", - "We will use the Best Linear Unbiased Estimator (BLUE) to solve for the unknown parameters. Therefore we also need a stochastic model, which is defined as\n", - "$$\n", - "\\mathbb{D}(Y) = \\Sigma_{Y}.\n", - "$$\n", - "where $\\Sigma_{Y}$ is the covariance matrix of the observables' vector. \n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "dc3aec4c", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 3.1:</b> \n", - " \n", - "Construct the covariance matrix for each type of data and assume that \n", - "\n", - "- the observables are independent\n", - "\n", - "- the observables are normally distributed\n", - "\n", - "- the observables' standard deviation is\n", - " \n", - " - $\\sigma_\\textrm{InSAR} = 2$ mm \n", - " - $\\sigma_\\textrm{GNSS} = 15$ mm \n", - " \n", - "</p>\n", - "</div>\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "163acdb3", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "executionInfo": { - "elapsed": 40, - "status": "ok", - "timestamp": 1664699881875, - "user": { - "displayName": "C Yin", - "userId": "14075875094781565898" - }, - "user_tz": -120 - }, - "id": "163acdb3", - "outputId": "8bc99da3-a61e-4a25-8a54-c90f33299a57", - "tags": [] - }, - "outputs": [], - "source": [ - "# YOUR_CODE_HERE\n", - "\n", - "# SOLUTION:\n", - "std_insar = 2 #mm\n", - "\n", - "Sigma_Y_insar = np.identity(len(times_insar))*std_insar**2\n", - "\n", - "print ('Sigma_Y (InSAR) is defined as:')\n", - "print (Sigma_Y_insar)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5d583bd8", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# YOUR_CODE_HERE\n", - "\n", - "# SOLUTION:\n", - "std_gnss = 15 #mm (corrected from original value of 5 mm)\n", - "\n", - "Sigma_Y_gnss = np.identity(len(times_gnss))*std_gnss**2\n", - "\n", - "print ('\\nSigma_Y (GNSS) is defined as:')\n", - "print (Sigma_Y_gnss)" - ] - }, - { - "cell_type": "markdown", - "id": "b2665071", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Task 3.2}$\n", - " \n", - "Answer the following questions:\n", - "\n", - "- What information is contained in the covariance matrix?\n", - "- How do you implement the assumption that all observations are independent?\n", - "- What is the dimension of $\\Sigma_{Y}$?\n", - "- How do you create $\\Sigma_{Y}$?\n", - "\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "4322a5b5", - "metadata": {}, - "source": [ - "_Write your answer in this cell._" - ] - }, - { - "cell_type": "markdown", - "id": "124ddd77", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Solution}$ \n", - "\n", - "- The covariance matrix contains information on the quality of the observations, where an entry on the diagonal represents the variance of one observation at a particular epoch. If there is an indication that for instance the quality for a particular time interval differs, different $\\sigma$ values can be put in the stochastic model for these epochs. \n", - "- The off-diagonal terms in the matrix are related to the correlation between observations at different epochs, where a zero value on the off-diagonal indicates zero correlation.\n", - "- The dimension of the matrix is 61x61 for InSAR and 730x730 for GNSS.\n", - "- See code.\n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "8e87d1fe", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 3.3:</b> \n", - " \n", - "Add <code>Sigma_Y</code> to the dictionaries for each model.\n", - "\n", - "</p>\n", - "</div>\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "13cffb4c", - "metadata": {}, - "outputs": [], - "source": [ - "# model_insar['Sigma_Y] = YOUR_CODE_HERE\n", - "# model_gnss['Sigma_Y'] = YOUR_CODE_HERE\n", - "\n", - "# SOLUTION:\n", - "model_insar['Sigma_Y'] = Sigma_Y_insar\n", - "model_gnss['Sigma_Y'] = Sigma_Y_gnss" - ] - }, - { - "cell_type": "markdown", - "id": "09e965bf", - "metadata": { - "id": "09e965bf" - }, - "source": [ - "## 4. Apply best linear unbiased estimation\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "83ec4a48", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 4.1:</b> \n", - " \n", - "Write a function to apply BLUE in the cell below and use the function to estimate the unknowns for the model using the data.\n", - "\n", - "Compute the modeled displacements ($\\hat{\\mathrm{y}}$), and corresponding residuals ($\\hat{\\mathrm{\\epsilon}}$), as well as associated values (as requested by the blank code lines).\n", - "</p>\n", - "</div>\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "936d6b0c", - "metadata": {}, - "source": [ - "<div style=\"background-color:#facb8e; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\"> <p><strong>Note on code implementation</strong>: you'll see that the functions in this assignment use a dictionary; this greatly reduces the number of input/output variables needed in a function. However, it can make the code inside the function more difficult to read due to the key syntax (e.g., <code>dict['variable_1']</code> versus <code>variable\n", - "_1</code>). To make this assignment easier for you to implement we have split these functions into three parts: 1) define variables from the dictionary, 2) perform analysis, 3) add results to the dictionary. Note that this is not the most efficient way to write this code; it is done here specifically for clarity and to help you focus on writing the equations properly and understanding the meaning of each term.</p></div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d85b1826", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "def BLUE(d):\n", - " \"\"\"Calculate the Best Linear Unbiased Estimator\n", - " \n", - " Uses dict as input/output:\n", - " - inputs defined from existing values in dict\n", - " - outputs defined as new values in dict\n", - " \"\"\"\n", - "\n", - " y = d['y']\n", - " A = d['A']\n", - " Sigma_Y = d['Sigma_Y']\n", - "\n", - " # Sigma_X_hat = YOUR_CODE_HERE\n", - " # x_hat = YOUR_CODE_HERE\n", - " \n", - " # y_hat = YOUR_CODE_HERE\n", - "\n", - " # e_hat = YOUR_CODE_HERE\n", - "\n", - " # Sigma_Y_hat = YOUR_CODE_HERE\n", - " # std_y = YOUR_CODE_HERE\n", - "\n", - " # Sigma_e_hat = YOUR_CODE_HERE\n", - " # std_e_hat = YOUR_CODE_HERE\n", - "\n", - " # SOLUTION:\n", - " Sigma_X_hat = np.linalg.inv(A.T @ np.linalg.inv(Sigma_Y) @ A)\n", - " x_hat = Sigma_X_hat @ A.T @ np.linalg.inv(Sigma_Y) @ y\n", - " \n", - " y_hat = A @ x_hat\n", - "\n", - " e_hat = y - y_hat\n", - "\n", - " Sigma_Y_hat = A @ Sigma_X_hat @ A.T\n", - " std_y = np.sqrt(Sigma_Y_hat.diagonal())\n", - "\n", - " Sigma_e_hat = Sigma_Y - Sigma_Y_hat\n", - " std_e_hat = np.sqrt(Sigma_e_hat.diagonal())\n", - "\n", - " d['Sigma_X_hat'] = Sigma_X_hat\n", - " d['x_hat'] = x_hat\n", - " d['y_hat'] = y_hat\n", - " d['e_hat'] = e_hat\n", - " d['Sigma_Y_hat'] = Sigma_Y_hat\n", - " d['std_y'] = std_y\n", - " d['Sigma_e_hat'] = Sigma_e_hat\n", - " d['std_e_hat'] = std_e_hat\n", - "\n", - " return d" - ] - }, - { - "cell_type": "markdown", - "id": "f6c74941", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 4.2:</b> \n", - " \n", - "Now that you have completed the function, apply it to our two models and then print values for the estimated parameters.\n", - "</p>\n", - "</div>\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4a592ac1", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "model_insar = BLUE(model_insar)\n", - "x_hat_insar = model_insar['x_hat']\n", - "\n", - "# YOUR_CODE_HERE\n", - "\n", - "# SOLUTION:\n", - "print ('The InSAR-estimated offset is', np.round(x_hat_insar[0],3), 'mm')\n", - "print ('The InSAR-estimated velocity is', np.round(x_hat_insar[1],4), 'mm/day')\n", - "print ('The InSAR-estimated velocity is', np.round(x_hat_insar[1]*365,4), 'mm/year')\n", - "print ('The InSAR-estimated GW factor is', np.round(x_hat_insar[2],3), '[-]\\n')\n", - "\n", - "model_gnss = BLUE(model_gnss)\n", - "x_hat_gnss = model_gnss['x_hat']\n", - "\n", - "# YOUR_CODE_HERE\n", - "\n", - "# SOLUTION:\n", - "print ('The GNSS-estimated offset is', np.round(x_hat_gnss[0],3), 'mm')\n", - "print ('The GNSS-estimated velocity is', np.round(x_hat_gnss[1],4), 'mm/day')\n", - "print ('The GNSS-estimated velocity is', np.round(x_hat_gnss[1]*365,4), 'mm/year')\n", - "print ('The GNSS-estimated GW factor is', np.round(x_hat_gnss[2],3), '[-]')" - ] - }, - { - "cell_type": "markdown", - "id": "bef2f3be", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 4.3:</b> \n", - "Do the values that you just estimated make sense? Explain, using quantitative results.\n", - "\n", - "<em>Hint: all you need to do is use the figures created above to verify that the parameter values printed above are reasonable (e.g., order of magnitude, units, etc).</em> \n", - "</p>\n", - "</div>\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "f6740791", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Solution}$ \n", - " \n", - "As long as the velocity is negative and around -0.02 mm/day or -10 mm/yr it makes sense if you compare with what you see in the plots with observations. Since load is applied on soil layers we expect the road to subside. We also expect to see a positive value for the GW factor.\n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "65e42a43", - "metadata": { - "id": "65e42a43" - }, - "source": [ - "## 5. Evaluate the precision\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "68f79fcb", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 5:</b> \n", - " \n", - "What is the precision of the final estimates? \n", - " \n", - "Print the full covariance matrix of your estimates, and give an interpretation of the numbers in the covariance matrix.\n", - "</p>\n", - "</div>\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "835eefc8", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "executionInfo": { - "elapsed": 16, - "status": "ok", - "timestamp": 1664699882186, - "user": { - "displayName": "C Yin", - "userId": "14075875094781565898" - }, - "user_tz": -120 - }, - "id": "835eefc8", - "outputId": "ad47d53d-c147-4b25-fb03-b967a3bb6f96", - "tags": [] - }, - "outputs": [], - "source": [ - "Sigma_X_hat_insar = model_insar['Sigma_X_hat']\n", - "\n", - "# YOUR_CODE_HERE\n", - "\n", - "# SOLUTION:\n", - "print ('Covariance matrix of estimated parameters (InSAR):')\n", - "print (Sigma_X_hat_insar)\n", - "print ('\\nThe standard deviation for the InSAR-estimated offset is', \n", - " np.round(np.sqrt(Sigma_X_hat_insar[0,0]),3), 'mm')\n", - "print ('The standard deviation for the InSAR-estimated velocity is', \n", - " np.round(np.sqrt(Sigma_X_hat_insar[1,1]),4), 'mm/day')\n", - "print ('The standard deviation for the InSAR-estimated GW factor is', \n", - " np.round(np.sqrt(Sigma_X_hat_insar[2,2]),3), '[-]\\n')\n", - "\n", - "Sigma_X_hat_gnss = model_gnss['Sigma_X_hat']\n", - "\n", - "# YOUR_CODE_HERE\n", - "\n", - "# SOLUTION:\n", - "print ('Covariance matrix of estimated parameters (GNSS):')\n", - "print (Sigma_X_hat_gnss)\n", - "print ('\\nThe standard deviation for the GNSS-estimated offset is', \n", - " np.round(np.sqrt(Sigma_X_hat_gnss[0,0]),3), 'mm')\n", - "print ('The standard deviation for the GNSS-estimated velocity is', \n", - " np.round(np.sqrt(Sigma_X_hat_gnss[1,1]),4), 'mm/day')\n", - "print ('The standard deviation for the GNSS-estimated GW factor is', \n", - " np.round(np.sqrt(Sigma_X_hat_gnss[2,2]),3), '[-]')" - ] - }, - { - "cell_type": "markdown", - "id": "8e62592d", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Solution}$\n", - " \n", - "As shown above, the standard deviations of the estimated parameters are equal to the square root of the diagonal elements. Compared with the estimated values, the standard deviations seem quite small, except for the estimated offsets. Meaning that the complete estimated model can be shifted up or down. \n", - " \n", - "The off-diagonal elements show the covariances between the estimated parameters, which are non-zeros since the estimates are all computed as function of the same vector of observations and the same model. A different value for the estimated velocity would imply a different value for the GW factor and offset. \n", - " \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "markdown", - "id": "886efe26", - "metadata": { - "id": "886efe26" - }, - "source": [ - "## 6. Present and reflect on estimation results" - ] - }, - { - "cell_type": "markdown", - "id": "7ef41ce8", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 6.1:</b> \n", - " \n", - "Complete the function below to help us compute the confidence intervals, then apply the function. Use a confidence interval of 96% in your analysis.\n", - "\n", - "<em>Hint: it can be used in exactly the same way as the <code>BLUE</code> function above, although it has one extra input.</em>\n", - "</p>\n", - "</div>\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2711da12", - "metadata": {}, - "outputs": [], - "source": [ - "def get_CI(d, alpha):\n", - " \"\"\"Compute the confidence intervals.\n", - " \n", - " Uses dict as input/output:\n", - " - inputs defined from existing values in dict\n", - " - outputs defined as new values in dict\n", - " \"\"\"\n", - "\n", - " std_e_hat = d['std_e_hat']\n", - " std_y = d['std_y']\n", - "\n", - " # k = YOUR_CODE_HERE\n", - " # CI_y = YOUR_CODE_HERE\n", - " # CI_res = YOUR_CODE_HERE\n", - "\n", - " # SOLUTION:\n", - " k = norm.ppf(1 - 0.5*alpha)\n", - " CI_y = k*std_y\n", - " CI_res = k*std_e_hat\n", - " CI_y_hat = k*np.sqrt(d['Sigma_Y_hat'].diagonal())\n", - "\n", - " d['alpha'] = alpha\n", - " d['CI_y'] = CI_y\n", - " d['CI_res'] = CI_res\n", - " d['CI_Y_hat'] = CI_y_hat\n", - "\n", - " return d" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d9a41ea5", - "metadata": {}, - "outputs": [], - "source": [ - "# model_insar = YOUR_CODE_HERE\n", - "# model_gnss = YOUR_CODE_HERE\n", - "\n", - "# SOLUTION:\n", - "model_insar = get_CI(model_insar, 0.04)\n", - "model_gnss = get_CI(model_gnss, 0.04)" - ] - }, - { - "cell_type": "markdown", - "id": "53cf3663", - "metadata": {}, - "source": [ - "At this point we have all the important results entered in our dictionary and we will be able to use the plots that have been written for you in the next Tasks. In case you would like to easily see all of the key-value pairs that have been added to the dictionary, you can run the cell below:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b3bb808e", - "metadata": {}, - "outputs": [], - "source": [ - "print(\"Keys and Values (type) for model_insar:\")\n", - "for key, value in model_insar.items():\n", - " print(f\"{key:16s} --> {type(value)}\")\n", - "print(\"\\nKeys and Values (type) for model_gnss:\")\n", - "for key, value in model_gnss.items():\n", - " print(f\"{key:16s} --> {type(value)}\")" - ] - }, - { - "cell_type": "markdown", - "id": "aaf72e41", - "metadata": {}, - "source": [ - "<div style=\"background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "<b>Task 6.2:</b> \n", - " \n", - "Read the contents of file <code>functions.py</code> and identify what it is doing: you should be able to recognize that they use our model dictionary as an input and create three different figures. Note also that the function to create the figures have already been imported at the top of this notebook.\n", - "\n", - "Use the functions provided to visualize the results of our two models.\n", - "</p>\n", - "</div>\n" - ] - }, - { - "cell_type": "markdown", - "id": "e8da1f6c-23de-4f80-a76c-5f0a9b4020b4", - "metadata": { - "id": "0491cc69" - }, - "source": [ - "<div style=\"background-color:#facb8e; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\"> <p><strong>Note</strong>: remember that you will have to use the same function to look at <em>both</em> models when writing your interpretation in the Report.</p></div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ec7c8bef", - "metadata": {}, - "outputs": [], - "source": [ - "# _, _ = plot_model(YOUR_CODE_HERE)\n", - "\n", - "# SOLUTION:\n", - "_, _ = plot_model(model_insar)\n", - "_, _ = plot_model(model_gnss)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "104d155d", - "metadata": {}, - "outputs": [], - "source": [ - "# _, _ = plot_residual(YOUR_CODE_HERE)\n", - "\n", - "# SOLUTION:\n", - "_, _ = plot_residual(model_insar)\n", - "_, _ = plot_residual(model_gnss)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1dc93ce9", - "metadata": {}, - "outputs": [], - "source": [ - "# _, _ = plot_residual_histogram(YOUR_CODE_HERE)\n", - "\n", - "# SOLUTION:\n", - "_, _ = plot_residual_histogram(model_insar)\n", - "_, _ = plot_residual_histogram(model_gnss)" - ] - }, - { - "cell_type": "markdown", - "id": "1ae74dd4", - "metadata": {}, - "source": [ - "<div style=\"background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px\">\n", - "<p>\n", - "\n", - "$\\textbf{Solution: the True Model}$\n", - " \n", - "The data used in this exercise was generated using Monte Carlo Simulation. It is added to the plots here to illustrate where and how our models differ (it is your job to interpret \"why\"). \n", - "</p>\n", - "</div>" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "113f3809", - "metadata": {}, - "outputs": [], - "source": [ - "k_true = 0.15\n", - "R_true = -22 \n", - "a_true = 180\n", - "d0_true = 10\n", - "\n", - "disp_insar = (d0_true + R_true*(1 - np.exp(-days_insar/a_true)) +\n", - " k_true*GW_at_InSAR_times)\n", - "disp_gnss = (d0_true + R_true*(1 - np.exp(-days_gnss/a_true)) +\n", - " k_true*GW_at_GNSS_times)\n", - "\n", - "plot_model(model_insar, alt_model=('True model', times_insar, disp_insar));\n", - "plot_model(model_gnss, alt_model=('True model', times_gnss, disp_gnss));" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aa877dd5", - "metadata": {}, - "outputs": [], - "source": [ - "import ipywidgets as widgets\n", - "from ipywidgets import interact\n", - "\n", - "# Function to update the plot based on slider values\n", - "def update_plot(x0, x1, x2):\n", - " plt.figure(figsize=(15,5))\n", - " for m in [model_gnss]: #[model_insar, model_gnss]:\n", - " plt.plot(m['times'], m['y'], 'o', label=m['data_type'])\n", - " plt.ylabel('Displacement [mm]')\n", - " plt.xlabel('Time')\n", - " \n", - " y_fit = model_gnss['A'] @ [x0, x1, x2]\n", - " if (x0 == 0) & (x1 == 0) & (x2 == 1):\n", - " plt.plot(model_gnss['times'], y_fit, 'r', label='Groundwater data', linewidth=2)\n", - " else:\n", - " plt.plot(model_gnss['times'], y_fit, 'r', label='Fit (GNSS)', linewidth=2)\n", - "\n", - " W = np.linalg.inv(model_gnss['Sigma_Y'])\n", - " ss_res = (model_gnss['y'] - y_fit).T @ W @ (model_gnss['y'] - y_fit)\n", - " plt.title(f'Mean of squared residuals: {ss_res:.0f}')\n", - " plt.grid()\n", - " plt.legend()\n", - " plt.show()\n", - "\n", - "# Create sliders for x0, x1, and x2\n", - "x0_slider = widgets.FloatSlider(value=0, min=-10, max=10, step=0.1, description='x0')\n", - "x1_slider = widgets.FloatSlider(value=0, min=-0.1, max=0.1, step=0.001, description='x1')\n", - "x2_slider = widgets.FloatSlider(value=0, min=-1, max=1, step=0.01, description='x2')\n", - "\n", - "# Use interact to create the interactive plot\n", - "interact(update_plot, x0=x0_slider, x1=x1_slider, x2=x2_slider)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d8b31540", - "metadata": {}, - "outputs": [], - "source": [ - "xhat_slider_plot(model_gnss['A'], model_gnss['y'], model_gnss['times'], model_gnss['Sigma_Y'])" - ] - }, - { - "cell_type": "markdown", - "id": "3203d779", - "metadata": {}, - "source": [ - "**End of notebook.**\n", - "<h2 style=\"height: 60px\">\n", - "</h2>\n", - "<h3 style=\"position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0\">\n", - " <style>\n", - " .markdown {width:100%; position: relative}\n", - " article { position: relative }\n", - " </style>\n", - " <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">\n", - " <img alt=\"Creative Commons License\" style=\"border-width:; width:88px; height:auto; padding-top:10px\" src=\"https://i.creativecommons.org/l/by/4.0/88x31.png\" />\n", - " </a>\n", - " <a rel=\"TU Delft\" href=\"https://www.tudelft.nl/en/ceg\">\n", - " <img alt=\"TU Delft\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png\" />\n", - " </a>\n", - " <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">\n", - " <img alt=\"MUDE\" style=\"border-width:0; width:100px; height:auto; padding-bottom:0px\" src=\"https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png\" />\n", - " </a>\n", - " \n", - "</h3>\n", - "<span style=\"font-size: 75%\">\n", - "© Copyright 2024 <a rel=\"MUDE\" href=\"http://mude.citg.tudelft.nl/\">MUDE</a> TU Delft. This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">CC BY 4.0 License</a>." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "provenance": [] - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.4" - }, - "vscode": { - "interpreter": { - "hash": "b932539803d9742d977fbe9ca28a706a58466dc5c9df0c7af4e41c76d82e5a85" - } - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/synced_files/test/Analysis_Solution.md b/synced_files/test/Analysis_Solution.md deleted file mode 100644 index 1b7bb93997150fbf68f130d1755f1cdf99084e5a..0000000000000000000000000000000000000000 --- a/synced_files/test/Analysis_Solution.md +++ /dev/null @@ -1,975 +0,0 @@ ---- -jupyter: - jupytext: - text_representation: - extension: .md - format_name: markdown - format_version: '1.3' - jupytext_version: 1.16.4 - kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -# GA 1.3: Modelling Road Deformation using Non-Linear Least-Squares test! - -<h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> - <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -</h1> -<h2 style="height: 10px"> -</h2> - -*[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.3. Due: Friday, September 20, 2024.* - - -<div style="background-color:#ffa6a6; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"><p><b>Note:</b> don't forget to read the "Assignment Context" section of the README, it contains important information to understand this analysis.</p></div> - -```python -import numpy as np -from scipy import interpolate -from scipy.stats import norm -import pandas as pd -import matplotlib.pyplot as plt - - -from functions import * - -np.set_printoptions(precision=3) -``` - -## Part 0: Dictionary Review - -As described above, several functions in this assignment require the use of a Python dictionary to make it easier to keep track of important data, variables and results for the various _models_ we will be constructing and validating. - -_It may be useful to revisit PA 1.1, where there was a brief infroduction to dictionaires. That PA contains all the dictionary info you need for GA 1.3. A [read-only copy is here](https://mude.citg.tudelft.nl/2024/files/Week_1_1/PA_1_1_Catch_Them_All.html) and [the source code (notebook) is here](https://gitlab.tudelft.nl/mude/2024-week-1-1)._ - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Task 0.1}$ - -Read and run the cell below to make sure you remember how to use a dictionary. - -Modify the function to print some of the other key-value pairs of the dictionary. - -<em>It may also be useful to use the cell below when working on later tasks in this assignment.</em> - -</p> -</div> - -```python -my_dictionary = {'key1': 'value1', - 'key2': 'value2', - 'name': 'Dictionary Example', - 'a_list': [1, 2, 3], - 'an_array': np.array([1, 2, 3]), - 'a_string': 'hello' - } - -def function_that_uses_my_dictionary(d): - print(d['key1']) - - # SOLUTION: - print(d['name']) - print(d['a_list']) - print(d['an_array']) - print(d['a_string']) - - if 'new_key' in d: - print('new_key exists and has value:', d['new_key']) - return - -function_that_uses_my_dictionary(my_dictionary) -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Task 0.2}$ - -Test your knowledge by adding a new key <code>new_key</code> and then executing the function to print the value. - -</p> -</div> - -```python -# YOUR_CODE_HERE -# function_that_uses_my_dictionary(my_dictionary) - -# SOLUTION: -my_dictionary['new_key'] = 'new_value' -function_that_uses_my_dictionary(my_dictionary) -``` - -<!-- #region id="160d6250" --> -## Task 1: Preparing the data - -Within this assignment you will work with two types of data: InSAR data and GNSS data. The cell below will load the data and visualize the observed displacements time. In this task we use the package `pandas`, which is really useful for handling time series. We will learn how to use it later in the quarter; for now, you only need to recognize that it imports the data as a `dataframe` object, which we then convert into a numpy array using the code below. -<!-- #endregion --> - -<div style="background-color:#facb8e; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> <p>Tip: note that we have converted all observations to millimeters.</p></div> - -```python -gnss = pd.read_csv('./data/gnss_observations.csv') -times_gnss = pd.to_datetime(gnss['times']) -y_gnss = (gnss['observations[m]']).to_numpy()*1000 - -insar = pd.read_csv('./data/insar_observations.csv') -times_insar = pd.to_datetime(insar['times']) -y_insar = (insar['observations[m]']).to_numpy()*1000 - -gw = pd.read_csv('./data/groundwater_levels.csv') -times_gw = pd.to_datetime(gw['times']) -y_gw = (gw['observations[mm]']).to_numpy() -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.1:</b> - -Once you have used the cell above to import the data, investigate the data sets using the code cell below. Then provide some relevant summary information in the Markdown cell. - -<em>Hint: at the least, you should be able to tell how many data points are in each data set and get an understanding of the mean and standard deviation of each. Make sure you compare the different datasets and use consistent units.</em> - -</p> -</div> - -<!-- #region id="0491cc69" --> -<div style="background-color:#facb8e; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> <p>The code below gives some examples of the quantitative and qualitative ways you could have looked at the data. It is more than you were expected to do; the important thing is that you showed the ability to learn something about the data and describe aspects that are relevant to our problem. We use a dictionary to easily access the different data series using their names, which are entered as the dictionary keys (also not expected of you, but it's hopefully fun to learn useful tricks).</div> -<!-- #endregion --> - -```python -# YOUR_CODE_HERE - -# SOLUTION: -data_list = ['y_gnss', 'y_insar', 'y_gw'] -data_dict = {data_list[0]: y_gnss, - data_list[1]: y_insar, - data_list[2]: y_gw} -def print_summary(data): - '''Summarize an array with simple print statements.''' - print('Minimum = ', data.min()) - print('Maximum = ', data.max()) - print('Mean = ', data.mean()) - print('Std dev = ', data.std()) - print('Shape = ', data.shape) - print('First value = ', data[0]) - print('Last value = ', data[-1]) - print('\n') - -for item in data_list: - print('Summary for array: ', item) - print('------------------------------------------------') - print_summary(data_dict[item]) -``` - -```python -# SOLUTION: -times_dict = {data_list[0]: times_gnss, - data_list[1]: times_insar, - data_list[2]: times_gw} -def plot_data(times, data, label): - plt.figure(figsize=(15,4)) - plt.plot(times, data, 'co', mec='black') - plt.title(label) - plt.xlabel('Times') - plt.ylabel('Data [mm]') - plt.show() - -plt.figure(figsize=(15,4)) -for i in range(3): - plot_data(times_dict[data_list[i]], - data_dict[data_list[i]], - data_list[i]) -``` - -<div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Solution}$ - -There are a lot more GNSS data points than InSAR or groundwater. The GNSS observations also have more noise, and what seem to be outliers. In this case the mean and standard deviation do not mean much, because there is clearly a trend with time. We can at least confirm that the time periods of measurements overlap, although the intervals between measurements is certainly not uniform (note that you don't need to do anything with the times, since they are pandas time series and we have not covered them yet). -</p> -</div> - - -You may have noticed that the groundwater data is available for different times than the GNSS and InSAR data. You will therefore have to *interpolate* the data to the same times for a further analysis. You can use the SciPy function ```interpolate.interp1d``` (read its [documentation](https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html)). - -The cells below do the following: -1. Define a function to convert the time unit -2. Convert the time stamps for all data -3. Use `interp1d` to interpolate the groundwater measurements at the time of the satellite measurements - -```python -def to_days_years(times): - '''Convert the observation times to days and years.''' - - times_datetime = pd.to_datetime(times) - time_diff = (times_datetime - times_datetime[0]) - days_diff = (time_diff / np.timedelta64(1,'D')).astype(int) - - days = days_diff.to_numpy() - years = days/365 - - return days, years -``` - -```python -days_gnss, years_gnss = to_days_years(times_gnss) -days_insar, years_insar = to_days_years(times_insar) -days_gw, years_gw = to_days_years(times_gw) - -interp = interpolate.interp1d(days_gw, y_gw) - -GW_at_GNSS_times = interp(days_gnss) -GW_at_InSAR_times = interp(days_insar) -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.2:</b> - -Answer/complete the code and Markdown cells below: -<ol> - <li>What is <code>interp</code>? (what kind of object is it, and how does it work?)</li> - <li>How did the groundwater observation array change? Be quantitative. </li> -</ol> - -</p> -</div> - -```python -# YOUR_CODE_HERE - -# SOLUTION: -print('array size of GW_at_GNSS_times', len(GW_at_GNSS_times)) -print('array size of GW_at_InSAR_times', len(GW_at_InSAR_times)) -print('array size of GW before interpolation', len(y_gw)) - -print('\nFirst values of times_gw:') -print(times_gw[0:2]) -print('\nFirst values of y_gw:') -print(y_gw[0:2]) -print('\nFirst values of times_gnss:') -print(times_gnss[0:2]) -print('\nFirst values of GW_at_GNSS_times:') -print(GW_at_GNSS_times[0:2]) -``` - -**Write your answer in this Markdown cell.** - - -<div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Solution}$ -<ol> - <li><code>interp</code> is a function that will return a value (gw level) for the input(s) (date(s)). The interpolated value is found by linearly interpolating between the two nearest times in the gw observations.</li> - <li>The observation arrays of <code>GW_at_GNSS_times</code> and <code>GW_at_INSAR_times</code> changed in size to match the size of the GNSS and InSAR observations, respectively.</li> -</ol> -</p> -</div> - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.3:</b> - -Create a single plot to compare observed displacement for the GNSS and InSAR data sets. - -</p> -</div> - -```python -# plt.figure(figsize=(15,5)) -# plt.plot(YOUR_CODE_HERE, YOUR_CODE_HERE, -# 'o', mec='black', label = 'GNSS') -# plt.plot(YOUR_CODE_HERE, YOUR_CODE_HERE, -# 'o', mec='black', label = 'InSAR') -# plt.legend() -# plt.ylabel('Displacement [mm]') -# plt.xlabel('Time') -# plt.show() - -# SOLUTION: -plt.figure(figsize=(15,5)) -plt.plot(times_gnss, y_gnss, 'o', mec='black', label = 'GNSS') -plt.plot(times_insar, y_insar, 'o', mec='black', label = 'InSAR') -plt.legend() -plt.ylabel('Displacement [mm]') -plt.xlabel('Time') -plt.show() -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.4:</b> -Describe the datasets based on the figure above and your observations from the previous tasks. What kind of deformation do you see? And what are the differences between both datasets? Be quantitative. -</p> -</div> - - -<div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Solution}$ - -The points obviously show subsidence, the displacement shows a similar pattern for both datasets. The GNSS data is much noisier than InSAR (range is around 60 mm versus only a few mm), but has a higher sampling rate. Also there seem to be more outliers in the GNSS data compared to InSAR, especially at the start of the observation period. InSAR has only observations every 6 days but is less noisy. -</p> -</div> - - -Before we move on, it is time to do a little bit of housekeeping. - -Have you found it confusing to keep track of two sets of variables---one for each data type? Let's use a dictionary to store relevant information about each model. We will use this in the plotting functions for this task (and again next week), so make sure you take the time to see what is happening. Review also Part 0 at the top of this notebook if you need a refresher on dictionaries. - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 1.5:</b> - -Run the cell below to define a dictionary for storing information about the two (future) models. - -</p> -</div> - - -```python -model_insar = {'data_type': 'InSAR', - 'y':y_insar, - 'times':times_insar, - 'groundwater': GW_at_InSAR_times - } - -model_gnss = {'data_type': 'GNSS', - 'y':y_gnss, - 'times':times_gnss, - 'groundwater': GW_at_GNSS_times - } -``` - -<!-- #region id="76c9115b" --> -## Task 2: Set-up linear functional model - -We want to investigate how we could model the observed displacements of the road. Because the road is built in the Green Heart we expect that the observed displacements are related to the groundwater level. Furthermore, we assume that the displacements can be modeled using a constant velocity. The model is defined as -$$ -d = d_0 + vt + k \ \textrm{GW}, -$$ -where $d$ is the displacement, $t$ is time and $\textrm{GW}$ is the groundwater level (that we assume to be deterministic). - -Therefore, the model has 3 unknowns: -1. $d_0$, as the initial displacement at $t_0$; -2. $v$, as the displacement velocity; -3. $k$, as the 'groundwater factor', which can be seen as the response of the soil to changes in the groundwater level. - - -As a group you will construct the **functional model** that is defined as -$$ -\mathbb{E}(Y) = \mathrm{A x}. -$$ - - -<!-- #endregion --> - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.1:</b> - -Construct the design matrix $A$ (for both InSAR and GNSS observations), then show the first 5 observations and confirm the dimensions of $A$. -</p> -</div> - -```python -# YOUR_CODE_HERE - -# SOLUTION: -A_insar = np.ones((len(times_insar), 3)) -A_insar[:,1] = days_insar -A_insar[:,2] = GW_at_InSAR_times - -print ('The first 5 rows of the A matrix (InSAR) are:') -print (A_insar[0:5, :]) - -print ('The first 5 observations [mm] of y_insar are:') -print (y_insar[0:5]) - -m_insar = np.shape(A_insar)[0] -n_insar = np.shape(A_insar)[1] -print(f'm = {m_insar} and n = {n_insar}') -``` - -```python -# YOUR_CODE_HERE - -# SOLUTION: -A_gnss = np.ones((len(times_gnss), 3)) -A_gnss[:,1] = days_gnss -A_gnss[:,2] = GW_at_GNSS_times - -print ('The first 5 rows of the A matrix (GNSS) are:') -print (A_gnss[0:5, :]) - -print ('\nThe first 5 observations [mm] of y_gnss are:') -print (y_gnss[0:5]) - -m_gnss = np.shape(A_gnss)[0] -n_gnss = np.shape(A_gnss)[1] -print(f'm = {m_gnss} and n = {n_gnss}') -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Task 2.2}$ - -Answer the following questions: - -- What is the dimension of the observables' vector $Y$? -- What are the unknowns of the functional model? -- What is the redundancy for this model? - -</p> -</div> - - - -<div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Solution}$ - -For InSAR: -<ol> - <li>The number of observations is 61.</li> - <li>The number of unknowns is 3.</li> - <li>The redundancy is 58.</li> -</ol> - -For GNSS: -<ol> - <li>The number of observations is 730.</li> - <li>The number of unknowns is 3.</li> - <li>The redundancy is 727.</li> -</ol> -</p> -</div> - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 2.3:</b> - -Add the A matrix to the dictionaries for each model. This will be used to plot results later in the notebook. - -</p> -</div> - - -```python -# model_insar['A'] = YOUR_CODE_HERE -# model_gnss['A'] = YOUR_CODE_HERE - -# SOLUTION: -model_insar['A'] = A_insar -model_gnss['A'] = A_gnss - -print("Keys and Values (type) for model_insar:") -for key, value in model_insar.items(): - print(f"{key:16s} --> {type(value)}") -print("\nKeys and Values (type) for model_gnss:") -for key, value in model_gnss.items(): - print(f"{key:16s} --> {type(value)}") -``` - -<!-- #region id="9325d32b" --> -## 3. Set-up stochastic model - -We will use the Best Linear Unbiased Estimator (BLUE) to solve for the unknown parameters. Therefore we also need a stochastic model, which is defined as -$$ -\mathbb{D}(Y) = \Sigma_{Y}. -$$ -where $\Sigma_{Y}$ is the covariance matrix of the observables' vector. - - - -<!-- #endregion --> - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 3.1:</b> - -Construct the covariance matrix for each type of data and assume that - -- the observables are independent - -- the observables are normally distributed - -- the observables' standard deviation is - - - $\sigma_\textrm{InSAR} = 2$ mm - - $\sigma_\textrm{GNSS} = 15$ mm - -</p> -</div> - - -```python colab={"base_uri": "https://localhost:8080/"} executionInfo={"elapsed": 40, "status": "ok", "timestamp": 1664699881875, "user": {"displayName": "C Yin", "userId": "14075875094781565898"}, "user_tz": -120} id="163acdb3" outputId="8bc99da3-a61e-4a25-8a54-c90f33299a57" -# YOUR_CODE_HERE - -# SOLUTION: -std_insar = 2 #mm - -Sigma_Y_insar = np.identity(len(times_insar))*std_insar**2 - -print ('Sigma_Y (InSAR) is defined as:') -print (Sigma_Y_insar) -``` - -```python -# YOUR_CODE_HERE - -# SOLUTION: -std_gnss = 15 #mm (corrected from original value of 5 mm) - -Sigma_Y_gnss = np.identity(len(times_gnss))*std_gnss**2 - -print ('\nSigma_Y (GNSS) is defined as:') -print (Sigma_Y_gnss) -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Task 3.2}$ - -Answer the following questions: - -- What information is contained in the covariance matrix? -- How do you implement the assumption that all observations are independent? -- What is the dimension of $\Sigma_{Y}$? -- How do you create $\Sigma_{Y}$? - -</p> -</div> - - -_Write your answer in this cell._ - - -<div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Solution}$ - -- The covariance matrix contains information on the quality of the observations, where an entry on the diagonal represents the variance of one observation at a particular epoch. If there is an indication that for instance the quality for a particular time interval differs, different $\sigma$ values can be put in the stochastic model for these epochs. -- The off-diagonal terms in the matrix are related to the correlation between observations at different epochs, where a zero value on the off-diagonal indicates zero correlation. -- The dimension of the matrix is 61x61 for InSAR and 730x730 for GNSS. -- See code. -</p> -</div> - - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 3.3:</b> - -Add <code>Sigma_Y</code> to the dictionaries for each model. - -</p> -</div> - - -```python -# model_insar['Sigma_Y] = YOUR_CODE_HERE -# model_gnss['Sigma_Y'] = YOUR_CODE_HERE - -# SOLUTION: -model_insar['Sigma_Y'] = Sigma_Y_insar -model_gnss['Sigma_Y'] = Sigma_Y_gnss -``` - -<!-- #region id="09e965bf" --> -## 4. Apply best linear unbiased estimation - - -<!-- #endregion --> - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 4.1:</b> - -Write a function to apply BLUE in the cell below and use the function to estimate the unknowns for the model using the data. - -Compute the modeled displacements ($\hat{\mathrm{y}}$), and corresponding residuals ($\hat{\mathrm{\epsilon}}$), as well as associated values (as requested by the blank code lines). -</p> -</div> - - - - -<div style="background-color:#facb8e; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> <p><strong>Note on code implementation</strong>: you'll see that the functions in this assignment use a dictionary; this greatly reduces the number of input/output variables needed in a function. However, it can make the code inside the function more difficult to read due to the key syntax (e.g., <code>dict['variable_1']</code> versus <code>variable -_1</code>). To make this assignment easier for you to implement we have split these functions into three parts: 1) define variables from the dictionary, 2) perform analysis, 3) add results to the dictionary. Note that this is not the most efficient way to write this code; it is done here specifically for clarity and to help you focus on writing the equations properly and understanding the meaning of each term.</p></div> - -```python -def BLUE(d): - """Calculate the Best Linear Unbiased Estimator - - Uses dict as input/output: - - inputs defined from existing values in dict - - outputs defined as new values in dict - """ - - y = d['y'] - A = d['A'] - Sigma_Y = d['Sigma_Y'] - - # Sigma_X_hat = YOUR_CODE_HERE - # x_hat = YOUR_CODE_HERE - - # y_hat = YOUR_CODE_HERE - - # e_hat = YOUR_CODE_HERE - - # Sigma_Y_hat = YOUR_CODE_HERE - # std_y = YOUR_CODE_HERE - - # Sigma_e_hat = YOUR_CODE_HERE - # std_e_hat = YOUR_CODE_HERE - - # SOLUTION: - Sigma_X_hat = np.linalg.inv(A.T @ np.linalg.inv(Sigma_Y) @ A) - x_hat = Sigma_X_hat @ A.T @ np.linalg.inv(Sigma_Y) @ y - - y_hat = A @ x_hat - - e_hat = y - y_hat - - Sigma_Y_hat = A @ Sigma_X_hat @ A.T - std_y = np.sqrt(Sigma_Y_hat.diagonal()) - - Sigma_e_hat = Sigma_Y - Sigma_Y_hat - std_e_hat = np.sqrt(Sigma_e_hat.diagonal()) - - d['Sigma_X_hat'] = Sigma_X_hat - d['x_hat'] = x_hat - d['y_hat'] = y_hat - d['e_hat'] = e_hat - d['Sigma_Y_hat'] = Sigma_Y_hat - d['std_y'] = std_y - d['Sigma_e_hat'] = Sigma_e_hat - d['std_e_hat'] = std_e_hat - - return d -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 4.2:</b> - -Now that you have completed the function, apply it to our two models and then print values for the estimated parameters. -</p> -</div> - - - -```python -model_insar = BLUE(model_insar) -x_hat_insar = model_insar['x_hat'] - -# YOUR_CODE_HERE - -# SOLUTION: -print ('The InSAR-estimated offset is', np.round(x_hat_insar[0],3), 'mm') -print ('The InSAR-estimated velocity is', np.round(x_hat_insar[1],4), 'mm/day') -print ('The InSAR-estimated velocity is', np.round(x_hat_insar[1]*365,4), 'mm/year') -print ('The InSAR-estimated GW factor is', np.round(x_hat_insar[2],3), '[-]\n') - -model_gnss = BLUE(model_gnss) -x_hat_gnss = model_gnss['x_hat'] - -# YOUR_CODE_HERE - -# SOLUTION: -print ('The GNSS-estimated offset is', np.round(x_hat_gnss[0],3), 'mm') -print ('The GNSS-estimated velocity is', np.round(x_hat_gnss[1],4), 'mm/day') -print ('The GNSS-estimated velocity is', np.round(x_hat_gnss[1]*365,4), 'mm/year') -print ('The GNSS-estimated GW factor is', np.round(x_hat_gnss[2],3), '[-]') -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 4.3:</b> -Do the values that you just estimated make sense? Explain, using quantitative results. - -<em>Hint: all you need to do is use the figures created above to verify that the parameter values printed above are reasonable (e.g., order of magnitude, units, etc).</em> -</p> -</div> - - - - -<div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Solution}$ - -As long as the velocity is negative and around -0.02 mm/day or -10 mm/yr it makes sense if you compare with what you see in the plots with observations. Since load is applied on soil layers we expect the road to subside. We also expect to see a positive value for the GW factor. - -</p> -</div> - -<!-- #region id="65e42a43" --> -## 5. Evaluate the precision - - -<!-- #endregion --> - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 5:</b> - -What is the precision of the final estimates? - -Print the full covariance matrix of your estimates, and give an interpretation of the numbers in the covariance matrix. -</p> -</div> - - - -```python colab={"base_uri": "https://localhost:8080/"} executionInfo={"elapsed": 16, "status": "ok", "timestamp": 1664699882186, "user": {"displayName": "C Yin", "userId": "14075875094781565898"}, "user_tz": -120} id="835eefc8" outputId="ad47d53d-c147-4b25-fb03-b967a3bb6f96" -Sigma_X_hat_insar = model_insar['Sigma_X_hat'] - -# YOUR_CODE_HERE - -# SOLUTION: -print ('Covariance matrix of estimated parameters (InSAR):') -print (Sigma_X_hat_insar) -print ('\nThe standard deviation for the InSAR-estimated offset is', - np.round(np.sqrt(Sigma_X_hat_insar[0,0]),3), 'mm') -print ('The standard deviation for the InSAR-estimated velocity is', - np.round(np.sqrt(Sigma_X_hat_insar[1,1]),4), 'mm/day') -print ('The standard deviation for the InSAR-estimated GW factor is', - np.round(np.sqrt(Sigma_X_hat_insar[2,2]),3), '[-]\n') - -Sigma_X_hat_gnss = model_gnss['Sigma_X_hat'] - -# YOUR_CODE_HERE - -# SOLUTION: -print ('Covariance matrix of estimated parameters (GNSS):') -print (Sigma_X_hat_gnss) -print ('\nThe standard deviation for the GNSS-estimated offset is', - np.round(np.sqrt(Sigma_X_hat_gnss[0,0]),3), 'mm') -print ('The standard deviation for the GNSS-estimated velocity is', - np.round(np.sqrt(Sigma_X_hat_gnss[1,1]),4), 'mm/day') -print ('The standard deviation for the GNSS-estimated GW factor is', - np.round(np.sqrt(Sigma_X_hat_gnss[2,2]),3), '[-]') -``` - -<div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Solution}$ - -As shown above, the standard deviations of the estimated parameters are equal to the square root of the diagonal elements. Compared with the estimated values, the standard deviations seem quite small, except for the estimated offsets. Meaning that the complete estimated model can be shifted up or down. - -The off-diagonal elements show the covariances between the estimated parameters, which are non-zeros since the estimates are all computed as function of the same vector of observations and the same model. A different value for the estimated velocity would imply a different value for the GW factor and offset. - -</p> -</div> - -<!-- #region id="886efe26" --> -## 6. Present and reflect on estimation results -<!-- #endregion --> - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 6.1:</b> - -Complete the function below to help us compute the confidence intervals, then apply the function. Use a confidence interval of 96% in your analysis. - -<em>Hint: it can be used in exactly the same way as the <code>BLUE</code> function above, although it has one extra input.</em> -</p> -</div> - - -```python -def get_CI(d, alpha): - """Compute the confidence intervals. - - Uses dict as input/output: - - inputs defined from existing values in dict - - outputs defined as new values in dict - """ - - std_e_hat = d['std_e_hat'] - std_y = d['std_y'] - - # k = YOUR_CODE_HERE - # CI_y = YOUR_CODE_HERE - # CI_res = YOUR_CODE_HERE - - # SOLUTION: - k = norm.ppf(1 - 0.5*alpha) - CI_y = k*std_y - CI_res = k*std_e_hat - CI_y_hat = k*np.sqrt(d['Sigma_Y_hat'].diagonal()) - - d['alpha'] = alpha - d['CI_y'] = CI_y - d['CI_res'] = CI_res - d['CI_Y_hat'] = CI_y_hat - - return d -``` - -```python -# model_insar = YOUR_CODE_HERE -# model_gnss = YOUR_CODE_HERE - -# SOLUTION: -model_insar = get_CI(model_insar, 0.04) -model_gnss = get_CI(model_gnss, 0.04) -``` - -At this point we have all the important results entered in our dictionary and we will be able to use the plots that have been written for you in the next Tasks. In case you would like to easily see all of the key-value pairs that have been added to the dictionary, you can run the cell below: - -```python -print("Keys and Values (type) for model_insar:") -for key, value in model_insar.items(): - print(f"{key:16s} --> {type(value)}") -print("\nKeys and Values (type) for model_gnss:") -for key, value in model_gnss.items(): - print(f"{key:16s} --> {type(value)}") -``` - -<div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> -<b>Task 6.2:</b> - -Read the contents of file <code>functions.py</code> and identify what it is doing: you should be able to recognize that they use our model dictionary as an input and create three different figures. Note also that the function to create the figures have already been imported at the top of this notebook. - -Use the functions provided to visualize the results of our two models. -</p> -</div> - - -<!-- #region id="0491cc69" --> -<div style="background-color:#facb8e; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> <p><strong>Note</strong>: remember that you will have to use the same function to look at <em>both</em> models when writing your interpretation in the Report.</p></div> -<!-- #endregion --> - -```python -# _, _ = plot_model(YOUR_CODE_HERE) - -# SOLUTION: -_, _ = plot_model(model_insar) -_, _ = plot_model(model_gnss) -``` - -```python -# _, _ = plot_residual(YOUR_CODE_HERE) - -# SOLUTION: -_, _ = plot_residual(model_insar) -_, _ = plot_residual(model_gnss) -``` - -```python -# _, _ = plot_residual_histogram(YOUR_CODE_HERE) - -# SOLUTION: -_, _ = plot_residual_histogram(model_insar) -_, _ = plot_residual_histogram(model_gnss) -``` - -<div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -<p> - -$\textbf{Solution: the True Model}$ - -The data used in this exercise was generated using Monte Carlo Simulation. It is added to the plots here to illustrate where and how our models differ (it is your job to interpret "why"). -</p> -</div> - -```python -k_true = 0.15 -R_true = -22 -a_true = 180 -d0_true = 10 - -disp_insar = (d0_true + R_true*(1 - np.exp(-days_insar/a_true)) + - k_true*GW_at_InSAR_times) -disp_gnss = (d0_true + R_true*(1 - np.exp(-days_gnss/a_true)) + - k_true*GW_at_GNSS_times) - -plot_model(model_insar, alt_model=('True model', times_insar, disp_insar)); -plot_model(model_gnss, alt_model=('True model', times_gnss, disp_gnss)); -``` - -```python -import ipywidgets as widgets -from ipywidgets import interact - -# Function to update the plot based on slider values -def update_plot(x0, x1, x2): - plt.figure(figsize=(15,5)) - for m in [model_gnss]: #[model_insar, model_gnss]: - plt.plot(m['times'], m['y'], 'o', label=m['data_type']) - plt.ylabel('Displacement [mm]') - plt.xlabel('Time') - - y_fit = model_gnss['A'] @ [x0, x1, x2] - if (x0 == 0) & (x1 == 0) & (x2 == 1): - plt.plot(model_gnss['times'], y_fit, 'r', label='Groundwater data', linewidth=2) - else: - plt.plot(model_gnss['times'], y_fit, 'r', label='Fit (GNSS)', linewidth=2) - - W = np.linalg.inv(model_gnss['Sigma_Y']) - ss_res = (model_gnss['y'] - y_fit).T @ W @ (model_gnss['y'] - y_fit) - plt.title(f'Mean of squared residuals: {ss_res:.0f}') - plt.grid() - plt.legend() - plt.show() - -# Create sliders for x0, x1, and x2 -x0_slider = widgets.FloatSlider(value=0, min=-10, max=10, step=0.1, description='x0') -x1_slider = widgets.FloatSlider(value=0, min=-0.1, max=0.1, step=0.001, description='x1') -x2_slider = widgets.FloatSlider(value=0, min=-1, max=1, step=0.01, description='x2') - -# Use interact to create the interactive plot -interact(update_plot, x0=x0_slider, x1=x1_slider, x2=x2_slider) - -``` - -```python -xhat_slider_plot(model_gnss['A'], model_gnss['y'], model_gnss['times'], model_gnss['Sigma_Y']) -``` - -**End of notebook.** -<h2 style="height: 60px"> -</h2> -<h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> - <style> - .markdown {width:100%; position: relative} - article { position: relative } - </style> - <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> - <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> - </a> - <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> - <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> - </a> - <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> - <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> - </a> - -</h3> -<span style="font-size: 75%"> -© Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>. diff --git a/synced_files/test/Analysis_Solution.py b/synced_files/test/Analysis_Solution.py deleted file mode 100644 index e4cb1d8c819e8ab501f3c728f142632cf755ba86..0000000000000000000000000000000000000000 --- a/synced_files/test/Analysis_Solution.py +++ /dev/null @@ -1,967 +0,0 @@ -# --- -# jupyter: -# jupytext: -# text_representation: -# extension: .py -# format_name: percent -# format_version: '1.3' -# jupytext_version: 1.16.4 -# kernelspec: -# display_name: Python 3 (ipykernel) -# language: python -# name: python3 -# --- - -# %% [markdown] -# # GA 1.3: Modelling Road Deformation using Non-Linear Least-Squares test! -# -# <h1 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; top: 60px;right: 30px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" style="width:100px" /> -# <img src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" style="width:100px" /> -# </h1> -# <h2 style="height: 10px"> -# </h2> -# -# *[CEGM1000 MUDE](http://mude.citg.tudelft.nl/): Week 1.3. Due: Friday, September 20, 2024.* - -# %% [markdown] -# <div style="background-color:#ffa6a6; color: black; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px; width: 95%"><p><b>Note:</b> don't forget to read the "Assignment Context" section of the README, it contains important information to understand this analysis.</p></div> - -# %% -import numpy as np -from scipy import interpolate -from scipy.stats import norm -import pandas as pd -import matplotlib.pyplot as plt - - -from functions import * - -np.set_printoptions(precision=3) - -# %% [markdown] -# ## Part 0: Dictionary Review -# -# As described above, several functions in this assignment require the use of a Python dictionary to make it easier to keep track of important data, variables and results for the various _models_ we will be constructing and validating. -# -# _It may be useful to revisit PA 1.1, where there was a brief infroduction to dictionaires. That PA contains all the dictionary info you need for GA 1.3. A [read-only copy is here](https://mude.citg.tudelft.nl/2024/files/Week_1_1/PA_1_1_Catch_Them_All.html) and [the source code (notebook) is here](https://gitlab.tudelft.nl/mude/2024-week-1-1)._ - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Task 0.1}$ -# -# Read and run the cell below to make sure you remember how to use a dictionary. -# -# Modify the function to print some of the other key-value pairs of the dictionary. -# -# <em>It may also be useful to use the cell below when working on later tasks in this assignment.</em> -# -# </p> -# </div> - -# %% -my_dictionary = {'key1': 'value1', - 'key2': 'value2', - 'name': 'Dictionary Example', - 'a_list': [1, 2, 3], - 'an_array': np.array([1, 2, 3]), - 'a_string': 'hello' - } - -def function_that_uses_my_dictionary(d): - print(d['key1']) - - # SOLUTION: - print(d['name']) - print(d['a_list']) - print(d['an_array']) - print(d['a_string']) - - if 'new_key' in d: - print('new_key exists and has value:', d['new_key']) - return - -function_that_uses_my_dictionary(my_dictionary) - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Task 0.2}$ -# -# Test your knowledge by adding a new key <code>new_key</code> and then executing the function to print the value. -# -# </p> -# </div> - -# %% -# YOUR_CODE_HERE -# function_that_uses_my_dictionary(my_dictionary) - -# SOLUTION: -my_dictionary['new_key'] = 'new_value' -function_that_uses_my_dictionary(my_dictionary) - -# %% [markdown] id="160d6250" -# ## Task 1: Preparing the data -# -# Within this assignment you will work with two types of data: InSAR data and GNSS data. The cell below will load the data and visualize the observed displacements time. In this task we use the package `pandas`, which is really useful for handling time series. We will learn how to use it later in the quarter; for now, you only need to recognize that it imports the data as a `dataframe` object, which we then convert into a numpy array using the code below. - -# %% [markdown] -# <div style="background-color:#facb8e; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> <p>Tip: note that we have converted all observations to millimeters.</p></div> - -# %% -gnss = pd.read_csv('./data/gnss_observations.csv') -times_gnss = pd.to_datetime(gnss['times']) -y_gnss = (gnss['observations[m]']).to_numpy()*1000 - -insar = pd.read_csv('./data/insar_observations.csv') -times_insar = pd.to_datetime(insar['times']) -y_insar = (insar['observations[m]']).to_numpy()*1000 - -gw = pd.read_csv('./data/groundwater_levels.csv') -times_gw = pd.to_datetime(gw['times']) -y_gw = (gw['observations[mm]']).to_numpy() - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.1:</b> -# -# Once you have used the cell above to import the data, investigate the data sets using the code cell below. Then provide some relevant summary information in the Markdown cell. -# -# <em>Hint: at the least, you should be able to tell how many data points are in each data set and get an understanding of the mean and standard deviation of each. Make sure you compare the different datasets and use consistent units.</em> -# -# </p> -# </div> - -# %% [markdown] id="0491cc69" -# <div style="background-color:#facb8e; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> <p>The code below gives some examples of the quantitative and qualitative ways you could have looked at the data. It is more than you were expected to do; the important thing is that you showed the ability to learn something about the data and describe aspects that are relevant to our problem. We use a dictionary to easily access the different data series using their names, which are entered as the dictionary keys (also not expected of you, but it's hopefully fun to learn useful tricks).</div> - -# %% -# YOUR_CODE_HERE - -# SOLUTION: -data_list = ['y_gnss', 'y_insar', 'y_gw'] -data_dict = {data_list[0]: y_gnss, - data_list[1]: y_insar, - data_list[2]: y_gw} -def print_summary(data): - '''Summarize an array with simple print statements.''' - print('Minimum = ', data.min()) - print('Maximum = ', data.max()) - print('Mean = ', data.mean()) - print('Std dev = ', data.std()) - print('Shape = ', data.shape) - print('First value = ', data[0]) - print('Last value = ', data[-1]) - print('\n') - -for item in data_list: - print('Summary for array: ', item) - print('------------------------------------------------') - print_summary(data_dict[item]) - -# %% -# SOLUTION: -times_dict = {data_list[0]: times_gnss, - data_list[1]: times_insar, - data_list[2]: times_gw} -def plot_data(times, data, label): - plt.figure(figsize=(15,4)) - plt.plot(times, data, 'co', mec='black') - plt.title(label) - plt.xlabel('Times') - plt.ylabel('Data [mm]') - plt.show() - -plt.figure(figsize=(15,4)) -for i in range(3): - plot_data(times_dict[data_list[i]], - data_dict[data_list[i]], - data_list[i]) - - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Solution}$ -# -# There are a lot more GNSS data points than InSAR or groundwater. The GNSS observations also have more noise, and what seem to be outliers. In this case the mean and standard deviation do not mean much, because there is clearly a trend with time. We can at least confirm that the time periods of measurements overlap, although the intervals between measurements is certainly not uniform (note that you don't need to do anything with the times, since they are pandas time series and we have not covered them yet). -# </p> -# </div> - -# %% [markdown] -# You may have noticed that the groundwater data is available for different times than the GNSS and InSAR data. You will therefore have to *interpolate* the data to the same times for a further analysis. You can use the SciPy function ```interpolate.interp1d``` (read its [documentation](https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html)). -# -# The cells below do the following: -# 1. Define a function to convert the time unit -# 2. Convert the time stamps for all data -# 3. Use `interp1d` to interpolate the groundwater measurements at the time of the satellite measurements - -# %% -def to_days_years(times): - '''Convert the observation times to days and years.''' - - times_datetime = pd.to_datetime(times) - time_diff = (times_datetime - times_datetime[0]) - days_diff = (time_diff / np.timedelta64(1,'D')).astype(int) - - days = days_diff.to_numpy() - years = days/365 - - return days, years - - -# %% -days_gnss, years_gnss = to_days_years(times_gnss) -days_insar, years_insar = to_days_years(times_insar) -days_gw, years_gw = to_days_years(times_gw) - -interp = interpolate.interp1d(days_gw, y_gw) - -GW_at_GNSS_times = interp(days_gnss) -GW_at_InSAR_times = interp(days_insar) - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.2:</b> -# -# Answer/complete the code and Markdown cells below: -# <ol> -# <li>What is <code>interp</code>? (what kind of object is it, and how does it work?)</li> -# <li>How did the groundwater observation array change? Be quantitative. </li> -# </ol> -# -# </p> -# </div> - -# %% -# YOUR_CODE_HERE - -# SOLUTION: -print('array size of GW_at_GNSS_times', len(GW_at_GNSS_times)) -print('array size of GW_at_InSAR_times', len(GW_at_InSAR_times)) -print('array size of GW before interpolation', len(y_gw)) - -print('\nFirst values of times_gw:') -print(times_gw[0:2]) -print('\nFirst values of y_gw:') -print(y_gw[0:2]) -print('\nFirst values of times_gnss:') -print(times_gnss[0:2]) -print('\nFirst values of GW_at_GNSS_times:') -print(GW_at_GNSS_times[0:2]) - -# %% [markdown] -# **Write your answer in this Markdown cell.** - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Solution}$ -# <ol> -# <li><code>interp</code> is a function that will return a value (gw level) for the input(s) (date(s)). The interpolated value is found by linearly interpolating between the two nearest times in the gw observations.</li> -# <li>The observation arrays of <code>GW_at_GNSS_times</code> and <code>GW_at_INSAR_times</code> changed in size to match the size of the GNSS and InSAR observations, respectively.</li> -# </ol> -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.3:</b> -# -# Create a single plot to compare observed displacement for the GNSS and InSAR data sets. -# -# </p> -# </div> - -# %% -# plt.figure(figsize=(15,5)) -# plt.plot(YOUR_CODE_HERE, YOUR_CODE_HERE, -# 'o', mec='black', label = 'GNSS') -# plt.plot(YOUR_CODE_HERE, YOUR_CODE_HERE, -# 'o', mec='black', label = 'InSAR') -# plt.legend() -# plt.ylabel('Displacement [mm]') -# plt.xlabel('Time') -# plt.show() - -# SOLUTION: -plt.figure(figsize=(15,5)) -plt.plot(times_gnss, y_gnss, 'o', mec='black', label = 'GNSS') -plt.plot(times_insar, y_insar, 'o', mec='black', label = 'InSAR') -plt.legend() -plt.ylabel('Displacement [mm]') -plt.xlabel('Time') -plt.show() - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.4:</b> -# Describe the datasets based on the figure above and your observations from the previous tasks. What kind of deformation do you see? And what are the differences between both datasets? Be quantitative. -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Solution}$ -# -# The points obviously show subsidence, the displacement shows a similar pattern for both datasets. The GNSS data is much noisier than InSAR (range is around 60 mm versus only a few mm), but has a higher sampling rate. Also there seem to be more outliers in the GNSS data compared to InSAR, especially at the start of the observation period. InSAR has only observations every 6 days but is less noisy. -# </p> -# </div> - -# %% [markdown] -# Before we move on, it is time to do a little bit of housekeeping. -# -# Have you found it confusing to keep track of two sets of variables---one for each data type? Let's use a dictionary to store relevant information about each model. We will use this in the plotting functions for this task (and again next week), so make sure you take the time to see what is happening. Review also Part 0 at the top of this notebook if you need a refresher on dictionaries. - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 1.5:</b> -# -# Run the cell below to define a dictionary for storing information about the two (future) models. -# -# </p> -# </div> -# - -# %% -model_insar = {'data_type': 'InSAR', - 'y':y_insar, - 'times':times_insar, - 'groundwater': GW_at_InSAR_times - } - -model_gnss = {'data_type': 'GNSS', - 'y':y_gnss, - 'times':times_gnss, - 'groundwater': GW_at_GNSS_times - } - -# %% [markdown] id="76c9115b" -# ## Task 2: Set-up linear functional model -# -# We want to investigate how we could model the observed displacements of the road. Because the road is built in the Green Heart we expect that the observed displacements are related to the groundwater level. Furthermore, we assume that the displacements can be modeled using a constant velocity. The model is defined as -# $$ -# d = d_0 + vt + k \ \textrm{GW}, -# $$ -# where $d$ is the displacement, $t$ is time and $\textrm{GW}$ is the groundwater level (that we assume to be deterministic). -# -# Therefore, the model has 3 unknowns: -# 1. $d_0$, as the initial displacement at $t_0$; -# 2. $v$, as the displacement velocity; -# 3. $k$, as the 'groundwater factor', which can be seen as the response of the soil to changes in the groundwater level. -# -# -# As a group you will construct the **functional model** that is defined as -# $$ -# \mathbb{E}(Y) = \mathrm{A x}. -# $$ -# -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.1:</b> -# -# Construct the design matrix $A$ (for both InSAR and GNSS observations), then show the first 5 observations and confirm the dimensions of $A$. -# </p> -# </div> - -# %% -# YOUR_CODE_HERE - -# SOLUTION: -A_insar = np.ones((len(times_insar), 3)) -A_insar[:,1] = days_insar -A_insar[:,2] = GW_at_InSAR_times - -print ('The first 5 rows of the A matrix (InSAR) are:') -print (A_insar[0:5, :]) - -print ('The first 5 observations [mm] of y_insar are:') -print (y_insar[0:5]) - -m_insar = np.shape(A_insar)[0] -n_insar = np.shape(A_insar)[1] -print(f'm = {m_insar} and n = {n_insar}') - -# %% -# YOUR_CODE_HERE - -# SOLUTION: -A_gnss = np.ones((len(times_gnss), 3)) -A_gnss[:,1] = days_gnss -A_gnss[:,2] = GW_at_GNSS_times - -print ('The first 5 rows of the A matrix (GNSS) are:') -print (A_gnss[0:5, :]) - -print ('\nThe first 5 observations [mm] of y_gnss are:') -print (y_gnss[0:5]) - -m_gnss = np.shape(A_gnss)[0] -n_gnss = np.shape(A_gnss)[1] -print(f'm = {m_gnss} and n = {n_gnss}') - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Task 2.2}$ -# -# Answer the following questions: -# -# - What is the dimension of the observables' vector $Y$? -# - What are the unknowns of the functional model? -# - What is the redundancy for this model? -# -# </p> -# </div> -# - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Solution}$ -# -# For InSAR: -# <ol> -# <li>The number of observations is 61.</li> -# <li>The number of unknowns is 3.</li> -# <li>The redundancy is 58.</li> -# </ol> -# -# For GNSS: -# <ol> -# <li>The number of observations is 730.</li> -# <li>The number of unknowns is 3.</li> -# <li>The redundancy is 727.</li> -# </ol> -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 2.3:</b> -# -# Add the A matrix to the dictionaries for each model. This will be used to plot results later in the notebook. -# -# </p> -# </div> -# - -# %% -# model_insar['A'] = YOUR_CODE_HERE -# model_gnss['A'] = YOUR_CODE_HERE - -# SOLUTION: -model_insar['A'] = A_insar -model_gnss['A'] = A_gnss - -print("Keys and Values (type) for model_insar:") -for key, value in model_insar.items(): - print(f"{key:16s} --> {type(value)}") -print("\nKeys and Values (type) for model_gnss:") -for key, value in model_gnss.items(): - print(f"{key:16s} --> {type(value)}") - -# %% [markdown] id="9325d32b" -# ## 3. Set-up stochastic model -# -# We will use the Best Linear Unbiased Estimator (BLUE) to solve for the unknown parameters. Therefore we also need a stochastic model, which is defined as -# $$ -# \mathbb{D}(Y) = \Sigma_{Y}. -# $$ -# where $\Sigma_{Y}$ is the covariance matrix of the observables' vector. -# -# -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 3.1:</b> -# -# Construct the covariance matrix for each type of data and assume that -# -# - the observables are independent -# -# - the observables are normally distributed -# -# - the observables' standard deviation is -# -# - $\sigma_\textrm{InSAR} = 2$ mm -# - $\sigma_\textrm{GNSS} = 15$ mm -# -# </p> -# </div> -# - -# %% colab={"base_uri": "https://localhost:8080/"} executionInfo={"elapsed": 40, "status": "ok", "timestamp": 1664699881875, "user": {"displayName": "C Yin", "userId": "14075875094781565898"}, "user_tz": -120} id="163acdb3" outputId="8bc99da3-a61e-4a25-8a54-c90f33299a57" -# YOUR_CODE_HERE - -# SOLUTION: -std_insar = 2 #mm - -Sigma_Y_insar = np.identity(len(times_insar))*std_insar**2 - -print ('Sigma_Y (InSAR) is defined as:') -print (Sigma_Y_insar) - -# %% -# YOUR_CODE_HERE - -# SOLUTION: -std_gnss = 15 #mm (corrected from original value of 5 mm) - -Sigma_Y_gnss = np.identity(len(times_gnss))*std_gnss**2 - -print ('\nSigma_Y (GNSS) is defined as:') -print (Sigma_Y_gnss) - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Task 3.2}$ -# -# Answer the following questions: -# -# - What information is contained in the covariance matrix? -# - How do you implement the assumption that all observations are independent? -# - What is the dimension of $\Sigma_{Y}$? -# - How do you create $\Sigma_{Y}$? -# -# </p> -# </div> - -# %% [markdown] -# _Write your answer in this cell._ - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Solution}$ -# -# - The covariance matrix contains information on the quality of the observations, where an entry on the diagonal represents the variance of one observation at a particular epoch. If there is an indication that for instance the quality for a particular time interval differs, different $\sigma$ values can be put in the stochastic model for these epochs. -# - The off-diagonal terms in the matrix are related to the correlation between observations at different epochs, where a zero value on the off-diagonal indicates zero correlation. -# - The dimension of the matrix is 61x61 for InSAR and 730x730 for GNSS. -# - See code. -# </p> -# </div> - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 3.3:</b> -# -# Add <code>Sigma_Y</code> to the dictionaries for each model. -# -# </p> -# </div> -# - -# %% -# model_insar['Sigma_Y] = YOUR_CODE_HERE -# model_gnss['Sigma_Y'] = YOUR_CODE_HERE - -# SOLUTION: -model_insar['Sigma_Y'] = Sigma_Y_insar -model_gnss['Sigma_Y'] = Sigma_Y_gnss - - -# %% [markdown] id="09e965bf" -# ## 4. Apply best linear unbiased estimation -# -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 4.1:</b> -# -# Write a function to apply BLUE in the cell below and use the function to estimate the unknowns for the model using the data. -# -# Compute the modeled displacements ($\hat{\mathrm{y}}$), and corresponding residuals ($\hat{\mathrm{\epsilon}}$), as well as associated values (as requested by the blank code lines). -# </p> -# </div> -# -# - -# %% [markdown] -# <div style="background-color:#facb8e; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> <p><strong>Note on code implementation</strong>: you'll see that the functions in this assignment use a dictionary; this greatly reduces the number of input/output variables needed in a function. However, it can make the code inside the function more difficult to read due to the key syntax (e.g., <code>dict['variable_1']</code> versus <code>variable -# _1</code>). To make this assignment easier for you to implement we have split these functions into three parts: 1) define variables from the dictionary, 2) perform analysis, 3) add results to the dictionary. Note that this is not the most efficient way to write this code; it is done here specifically for clarity and to help you focus on writing the equations properly and understanding the meaning of each term.</p></div> - -# %% -def BLUE(d): - """Calculate the Best Linear Unbiased Estimator - - Uses dict as input/output: - - inputs defined from existing values in dict - - outputs defined as new values in dict - """ - - y = d['y'] - A = d['A'] - Sigma_Y = d['Sigma_Y'] - - # Sigma_X_hat = YOUR_CODE_HERE - # x_hat = YOUR_CODE_HERE - - # y_hat = YOUR_CODE_HERE - - # e_hat = YOUR_CODE_HERE - - # Sigma_Y_hat = YOUR_CODE_HERE - # std_y = YOUR_CODE_HERE - - # Sigma_e_hat = YOUR_CODE_HERE - # std_e_hat = YOUR_CODE_HERE - - # SOLUTION: - Sigma_X_hat = np.linalg.inv(A.T @ np.linalg.inv(Sigma_Y) @ A) - x_hat = Sigma_X_hat @ A.T @ np.linalg.inv(Sigma_Y) @ y - - y_hat = A @ x_hat - - e_hat = y - y_hat - - Sigma_Y_hat = A @ Sigma_X_hat @ A.T - std_y = np.sqrt(Sigma_Y_hat.diagonal()) - - Sigma_e_hat = Sigma_Y - Sigma_Y_hat - std_e_hat = np.sqrt(Sigma_e_hat.diagonal()) - - d['Sigma_X_hat'] = Sigma_X_hat - d['x_hat'] = x_hat - d['y_hat'] = y_hat - d['e_hat'] = e_hat - d['Sigma_Y_hat'] = Sigma_Y_hat - d['std_y'] = std_y - d['Sigma_e_hat'] = Sigma_e_hat - d['std_e_hat'] = std_e_hat - - return d - - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 4.2:</b> -# -# Now that you have completed the function, apply it to our two models and then print values for the estimated parameters. -# </p> -# </div> -# -# - -# %% -model_insar = BLUE(model_insar) -x_hat_insar = model_insar['x_hat'] - -# YOUR_CODE_HERE - -# SOLUTION: -print ('The InSAR-estimated offset is', np.round(x_hat_insar[0],3), 'mm') -print ('The InSAR-estimated velocity is', np.round(x_hat_insar[1],4), 'mm/day') -print ('The InSAR-estimated velocity is', np.round(x_hat_insar[1]*365,4), 'mm/year') -print ('The InSAR-estimated GW factor is', np.round(x_hat_insar[2],3), '[-]\n') - -model_gnss = BLUE(model_gnss) -x_hat_gnss = model_gnss['x_hat'] - -# YOUR_CODE_HERE - -# SOLUTION: -print ('The GNSS-estimated offset is', np.round(x_hat_gnss[0],3), 'mm') -print ('The GNSS-estimated velocity is', np.round(x_hat_gnss[1],4), 'mm/day') -print ('The GNSS-estimated velocity is', np.round(x_hat_gnss[1]*365,4), 'mm/year') -print ('The GNSS-estimated GW factor is', np.round(x_hat_gnss[2],3), '[-]') - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 4.3:</b> -# Do the values that you just estimated make sense? Explain, using quantitative results. -# -# <em>Hint: all you need to do is use the figures created above to verify that the parameter values printed above are reasonable (e.g., order of magnitude, units, etc).</em> -# </p> -# </div> -# -# - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Solution}$ -# -# As long as the velocity is negative and around -0.02 mm/day or -10 mm/yr it makes sense if you compare with what you see in the plots with observations. Since load is applied on soil layers we expect the road to subside. We also expect to see a positive value for the GW factor. -# -# </p> -# </div> - -# %% [markdown] id="65e42a43" -# ## 5. Evaluate the precision -# -# - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 5:</b> -# -# What is the precision of the final estimates? -# -# Print the full covariance matrix of your estimates, and give an interpretation of the numbers in the covariance matrix. -# </p> -# </div> -# -# - -# %% colab={"base_uri": "https://localhost:8080/"} executionInfo={"elapsed": 16, "status": "ok", "timestamp": 1664699882186, "user": {"displayName": "C Yin", "userId": "14075875094781565898"}, "user_tz": -120} id="835eefc8" outputId="ad47d53d-c147-4b25-fb03-b967a3bb6f96" -Sigma_X_hat_insar = model_insar['Sigma_X_hat'] - -# YOUR_CODE_HERE - -# SOLUTION: -print ('Covariance matrix of estimated parameters (InSAR):') -print (Sigma_X_hat_insar) -print ('\nThe standard deviation for the InSAR-estimated offset is', - np.round(np.sqrt(Sigma_X_hat_insar[0,0]),3), 'mm') -print ('The standard deviation for the InSAR-estimated velocity is', - np.round(np.sqrt(Sigma_X_hat_insar[1,1]),4), 'mm/day') -print ('The standard deviation for the InSAR-estimated GW factor is', - np.round(np.sqrt(Sigma_X_hat_insar[2,2]),3), '[-]\n') - -Sigma_X_hat_gnss = model_gnss['Sigma_X_hat'] - -# YOUR_CODE_HERE - -# SOLUTION: -print ('Covariance matrix of estimated parameters (GNSS):') -print (Sigma_X_hat_gnss) -print ('\nThe standard deviation for the GNSS-estimated offset is', - np.round(np.sqrt(Sigma_X_hat_gnss[0,0]),3), 'mm') -print ('The standard deviation for the GNSS-estimated velocity is', - np.round(np.sqrt(Sigma_X_hat_gnss[1,1]),4), 'mm/day') -print ('The standard deviation for the GNSS-estimated GW factor is', - np.round(np.sqrt(Sigma_X_hat_gnss[2,2]),3), '[-]') - - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Solution}$ -# -# As shown above, the standard deviations of the estimated parameters are equal to the square root of the diagonal elements. Compared with the estimated values, the standard deviations seem quite small, except for the estimated offsets. Meaning that the complete estimated model can be shifted up or down. -# -# The off-diagonal elements show the covariances between the estimated parameters, which are non-zeros since the estimates are all computed as function of the same vector of observations and the same model. A different value for the estimated velocity would imply a different value for the GW factor and offset. -# -# </p> -# </div> - -# %% [markdown] id="886efe26" -# ## 6. Present and reflect on estimation results - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 6.1:</b> -# -# Complete the function below to help us compute the confidence intervals, then apply the function. Use a confidence interval of 96% in your analysis. -# -# <em>Hint: it can be used in exactly the same way as the <code>BLUE</code> function above, although it has one extra input.</em> -# </p> -# </div> -# - -# %% -def get_CI(d, alpha): - """Compute the confidence intervals. - - Uses dict as input/output: - - inputs defined from existing values in dict - - outputs defined as new values in dict - """ - - std_e_hat = d['std_e_hat'] - std_y = d['std_y'] - - # k = YOUR_CODE_HERE - # CI_y = YOUR_CODE_HERE - # CI_res = YOUR_CODE_HERE - - # SOLUTION: - k = norm.ppf(1 - 0.5*alpha) - CI_y = k*std_y - CI_res = k*std_e_hat - CI_y_hat = k*np.sqrt(d['Sigma_Y_hat'].diagonal()) - - d['alpha'] = alpha - d['CI_y'] = CI_y - d['CI_res'] = CI_res - d['CI_Y_hat'] = CI_y_hat - - return d - - -# %% -# model_insar = YOUR_CODE_HERE -# model_gnss = YOUR_CODE_HERE - -# SOLUTION: -model_insar = get_CI(model_insar, 0.04) -model_gnss = get_CI(model_gnss, 0.04) - -# %% [markdown] -# At this point we have all the important results entered in our dictionary and we will be able to use the plots that have been written for you in the next Tasks. In case you would like to easily see all of the key-value pairs that have been added to the dictionary, you can run the cell below: - -# %% -print("Keys and Values (type) for model_insar:") -for key, value in model_insar.items(): - print(f"{key:16s} --> {type(value)}") -print("\nKeys and Values (type) for model_gnss:") -for key, value in model_gnss.items(): - print(f"{key:16s} --> {type(value)}") - -# %% [markdown] -# <div style="background-color:#AABAB2; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# <b>Task 6.2:</b> -# -# Read the contents of file <code>functions.py</code> and identify what it is doing: you should be able to recognize that they use our model dictionary as an input and create three different figures. Note also that the function to create the figures have already been imported at the top of this notebook. -# -# Use the functions provided to visualize the results of our two models. -# </p> -# </div> -# - -# %% [markdown] id="0491cc69" -# <div style="background-color:#facb8e; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> <p><strong>Note</strong>: remember that you will have to use the same function to look at <em>both</em> models when writing your interpretation in the Report.</p></div> - -# %% -# _, _ = plot_model(YOUR_CODE_HERE) - -# SOLUTION: -_, _ = plot_model(model_insar) -_, _ = plot_model(model_gnss) - -# %% -# _, _ = plot_residual(YOUR_CODE_HERE) - -# SOLUTION: -_, _ = plot_residual(model_insar) -_, _ = plot_residual(model_gnss) - -# %% -# _, _ = plot_residual_histogram(YOUR_CODE_HERE) - -# SOLUTION: -_, _ = plot_residual_histogram(model_insar) -_, _ = plot_residual_histogram(model_gnss) - -# %% [markdown] -# <div style="background-color:#FAE99E; color: black; width:95%; vertical-align: middle; padding:15px; margin: 10px; border-radius: 10px"> -# <p> -# -# $\textbf{Solution: the True Model}$ -# -# The data used in this exercise was generated using Monte Carlo Simulation. It is added to the plots here to illustrate where and how our models differ (it is your job to interpret "why"). -# </p> -# </div> - -# %% -k_true = 0.15 -R_true = -22 -a_true = 180 -d0_true = 10 - -disp_insar = (d0_true + R_true*(1 - np.exp(-days_insar/a_true)) + - k_true*GW_at_InSAR_times) -disp_gnss = (d0_true + R_true*(1 - np.exp(-days_gnss/a_true)) + - k_true*GW_at_GNSS_times) - -plot_model(model_insar, alt_model=('True model', times_insar, disp_insar)); -plot_model(model_gnss, alt_model=('True model', times_gnss, disp_gnss)); - -# %% -import ipywidgets as widgets -from ipywidgets import interact - -# Function to update the plot based on slider values -def update_plot(x0, x1, x2): - plt.figure(figsize=(15,5)) - for m in [model_gnss]: #[model_insar, model_gnss]: - plt.plot(m['times'], m['y'], 'o', label=m['data_type']) - plt.ylabel('Displacement [mm]') - plt.xlabel('Time') - - y_fit = model_gnss['A'] @ [x0, x1, x2] - if (x0 == 0) & (x1 == 0) & (x2 == 1): - plt.plot(model_gnss['times'], y_fit, 'r', label='Groundwater data', linewidth=2) - else: - plt.plot(model_gnss['times'], y_fit, 'r', label='Fit (GNSS)', linewidth=2) - - W = np.linalg.inv(model_gnss['Sigma_Y']) - ss_res = (model_gnss['y'] - y_fit).T @ W @ (model_gnss['y'] - y_fit) - plt.title(f'Mean of squared residuals: {ss_res:.0f}') - plt.grid() - plt.legend() - plt.show() - -# Create sliders for x0, x1, and x2 -x0_slider = widgets.FloatSlider(value=0, min=-10, max=10, step=0.1, description='x0') -x1_slider = widgets.FloatSlider(value=0, min=-0.1, max=0.1, step=0.001, description='x1') -x2_slider = widgets.FloatSlider(value=0, min=-1, max=1, step=0.01, description='x2') - -# Use interact to create the interactive plot -interact(update_plot, x0=x0_slider, x1=x1_slider, x2=x2_slider) - - -# %% -xhat_slider_plot(model_gnss['A'], model_gnss['y'], model_gnss['times'], model_gnss['Sigma_Y']) - -# %% [markdown] -# **End of notebook.** -# <h2 style="height: 60px"> -# </h2> -# <h3 style="position: absolute; display: flex; flex-grow: 0; flex-shrink: 0; flex-direction: row-reverse; bottom: 60px; right: 50px; margin: 0; border: 0"> -# <style> -# .markdown {width:100%; position: relative} -# article { position: relative } -# </style> -# <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"> -# <img alt="Creative Commons License" style="border-width:; width:88px; height:auto; padding-top:10px" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /> -# </a> -# <a rel="TU Delft" href="https://www.tudelft.nl/en/ceg"> -# <img alt="TU Delft" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/tu-logo/TU_P1_full-color.png" /> -# </a> -# <a rel="MUDE" href="http://mude.citg.tudelft.nl/"> -# <img alt="MUDE" style="border-width:0; width:100px; height:auto; padding-bottom:0px" src="https://gitlab.tudelft.nl/mude/public/-/raw/main/mude-logo/MUDE_Logo-small.png" /> -# </a> -# -# </h3> -# <span style="font-size: 75%"> -# © Copyright 2024 <a rel="MUDE" href="http://mude.citg.tudelft.nl/">MUDE</a> TU Delft. This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0 License</a>.