Skip to content

Commit

Permalink
Updated lecture 2
Browse files Browse the repository at this point in the history
mmoelle1 committed Nov 28, 2024
1 parent 59b3e8e commit ed2817d
Showing 1 changed file with 97 additions and 60 deletions.
157 changes: 97 additions & 60 deletions notebooks/lecture2_pretty.ipynb
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@
},
"id": "59398614",
"cell_type": "markdown",
"source": "# Task: Dot product\n\nWrite a $\\mathrm{C}++$ code that computes the dot product\n$$\na \\cdot b=\\sum_{i=1}^n a_i b_i\n$$\nof two vectors $a=\\left[a_1, a_2, \\ldots, a_n\\right]$ and $b=\\left[b_1, b_2, \\ldots, b_n\\right]$ and terminates if the two vectors have different length."
"source": "# Task: Dot product\n\nWrite a C++ code that computes the dot product\n$$\na \\cdot b=\\sum_{i=1}^n a_i b_i\n$$\nof two vectors $a=\\left[a_1, a_2, \\ldots, a_n\\right]$ and $b=\\left[b_1, b_2, \\ldots, b_n\\right]$ and terminates if the two vectors have different length."
},
{
"metadata": {
@@ -28,7 +28,7 @@
},
"id": "00de1935",
"cell_type": "markdown",
"source": "# Dot product function\n\nThe main functionality without any fail-safe checks"
"source": "# Dot product function\n\nThe main functionality of the ```dot_product``` function without any fail-safe checks"
},
{
"metadata": {
@@ -50,7 +50,7 @@
},
"id": "6bfb7f00",
"cell_type": "markdown",
"source": "# Dot product function - improved version\n\nFirst version of the dot product with exception"
"source": "# Dot product function - improved version\n\nFirst version of the ```dot_product``` function _with_ fail-safe checks"
},
{
"metadata": {
@@ -67,13 +67,22 @@
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"cell_type": "markdown",
"source": "Creation of two vectors and use of the ```dot_product``` function"
},
{
"metadata": {
"slideshow": {
"slide_type": "-"
},
"tags": [],
"trusted": false
},
"id": "a56e3e96-c884-4b16-aeb9-fbf84fddc800",
"cell_type": "code",
"source": "#include <iostream>\n\ndouble x[5] = { 1, 2, 3, 4, 5 };\ndouble y[4] = { 1, 2, 3, 4 };\ntry {\n double d = dot_product(x, 5, y, 4);\n} catch (const std::exception &e) {\n std::cout << e.what() << std::endl;\n}",
"source": "#include <iostream>\n\ndouble x[5] = { 1, 2, 3, 4, 5 };\ndouble y[4] = { 1, 2, 3, 4 };\n\ntry {\n double d = dot_product(x, 5, y, 4);\n} catch (const std::exception &e) {\n std::cout << e.what() << std::endl;\n}",
"execution_count": null,
"outputs": []
},
@@ -105,7 +114,7 @@
},
"id": "5a0bb6d1",
"cell_type": "markdown",
"source": "# Flashback: Object Oriented Programming\n<p>Imagine each LEGO block as a piece of data (like an integer, string, etc.). A <code>struct</code> or a <code>class</code> is like a LEGO set that contains a variety of different blocks.</p>\n<ul>\n <li>OOP: bundle data (e.g. <code>array</code>) and functionality (e.g. <code>length</code>) into a <code>struct</code> or <code>class</code>\n </li>\n <li> Components of a <span style = \"color:red;\">struct</span> are <code>public</code> (=can be accessed from\noutside the struct) by default\n </li>\n <li> Components of a <span style = \"color:red;\">class</span> are <code>private</code> (=cannot be accessed\nfrom outside the class) by default\n </li>\n <li> Components of a struct/class are <span style = \"color:red;\">attributes</span> and <span style = \"color:red;\">member\nfunctions (=methods)</span>\n </li>\n</ul>"
"source": "# Flashback: Object Oriented Programming\n\nImagine each LEGO block as a piece of data (like an integer, string, etc.). A ```struct``` or a ```class``` is like a LEGO set that contains a variety of different blocks.\n\n- OOP: bundle data (e.g. ```array```) and functionality (e.g. ```length```) into a ```struct``` or ```class``` \n- Components of a <span style = \"color:red;\">struct</span> are ```public``` (=can be accessed from outside the struct) by default\n- Components of a <span style = \"color:red;\">class</span> are ```private``` (=cannot be accessed from outside the class) by default\n- Components of a struct/class are <span style =\"color:red;\">attributes</span> and <span style = \"color:red;\">member\nfunctions (=methods)</span>\n"
},
{
"metadata": {
@@ -147,7 +156,7 @@
},
"id": "25f6d0fa",
"cell_type": "markdown",
"source": "<p>__When to use <code>class</code> and when to use <code>struct</code>?__</p>\n<ul><li><code>struct</code> is typically used when you want to group data together without needing to restrict access to it. It is straightforward and simple. Many type traits (later in this course) are implemented as <code>struct</code>s.\n </li>\n <li> <code>class</code> is typically used when you want more control over the data and the interface through which it is accessed and manipulated, promoting the principles of encapsulation and data hiding.\n </li>\n </ul>"
"source": "__When to use ```class``` and when to use ```struct```?__\n\n- ```struct``` is typically used when you want to group data together without needing to restrict access to it. It is straightforward and simple. Many type traits (later in this course) are implemented as ```struct```s.\n- ```class``` is typically used when you want more control over the data and the interface through which it is accessed and manipulated, promoting the principles of encapsulation and data hiding."
},
{
"metadata": {
@@ -157,7 +166,7 @@
},
"id": "5fb04b49",
"cell_type": "markdown",
"source": "# Dot product as a member function of Vector\n\nSecond version of the dot product using Vector class or struct"
"source": "# Dot product as a member function of Vector\n\nSecond version of the ```dot_product``` function"
},
{
"metadata": {
@@ -166,7 +175,7 @@
},
"id": "637fbc76",
"cell_type": "code",
"source": "#include <exception>\n\nclass Vector{\n public:\n double* array;\n int length;\n \n double dot_product(const Vector& a, const Vector& b)\n {\n if(a.length != b.length) \n throw std::invalid_argument(\"Vector lengths mismatch\");\n \n double d=0.0;\n for (auto i=0; i<a.length; i++)\n d += a.array[i]*b.array[i];\n return d;\n } \n};",
"source": "#include <exception>\n\nclass Vector {\n public:\n double* array;\n int length;\n \n double dot_product(const Vector& a, const Vector& b)\n {\n if (a.length != b.length) \n throw std::invalid_argument(\"Vector lengths mismatch\");\n \n double d=0.0;\n for (auto i=0; i<a.length; i++)\n d += a.array[i]*b.array[i];\n return d;\n } \n};",
"execution_count": null,
"outputs": []
},
@@ -176,7 +185,7 @@
},
"id": "9065c92c",
"cell_type": "markdown",
"source": "Access of members of a <code>struct</code> or <code>class</code> by __dot-notation („.“)__"
"source": "Access of members of a ```struct``` or ```class``` by __dot-notation (\".\")__"
},
{
"metadata": {
@@ -196,7 +205,7 @@
},
"id": "2756e20a-199a-40dd-b041-714151eb5308",
"cell_type": "code",
"source": "#include <iostream>\n\nVector x,y;\nx.array = new double[5]; x.length = 5;\ny.array = new double[5]; y.length = 5;\nfor (int i = 0; i < 5; ++i) {\n x.array[i] = i + 1; // 1, 2, 3, 4, 5\n y.array[i] = i + 1; // 1, 2, 3, 4, 5\n}\n \ntry {\n double result = /** ??? **/;\n } catch (const std::exception &e) {\n std::cout << e.what() << std::endl;\n}",
"source": "#include <iostream>\n\nVector x,y;\nx.array = new double[5]; x.length = 5;\ny.array = new double[5]; y.length = 5;\n\nfor (int i = 0; i < 5; ++i) {\n x.array[i] = i + 1; // 1, 2, 3, 4, 5\n y.array[i] = i + 1; // 1, 2, 3, 4, 5\n}\n \ntry {\n double result = /** ??? **/;\n} catch (const std::exception &e) {\n std::cout << e.what() << std::endl;\n}",
"execution_count": null,
"outputs": []
},
@@ -206,7 +215,7 @@
},
"id": "3df90be7-9c6c-4cc3-bbf7-f68c6bd7bc65",
"cell_type": "markdown",
"source": "The current implementation of the <code>dot_product</code> function comes from functional programming and is not OOP style because it takes two input arguments `x` and `y` and returns one output argument, the dot product. In other words, it is not attached to any object (`x` or `y`)."
"source": "The current implementation of the `dot_product` function comes from functional programming and is not OOP style because it takes two input arguments `x` and `y` and returns one output argument, the dot product. In other words, it is not attached to any object (`x` or `y`)."
},
{
"metadata": {
@@ -217,7 +226,7 @@
},
"id": "d23d2ba6-1233-4569-86cb-7472c77fbd74",
"cell_type": "markdown",
"source": "If we want to implement a function inside a <code>class</code> or <code>struct</code> that is not attached to an object we have to define it as <code>static</code>"
"source": "If we want to implement a function inside a ```class``` or ```struct``` that is not attached to an object we have to define it as ```static```"
},
{
"metadata": {
@@ -226,7 +235,7 @@
},
"id": "8d394c98",
"cell_type": "code",
"source": "#include <exception>\n\nclass Vector{\n public:\n double* array;\n int length;\n \n double dot_product(const Vector& a, const Vector& b)\n {\n if(a.length != b.length) \n throw std::invalid_argument(\"Vector lengths mismatch\");\n \n double d=0.0;\n for (auto i=0; i<a.length; i++)\n d += a.array[i]*b.array[i];\n return d;\n } \n};",
"source": "#include <exception>\n\nclass Vector {\n public:\n double* array;\n int length;\n \n static double dot_product(const Vector& a, const Vector& b)\n {\n if (a.length != b.length) \n throw std::invalid_argument(\"Vector lengths mismatch\");\n \n double d=0.0;\n for (auto i=0; i<a.length; i++)\n d += a.array[i]*b.array[i];\n return d;\n } \n};",
"execution_count": null,
"outputs": []
},
@@ -239,7 +248,7 @@
},
"id": "f5bbb4da-b866-4f1d-9578-f851f6215557",
"cell_type": "markdown",
"source": "<code>static</code> member functions are invoked with the full classname (comparable to namespaces)"
"source": "```static``` member functions are invoked with the full classname (comparable to namespaces)"
},
{
"metadata": {
@@ -248,7 +257,7 @@
},
"id": "767a8d52-d3fa-4ce2-90c5-5cab12bdf449",
"cell_type": "code",
"source": "#include <iostream>\n\nVector x,y;\nx.array = new double[5]; x.length = 5;\ny.array = new double[5]; y.length = 5;\nfor (int i = 0; i < 5; ++i) {\n x.array[i] = i + 1; // 1, 2, 3, 4, 5\n y.array[i] = i + 1; // 1, 2, 3, 4, 5\n}\n \ntry {\n double result = Vector::dot_product(x, y);\n } catch (const std::exception &e) {\n std::cout << e.what() << std::endl;\n}",
"source": "#include <iostream>\n\nVector x,y;\nx.array = new double[5]; x.length = 5;\ny.array = new double[5]; y.length = 5;\n\nfor (int i = 0; i < 5; ++i) {\n x.array[i] = i + 1; // 1, 2, 3, 4, 5\n y.array[i] = i + 1; // 1, 2, 3, 4, 5\n}\n \ntry {\n double result = Vector::dot_product(x, y);\n} catch (const std::exception &e) {\n std::cout << e.what() << std::endl;\n}",
"execution_count": null,
"outputs": []
},
@@ -260,7 +269,7 @@
},
"id": "412bd54a",
"cell_type": "markdown",
"source": "<ul>\n<li> It is still possible to initialise <code>x.length</code> by the wrong value, e.g.,\n </li>\n <p><code>x.array = new double[5] {1, 2, 3, 4, 5}; x.length = 4;</code></p>\n <li>The main function is not very readable due to the lengthy\ndeclaration, initialisation and deletion of data\n </li>\n <li>OOP solution:\n </li>\n <ul>\n <li>__Constructor(s):__ <span style=\"color:red;\">method</span> to construct a new <span style=\"color:red;\">Vector object</span>\n </li>\n <li>__Destructor:__ <span style=\"color:red;\">method</span> to destruct an existing <span style=\"color:red;\">Vector object</span>\n </li>\n </ul>\n</ul>"
"source": "- It is still possible to initialise ```x.length``` by the wrong value, e.g.,\n ```cpp\n x.array = new double[5] {1, 2, 3, 4, 5}; \n x.length = 4;\n ```\n- The main function is not very readable due to the lengthy declaration, initialization and deletion of data\n- OOP solution:\n - __Constructor(s):__ <span style=\"color:red;\">method</span> to construct a new <span style=\"color:red;\">Vector object</span>\n - __Destructor:__ <span style=\"color:red;\">method</span> to destruct an existing <span style=\"color:red;\">Vector object</span>"
},
{
"metadata": {
@@ -330,7 +339,7 @@
},
"id": "4034efd6",
"cell_type": "code",
"source": "class Vector\n{\n public:\n double* array;\n int length;\n \n Vector(int length) // Another constructor\n {\n // this pointer refers to the object itself,\n // hence this->length is the attribute and length\n // is the parameter passed to the constructor\n\n array = new double[length];\n this->length = length;\n }\n}; ",
"source": "class Vector\n{\n public:\n double* array;\n int length;\n \n Vector(int length) // Another constructor\n {\n // The 'this' pointer refers to the object itself,\n // hence this->length is the attribute and length\n // is the parameter passed to the constructor\n\n array = new double[length];\n this->length = length;\n }\n}; ",
"execution_count": null,
"outputs": []
},
@@ -412,7 +421,7 @@
},
"id": "c0b1a899",
"cell_type": "markdown",
"source": "# Delegating constructor (C++11)\n\nCan we delegate some of the work"
"source": "# Delegating constructor (C++11)\n\nCan we delegate some of the work?"
},
{
"metadata": {
@@ -446,7 +455,21 @@
},
"id": "5378508f",
"cell_type": "markdown",
"source": "# Quiz\n<div class=\"left1\", style=\"width:50%;height:90%; float:left;\">\n <ul>\n <li><code>Vector(int len)\n : length(len),\n array(new double[len])\n {}</code></li>\n <li><code>Vector(int len)\n : array(new double[len]),\n length(len)\n {}</code>\n </li>\n </ul>\n</div>\n<div class=\"right1\", style=\"width:50%;height:90%; float:right;\">\n <ul>\n <li><code>Vector(int len)\n : length(len),\n array(new double[lengh])\n {}</code></li>\n <li><code>Vector(int len)\n : array(new double[length]),\n length(len)\n {}</code>\n </li>\n </ul>\n</div>"
"source": "# Quiz: Which of the following codes is wrong?"
},
{
"metadata": {
"cell_style": "split"
},
"cell_type": "markdown",
"source": "- Code 1\n ```cpp\n Vector(int len)\n : length(len), \n array(new double[len])\n {}\n\n ```\n\n- Code 2\n ```cpp\n Vector(int len)\n : array(new double[len]), \n length(len)\n {}\n\n ```"
},
{
"metadata": {
"cell_style": "split"
},
"cell_type": "markdown",
"source": "- Code 3\n ```cpp\n Vector(int len)\n : length(len),\n array(new double[lengh])\n {}\n\n ```\n\n- Code 4\n ```cpp\n Vector(int len)\n : array(new double[length]),\n length(len)\n {}\n\n ```"
},
{
"metadata": {
@@ -457,7 +480,7 @@
},
"id": "0fd11e67",
"cell_type": "markdown",
"source": "If you have multiple constructors with increasing functionality, __delegating constructors__ can be really helpful to remove duplicate code, e.g.\n\n<code>Vector(const std::initializer_list&ltdouble>& list)\n: Vector((int)list.size())\n{\n std::uninitialized_copy(list.begin(),\n list.end(), array);\n}</code>"
"source": "If you have multiple constructors with increasing functionality, __delegating constructors__ can be really helpful to remove duplicate code, e.g.\n\n```cpp\nVector(const std::initializer_list<double>& list)\n : Vector((int)list.size())\n {\n std::uninitialized_copy(list.begin(), list.end(), array);\n }\n```"
},
{
"metadata": {
@@ -468,7 +491,7 @@
},
"id": "58ab6c05",
"cell_type": "markdown",
"source": "# Function -> member function\n\nFunction that computes the sum of a Vector\n\n```cpp\nstatic double sum(const Vector& a)\n{\n double s = 0;\n for (auto i=0; i&lta.length; i++)\n s += a.array[i];\n return s;\n}\n```\n\nThis is not really OOP-style!\n\n```cpp\nint main() {\n Vector x = { 1, 2, 3, 4, 5 };\n std::cout &lt< sum(x) &lt< std::endl; \n}\n```"
"source": "# Turning a stand-alone function into a member function\n\nFunction that computes the sum of a Vector\n\n```cpp\nstatic double sum(const Vector& a)\n{\n double s = 0;\n for (auto i=0; i<a.length; i++)\n s += a.array[i];\n return s;\n}\n```\n\nThis is not really OOP-style!\n\n```cpp\nint main() {\n Vector x = { 1, 2, 3, 4, 5 };\n std::cout << sum(x) << std::endl; \n}\n```"
},
{
"metadata": {
@@ -504,7 +527,7 @@
},
"id": "fe1a3a38",
"cell_type": "markdown",
"source": " This is good OOP-style\n\n```cpp\nVector v = {1.0, 2.0, 3.0};\nstd::cout << v.sum() << std::endl;\n```"
"source": " This is good OOP-style\n\n```cpp\nVector v = {1, 2, 3};\nstd::cout << v.sum() << std::endl;\n```"
},
{
"metadata": {
@@ -538,7 +561,7 @@
},
"id": "a16793a3",
"cell_type": "markdown",
"source": "This is good OOP-style\n\n```cpp\nint main()\n{\n Vector x = {1,2,3}; Vector y = {2,4,6};\n std::cout << x.dot_product(y) << std::endl;\n std::cout << y.dot_product(x) << std::endl;\n}\n```\n\nFormally, the dot product is an operation between two\nVector objects and not a member function of one Vector\nobject that needs another Vector object for calculation"
"source": "This is good OOP-style\n\n```cpp\nint main()\n{\n Vector x = {1,2,3}; \n Vector y = {2,4,6};\n \n std::cout << x.dot_product(y) << std::endl;\n std::cout << y.dot_product(x) << std::endl;\n}\n```\n\nFormally, the dot product is an operation between two\nVector objects and not a member function of one Vector\nobject that needs another Vector object for calculation"
},
{
"metadata": {
@@ -549,7 +572,7 @@
},
"id": "c70addbd",
"cell_type": "markdown",
"source": "# Operator overloading\n\nC++ allows to overload (=redefine) the standard operators\n- Unary operators: ```++a```, ```a++```, ```--a```, ```a--```, ```~a```, ```!a```\n- Binary operators: ```a+b```, ```a-b```, ```a*b```, ```a/b```\n- Relational operators: ```a==b```, ```a!=b```, ```a<b```, ```a<=b```, ```a>b```, ```a>=b```\n\nInterfaces:\n\n```cpp\nreturn_type operator() [const]\nreturn_type operator(const Vector& other) [const]\n```\n \n[Complete list:](https://en.cppreference.com/w/cpp/language/operators)https://en.cppreference.com/w/cpp/language/operators"
"source": "# Operator overloading\n\nC++ allows to overload (=redefine) the standard operators\n- Unary operators: ```++a```, ```a++```, ```--a```, ```a--```, ```~a```, ```!a```\n- Binary operators: ```a+b```, ```a-b```, ```a*b```, ```a/b```\n- Relational operators: ```a==b```, ```a!=b```, ```a<b```, ```a<=b```, ```a>b```, ```a>=b```\n\nInterfaces:\n\n```cpp\nreturn_type operator() [const]\nreturn_type operator(const Vector& other) [const]\n```\n \n[Complete list: https://en.cppreference.com/w/cpp/language/operators](https://en.cppreference.com/w/cpp/language/operators)"
},
{
"metadata": {
@@ -571,7 +594,7 @@
},
"id": "d5960faa",
"cell_type": "markdown",
"source": "Now, the dot product is implemented as __*-operator__ that\nmaps two Vector objects to a scalar value\n\n```cpp\nint main()\n{\n Vector x = {1,2,3}; Vector y = {2,4,6};\n std::cout << x * y << std::endl;\n std::cout << y * x << std::endl;\n}\n```"
"source": "Now, the dot product is implemented as __*-operator__ that\nmaps two Vector objects to a scalar value\n\n```cpp\nint main()\n{\n Vector x = {1,2,3}; \n Vector y = {2,4,6};\n \n std::cout << x * y << std::endl;\n std::cout << y * x << std::endl;\n}\n```"
},
{
"metadata": {
@@ -593,7 +616,7 @@
},
"id": "37e996c0",
"cell_type": "markdown",
"source": "# Assignment by operator overloading\n\nImplementation of assignment as __overloaded =-operator__\n\n```cpp\nVector&amp; operator=(const Vector& other)\n{\n if (this != &other)\n {\n length = other.length;\n delete[] array;\n array = new double[length];\n for (auto i=0; i<length; ++i)\n array[i] = other.array[i];\n }\n return *this;\n}\n```\n\n- Usage: ```Vector x, y; x = y;```\n- Note that the ```this``` pointer is modified so there must not be a trailing ```const```"
"source": "# Assignment by operator overloading\n\nImplementation of assignment as __overloaded =-operator__\n\n```cpp\nVector& operator=(const Vector& other)\n{\n if (this != &other)\n {\n length = other.length;\n delete[] array;\n array = new double[length];\n for (auto i=0; i<length; ++i)\n array[i] = other.array[i];\n }\n return *this;\n}\n```\n\n- Usage: \n ```cpp\n Vector x, y = {1,2,3};\n x = y;\n ```\n- Note that the ```this``` pointer is modified so there must not be a trailing ```const```"
},
{
"metadata": {
@@ -604,7 +627,7 @@
},
"id": "9242b8b7-6046-4ad1-8f2f-16d8d737f44b",
"cell_type": "markdown",
"source": "Implementation of incremental assignment as __overloaded =-operator__\n\n```cpp\nVector& operator+=(const Vector& other)\n{\n if(length != other.length) \n throw std::invalid_argument(\"Vector lengths mismatch\");\n for (auto i=0; i<length; i++)\n array[i] += other.array[i];\n return *this;\n}\n```\n\n- Usage: ```Vector x, y; x += y;```\n- Note that the ```this``` pointer is modified so there must not be a trailing ```const```"
"source": "Implementation of incremental assignment as __overloaded =-operator__\n\n```cpp\nVector& operator+=(const Vector& other)\n{\n if(length != other.length) \n throw std::invalid_argument(\"Vector lengths mismatch\");\n for (auto i=0; i<length; i++)\n array[i] += other.array[i];\n return *this;\n}\n```\n\n- Usage: \n ```cpp\n Vector x = {1,2,3}, y = {4,5,6};\n x += y;\n ```\n- Note that the ```this``` pointer is modified so there must not be a trailing ```const```"
},
{
"metadata": {
@@ -639,7 +662,7 @@
},
"id": "6bcfdf28",
"cell_type": "markdown",
"source": "# Container class\n\n```cpp\nclass Container {\nprivate:\n double* data;\n int length;\npublic:\n Container(int length)\n : length(length), data(new double[length])\n { }\n Container(const std::initializer_list<double> l)\n : Container( (int)l.size() )\n {\n std::uninitialized_copy(l.begin(), l.end(), data);\n }\n};\n```"
"source": "# Container class\n\n```cpp\nclass Container {\nprivate:\n double* data;\n int length;\n \npublic:\n Container(int length)\n : length(length), data(new double[length])\n { }\n \n Container(const std::initializer_list<double> l)\n : Container( (int)l.size() )\n {\n std::uninitialized_copy(l.begin(), l.end(), data);\n }\n};\n```"
},
{
"metadata": {
@@ -679,7 +702,7 @@
},
"id": "a8d2812d",
"cell_type": "markdown",
"source": "# Task: Numerical integration\n\n<ul>\n <li>Approximate a one-dimensional integral by numerical quadrature</li>\n $$\\int_a^bf(x)dx \\approx \\sum_{i=1}^n w_i f\\left(x_i\\right)$$\n <li>Choice of quadrature weights $w_i$ and points $x_i$ determines\n the concrete numerical integration rule</li>\n</ul>\n "
"source": "# Task: Numerical integration\n\n- Approximate a one-dimensional integral by numerical quadrature\n $$\n \\int_a^bf(x)dx \\approx \\sum_{i=1}^n w_i f\\left(x_i\\right)\n $$\n \n- Choice of quadrature weights $w_i$ and points $x_i$ determines the concrete numerical integration rule\n "
},
{
"metadata": {
@@ -689,7 +712,7 @@
},
"id": "84a5ecaf",
"cell_type": "markdown",
"source": "# Simple integration rules\n\n<ul>\n <li>Midpoint rule\n </li>\n $$\\int_a^b f(x) d x \\approx(b-a) \\cdot f\\left(\\frac{a+b}{2}\\right)$$\n <li>Simpson rule\n </li>\n $$\\int_a^b f(x) d x \\approx \\frac{b-a}{6}\\left[f(a)+4 f\\left(\\frac{a+b}{2}\\right)+f(b)\\right]$$\n <li>Rectangle rule\n </li>\n $$\\int_a^b f(x) d x \\approx h \\sum_{n=0}^{N-1} f\\left(x_n\\right), \\quad h=\\frac{b-a}{N}, \\quad x_n=a+n h$$\n </ul>"
"source": "# Simple integration rules\n\n- Midpoint rule\n $$\\int_a^b f(x) d x \\approx(b-a) \\cdot f\\left(\\frac{a+b}{2}\\right)$$\n- Simpson rule\n $$\\int_a^b f(x) d x \\approx \\frac{b-a}{6}\\left[f(a)+4 f\\left(\\frac{a+b}{2}\\right)+f(b)\\right]$$\n- Rectangle rule\n $$\\int_a^b f(x) d x \\approx h \\sum_{n=0}^{N-1} f\\left(x_n\\right), \\quad h=\\frac{b-a}{N}, \\quad x_n=a+n h$$"
},
{
"metadata": {
@@ -699,7 +722,21 @@
},
"id": "9bcf5ae9",
"cell_type": "markdown",
"source": "# Gauss integration rules\n<div class=\"left\", style=\"width:50%;height:70%; float:left;\"> \n <ul>\n <li>Zoo of Gauss integration rules with quadrature weights and points tabulated for the reference interval [-1,1]\n </li>\n <li> Complete list of weights/points is available, e.g., at Wikipedia\n </li>\n </ul>\n</div>\n<div class=\"right\", style=\"width:50%;height:70%; float:right;\"> \n<table>\n <tr>\n <th style=\"text-align:left;\">$n$</th>\n <th style=\"text-align:left;\">$\\xi_{i}$</th>\n <th style=\"text-align:left;\">$w_i$</th>\n </tr>\n <tr>\n <td style=\"text-align:left;\">1</td>\n <td style=\"text-align:left;\">0</td>\n <td style=\"text-align:left;\">2</td>\n </tr>\n <tr>\n <td style=\"text-align:left;\">2</td>\n <td style=\"text-align:left;\">-0.57735026919</td>\n <td style=\"text-align:left;\">2</td> \n </tr>\n <tr>\n <td style=\"text-align:left;\"></td>\n <td style=\"text-align:left;\">0.57735026919</td>\n <td style=\"text-align:left;\">1</td> \n </tr>\n <tr>\n <td style=\"text-align:left;\">3</td>\n <td style=\"text-align:left;\">-0.774596669241</td>\n <td style=\"text-align:left;\">5/9</td> \n </tr>\n <tr>\n <td style=\"text-align:left;\"></td>\n <td style=\"text-align:left;\">0.0</td>\n <td style=\"text-align:left;\">8/9</td> \n </tr>\n <tr>\n <td style=\"text-align:left;\"></td>\n <td style=\"text-align:left;\">0.774596669241</td>\n <td style=\"text-align:left;\">5/9</td> \n </tr>\n <tr>\n <td style=\"text-align:left;\">4</td>\n <td style=\"text-align:left;\">-0.861136311594053</td>\n <td style=\"text-align:left;\">0.347854845137454</td> \n </tr>\n <tr>\n <td style=\"text-align:left;\"></td>\n <td style=\"text-align:left;\">-0.339981043584856</td>\n <td style=\"text-align:left;\">0.652145154862546</td> \n </tr>\n <tr>\n <td style=\"text-align:left;\"></td>\n <td style=\"text-align:left;\">0.774596669241</td>\n <td style = \"text-align:left;\">0.652145154862546</td>\n </tr>\n <tr>\n <td style=\"text-align:left;\"></td>\n <td style=\"text-align:left;\">0.861136311594053</td>\n <td style =\"text-align:left;\">0.347854845137454</td>\n </tr>\n </table>\n</div>"
"source": "# Gauss integration rules"
},
{
"metadata": {
"cell_style": "split"
},
"cell_type": "markdown",
"source": "- Zoo of Gauss integration rules with quadrature weights and points tabulated for the reference interval $[-1,1]$\n- Complete list of weights/points is available, e.g., at Wikipedia"
},
{
"metadata": {
"cell_style": "split"
},
"cell_type": "markdown",
"source": "<table>\n <tr>\n <th style=\"text-align:left;\">$n$</th>\n <th style=\"text-align:left;\">$\\xi_{i}$</th>\n <th style=\"text-align:left;\">$w_i$</th>\n </tr>\n <tr>\n <td style=\"text-align:left;\">1</td>\n <td style=\"text-align:left;\">0</td>\n <td style=\"text-align:left;\">2</td>\n </tr>\n <tr>\n <td style=\"text-align:left;\">2</td>\n <td style=\"text-align:left;\">-0.57735026919</td>\n <td style=\"text-align:left;\">2</td> \n </tr>\n <tr>\n <td style=\"text-align:left;\"></td>\n <td style=\"text-align:left;\">0.57735026919</td>\n <td style=\"text-align:left;\">1</td> \n </tr>\n <tr>\n <td style=\"text-align:left;\">3</td>\n <td style=\"text-align:left;\">-0.774596669241</td>\n <td style=\"text-align:left;\">5/9</td> \n </tr>\n <tr>\n <td style=\"text-align:left;\"></td>\n <td style=\"text-align:left;\">0.0</td>\n <td style=\"text-align:left;\">8/9</td> \n </tr>\n <tr>\n <td style=\"text-align:left;\"></td>\n <td style=\"text-align:left;\">0.774596669241</td>\n <td style=\"text-align:left;\">5/9</td> \n </tr>\n <tr>\n <td style=\"text-align:left;\">4</td>\n <td style=\"text-align:left;\">-0.861136311594053</td>\n <td style=\"text-align:left;\">0.347854845137454</td> \n </tr>\n <tr>\n <td style=\"text-align:left;\"></td>\n <td style=\"text-align:left;\">-0.339981043584856</td>\n <td style=\"text-align:left;\">0.652145154862546</td> \n </tr>\n <tr>\n <td style=\"text-align:left;\"></td>\n <td style=\"text-align:left;\">0.774596669241</td>\n <td style = \"text-align:left;\">0.652145154862546</td>\n </tr>\n <tr>\n <td style=\"text-align:left;\"></td>\n <td style=\"text-align:left;\">0.861136311594053</td>\n <td style =\"text-align:left;\">0.347854845137454</td>\n </tr>\n </table>"
},
{
"metadata": {
@@ -709,7 +746,7 @@
},
"id": "c1e5486d",
"cell_type": "markdown",
"source": "<ul>\n <li>Change of variable theorem\n </li>\n $$\\int_{a}^{b} f(x)dx = \\int_{-1}^{1}f(\\phi(t))\\phi^{i}(t)dt$$\n <li>Mapping from interval [a,b] to interval [-1,1]\n </li>\n $$\\phi(t) = \\frac{b-a}{2}t + \\frac{a+b}{2}, \\phi^{'}(t) = \\frac{b-a}{2}$$\n <li>Numerical quadrature rule\n </li>\n $$\\int_{a}^{b}f(x)dx\\approx\\phi^{'}\\sum_{n=1}^{n}w_if(\\phi(\\xi_i))$$\n </ul>"
"source": "- Change of variable theorem\n $$\\int_{a}^{b} f(x)dx = \\int_{-1}^{1}f(\\phi(t))\\phi^{i}(t)dt$$\n- Mapping from interval $[a,b]$ to interval $[-1,1]$\n $$\\phi(t) = \\frac{b-a}{2}t + \\frac{a+b}{2}, \\phi^{'}(t) = \\frac{b-a}{2}$$\n- Numerical quadrature rule\n $$\\int_{a}^{b}f(x)dx\\approx\\phi^{'}\\sum_{n=1}^{n}w_if(\\phi(\\xi_i))$$"
},
{
"metadata": {
@@ -719,7 +756,7 @@
},
"id": "a5f156a5",
"cell_type": "markdown",
"source": "# Program design\n\nWe need...\n<ul>\n <li> A strategy to ensure that all numerical quadrature rules\n(=classes) provide an __identical interface__ for evaluating integrals\n </li>\n <li>A standard way to __pass user-definable function__ f(x) from outside (=main routine) to the evaluation function\n </li>\n </ul>"
"source": "# Program design\n\nWe need...\n- A strategy to ensure that all numerical quadrature rules\n(=classes) provide an __identical interface__ for evaluating integrals\n- A standard way to __pass user-definable function__ f(x) from outside (=main routine) to the evaluation function"
},
{
"metadata": {
@@ -729,7 +766,7 @@
},
"id": "e3ca4745",
"cell_type": "markdown",
"source": "<ul>\n <li> <span style=color:gray;>A strategy to ensure that all numerical quadrature rules (=classes) provide an __identical interface__ for evaluating integrals</span>\n </li>\n <ul>\n <li> __Polymorphism:__ <span style=color:blue;>Base class Quadrature</span> provides common attributes and member functions (at least their <span style=color:red;>interface declaration</span>); <span style=color:red;>derived classes implement</span> specific quadrature rule (reusing common functionality of the base class, where this is possible and makes sense)\n </li>\n </ul>\n </ul>"
"source": "- <span style=color:gray;>A strategy to ensure that all numerical quadrature rules (=classes) provide an __identical interface__ for evaluating integrals</span>\n - __Polymorphism:__ <span style=color:blue;>Base class Quadrature</span> provides common attributes and member functions (at least their <span style=color:red;>interface declaration</span>); <span style=color:red;>derived classes implement</span> specific quadrature rule (reusing common functionality of the base class, where this is possible and makes sense)"
},
{
"metadata": {
@@ -739,7 +776,7 @@
},
"id": "7adb6a72",
"cell_type": "markdown",
"source": "<ul>\n <li> <span style=color:gray;>A standard way to __pass user-definable function__ f(x) from outside (=main routine) to the evaluation function</span>\n </li>\n <ul>\n <li> Function pointers (traditional approach)\n </li>\n <li> Lambda expressions (recommended approach since C++11)\n </li>\n </ul>\n </ul>"
"source": "- <span style=color:gray;>A standard way to __pass user-definable function__ f(x) from outside (=main routine) to the evaluation function</span>\n - Function pointers (traditional approach)\n - Lambda expressions (recommended approach since C++11)"
},
{
"metadata": {
@@ -749,7 +786,7 @@
},
"id": "be00d9e9",
"cell_type": "markdown",
"source": "# Function pointers\n<ul>\n <li>Define a function to be integrated\n </li>\n <code><span style=color:red;>const double myfunc1(double x)</span><span style=color:blue;>{ return x; }</span></code>\n <li>Define interface of the integrate function\n </li>\n <code><span style=color:blue;>double integrate(</span><span style=color:red;>const double (*func)(double x)</span><span style=color:blue;>, double a, double b) { ... }</span></code>\n <li>Usage:<code><span style=color:blue;>integrate(</span><span style=color:red;>myfunc1</span><span style=color:blue;>, 0, 1);</span></code>\n </li>\n </ul>"
"source": "# Function pointers\n\n- Define a function to be integrated\n ```cpp\n const double myfunc1(double x){ return x; }\n ```\n- Define interface of the integrate function\n ```cpp\n double integrate(const double (*func)(double x), double a, double b) { ... }\n ```\n\n- Usage: \n ```cpp\n integrate(myfunc1, 0, 1);\n ```"
},
{
"metadata": {
@@ -759,7 +796,7 @@
},
"id": "97851d03",
"cell_type": "markdown",
"source": "# Lambda expressions\n<ul>\n <li>Introduced in C++11, __lambda expressions__ provide an elegant way to write user-defined callback functions\n </li>\n <li>General syntax\n </li>\n <code><span style =color:blue;>auto name =</span> <span style=color:red;>[&ltcaptures>] (&ltparameters>) {&ltbody>};</span></code>\n <li>Lambda expressions can be inlined (anonymous functions)\n </li>\n <code><span style=color:blue;>integrate(</span><span style=color:red;>[&ltcaptures>](&ltparameters>) {&ltbody>}</span><span style=color:blue;>);</span></code>\n </ul>"
"source": "# Lambda expressions\n\n- Introduced in C++11, __lambda expressions__ provide an elegant way to write user-defined callback functions\n- General syntax\n ```cpp\n auto name = [<captures>] (<parameters>) { <body> };\n ```\n- Lambda expressions can be inlined (anonymous functions)\n ```cpp\n integrate([<captures>] (<parameters>) { <body> });\n ```"
},
{
"metadata": {
@@ -769,7 +806,7 @@
},
"id": "b54d3253",
"cell_type": "markdown",
"source": "<ul>\n <li> Define function to be integrated\n </li>\n <code><span style=color:red;>auto myfunc2 = [](double x) </span>{ return x; };</code>\n <li> Define interface of the integration function\n </li>\n <code><span style=color:blue;>double integrate(</span><span style=color:red;>std::function&ltdouble(double)> func</span><span style=color:blue;>, double a, double b) const { ... }</span></code>\n <li> Usage:\n </li>\n <code><span style=color:blue;>integrate(</span><span style=color:red;>myfunc2</span><span style=color:blue;>, 0, 1);</span> \n <span style=color:blue;>integrate(</span><span style=color:red;>[](double x){ return x; }</span><span style=color:blue;>, 0, 1);</span></code>\n</ul>"
"source": "- Define function to be integrated\n ```cpp\n auto myfunc2 = [](double x) { return x; };\n ```\n- Define interface of the integration function\n ```cpp\n double integrate(std::function<double(double)> func, double a, double b) const { ... }\n ```\n- Usage:\n ```cpp\n integrate(myfunc2, 0, 1);\n integrate([](double x){ return x; }, 0, 1);\n ```"
},
{
"metadata": {
@@ -779,7 +816,7 @@
},
"id": "44c14e8f",
"cell_type": "markdown",
"source": "# Program design, revisited\n<center><img src='plots/lecture2_program_design.png' width=\"700px\"></center>"
"source": "# Program design, revisited\n\n<center><img src='plots/lecture2_program_design.png' width=\"700px\"></center>"
},
{
"metadata": {
@@ -789,7 +826,7 @@
},
"id": "d27c3b4b",
"cell_type": "markdown",
"source": "# Base class <code>Quadrature</code>"
"source": "# Base class ```Quadrature```"
},
{
"metadata": {
@@ -801,7 +838,7 @@
},
"id": "af42c59d",
"cell_type": "code",
"source": "class Quadrature\n{\n public:\n Quadrature()\n : n(0), weights(nullptr), points(nullptr) {};\n Quadrature(int n)\n : n(n), weights(new double[n]), points(new double[n]) {};\n ~Quadrature()\n { delete[] weights; delete[] points; n=0; }\n private:\n double* weights;\n double* points;\n int n;\n};",
"source": "class Quadrature\n{\n public:\n Quadrature()\n : n(0), weights(nullptr), points(nullptr) {};\n \n Quadrature(int n)\n : n(n), weights(new double[n]), points(new double[n]) {};\n \n ~Quadrature()\n { delete[] weights; delete[] points; n=0; }\n \n private:\n double* weights;\n double* points;\n int n;\n};",
"execution_count": null,
"outputs": []
},
@@ -813,7 +850,7 @@
},
"id": "84de8363",
"cell_type": "markdown",
"source": "<ul><li><i>Scenario I:</i> We want to __declare the interface__ of the integrate function but we want to <i>force</i> the user to implement each integration rule individually</li>\n\n<code><span style=color:gray;>// pure (=0) virtual member function</span>\n<span style=color:red;>virtual</span> <span style = color:blue;>double integrate(double (*func)(double x), double a, double b) const </span><span style=color:red;>= 0;</span></code>\n<p><code><span style=color:gray;>// pure (=0) virtual member function</span>\n<span style=color:red;>virtual</span> <span style = color:blue;>double integrate(std::function&ltdouble(double)> func, double a, double b) const </span><span style=color:red;>= 0;</span></code></p>\n</ul>"
"source": "_Scenario I:_ We want to __declare the interface__ of the integrate function but we want to _force_ the user to implement each integration rule individually\n\n```cpp\n// pure (=0) virtual member functions\nvirtual double integrate(double (*func)(double x), double a, double b) const = 0;\nvirtual double integrate(std::function<double(double)> func, double a, double b) const = 0;\n```"
},
{
"metadata": {
@@ -824,18 +861,18 @@
},
"id": "cdb082e1",
"cell_type": "markdown",
"source": "<ul>\n<li> Keyword <code><span style=color:red;>virtual ... = 0;</span></code> declares the function to be __pure virtual__\n </li>\n <li>That is, each class that is derived from the __abstract class__\n<code><span style=color:blue;>Quadrature</span></code> must(!!!) implement this function explicitly\n </li>\n <li>Otherwise, the compiler complains when the programmer forgets to implement a pure virtual function and tries to create an object of the derived but not fully implemented class\n </li>\n</ul>"
"source": "- Keyword ```virtual ... = 0;``` declares the function to be __pure virtual__\n- That is, each class that is derived from the __abstract class__ ```Quadrature``` must(!!!) implement this function explicitly\n- Otherwise, the compiler complains when the programmer forgets to implement a pure virtual function and tries to create an object of the derived but not fully implemented class"
},
{
"metadata": {
"slideshow": {
"slide_type": "skip"
"slide_type": "slide"
},
"tags": []
},
"id": "2699b8e1",
"cell_type": "markdown",
"source": "# Abstract classes\n<ul>A class with at least one pure virtual function is an __abstract class__ and it is not possible to create an object thereof\n </ul>\n<center><img src='plots/lecture2_abstract_classes.png' width=\"400px\"></center>"
"source": "# Abstract classes\n\nA class with at least one pure virtual function is an __abstract class__ and it is not possible to create an object thereof\n\n<img src='plots/lecture2_abstract_classes.png' width=\"400px\">"
},
{
"metadata": {
@@ -846,7 +883,7 @@
},
"id": "2fdba15b",
"cell_type": "markdown",
"source": "# Base class <code>Quadrature</code>\n<ul>\n <li><i>Scenario II:</i> We provide a <i>generic implementation</i> but allow\nthe user to override it explicitly in a derived class\n </li>\n <code><span style=color:red;>virtual</span> <span style = color:blue;>double integrate(double (*func)(double x), double a, double b) const </span><span style=color:red;>{...}</span></code>\n<p><code><span style=color:red;>virtual</span> <span style = color:blue;>double integrate(std::function&ltdouble(double)> func, double a, double b) const</span><span style=color:red;>{...}</span></code></p>\n <li>Keyword <span style=color:red;>virtual</span> declares the function __virtual__. Virtual functions <i>can</i> be overridden in a derived class. If no overriding takes place, then the function implementation from the base class is used\n </li>\n </ul>"
"source": "# Base class ```Quadrature```\n\n_Scenario II:_ We provide a _generic implementation_ but allow the user to override it explicitly in a derived class\n\n```cpp\n// virtual memper functions\nvirtual double integrate(double (*func)(double x), double a, double b) const {...}\nvirtual double integrate(std::function<double(double)> func, double a, double b) const {...}\n```\n- Keyword ```virtual``` declares the function __virtual__. Virtual functions _can_ be overridden in a derived class. If no overriding takes place, then the function implementation from the base class is used"
},
{
"metadata": {
@@ -858,7 +895,7 @@
},
"id": "ecf096f8",
"cell_type": "code",
"source": "class Quadrature {\n private:\n double* weights;\n double* points;\n int n;\n \n public:\n Quadrature()\n : n(0), weights(nullptr), points(nullptr) {};\n Quadrature(int n)\n : n(n), weights(new double[n]), points(new double[n]) {};\n ~Quadrature()\n { delete[] weights; delete[] points; n=0; }\n \n // ** pure virtual functions (implemented in derived class) ** /\n virtual double mapping(double xi, double a, double b) const = 0;\n virtual double factor(double a, double b) const = 0;\n \n // ** virtual integration function (generic implementation) ** /\n virtual double integrate(double (*func)(double x), double a, double b) const {\n double integral(0.0);\n for (auto i=0; i<n; i++)\n integral += weights[i]*func(mapping(points[i],a,b)); \n return factor(a,b)*integral;\n } \n};",
"source": "class Quadrature {\n private:\n double* weights;\n double* points;\n int n;\n \n public:\n Quadrature()\n : n(0), weights(nullptr), points(nullptr) {};\n \n Quadrature(int n)\n : n(n), weights(new double[n]), points(new double[n]) {};\n \n ~Quadrature()\n { delete[] weights; delete[] points; n=0; }\n \n // pure virtual functions (must be implemented in derived class)\n virtual double mapping(double xi, double a, double b) const = 0;\n virtual double factor(double a, double b) const = 0;\n \n // virtual function (generic implementation)\n virtual double integrate(double (*func)(double x), double a, double b) const {\n double integral(0.0);\n for (auto i=0; i<n; i++)\n integral += weights[i]*func(mapping(points[i],a,b)); \n return factor(a,b)*integral;\n } \n};",
"execution_count": null,
"outputs": []
},
@@ -870,7 +907,7 @@
},
"id": "418667c4",
"cell_type": "markdown",
"source": "<ul>\n <li>The <span style=color:red;>virtual</span> <code><span style=color:blue;>integrate</span></code> function makes use of the <span style=color:red;>pure virtual</span> functions <code><span style=color:blue;>factor</span></code> and <code><span style=color:blue;>mapping</span></code></li>\n <li>Both functions are __not__ implemented in class Quadrature\n </li>\n <li>It is therefore obvious that class <code><span style=color:blue;>Quadrature</span></code> must be an __abstract class__ (and cannot be instantiated) since some of its functions (here: <code><span style=color:blue;>integrate</span></code>) are still unavailable\n </li>\n <li>Virtual functions make it is possible to call functions in the base class which will be implemented in the derived class\n </li>\n</ul>"
"source": "- The __virtual__ ```integrate``` function makes use of the __pure virtual__ functions ```factor``` and ```mapping```\n- Both functions are __not__ implemented in class ```Quadrature```\n- It is therefore obvious that class ```Quadrature``` must be an __abstract class__ (and cannot be instantiated) since some of its functions (here: ```integrate```) are still unavailable\n- Virtual functions make it is possible to call functions in the base class which will be implemented in the derived class"
},
{
"metadata": {
@@ -880,7 +917,7 @@
},
"id": "5f8b3918",
"cell_type": "markdown",
"source": "# Class <code>MidpointRule</code>\n<ul><li>__Derive__ class <span style=color:blue;>MidpointRule</span> from base class <span style=color:blue;>Quadrature</span>\n </li>\n</ul>"
"source": "# Class ```MidpointRule```\n\n- __Derive__ class ```MidpointRule``` from base class ```Quadrature```"
},
{
"metadata": {
@@ -902,7 +939,7 @@
},
"id": "4fe75525-c7ff-417d-94b1-3fee62185f9b",
"cell_type": "markdown",
"source": "# Class <code>SimpsonRule</code>\n<ul><li>__Derive__ class <span style=color:blue;>SimpsonRule</span> from base class <span style=color:blue;>Quadrature</span>\n </li>\n</ul>"
"source": "# Class ```SimpsonRule```\n\n- __Derive__ class ```SimpsonRule``` from base class ```Quadrature```"
},
{
"metadata": {
@@ -923,7 +960,7 @@
},
"id": "d74d5d82-2bbf-463c-87ef-c025d826a344",
"cell_type": "markdown",
"source": "# Class <code>GaussRule</code>\n<center><img src='plots/lecture2_gaussrule.png' width=\"700px\"></center>"
"source": "# Class ```GaussRule```\n\n__Derive__ class ```GaussRule``` from base class ```Quadrature```\n\n```cpp\nclass GaussRule : publixc Quadrature {\n GaussRule(int n) : Quadrature(n) {\n switch (n) {\n case 1: \n weights[0] = { 2.0 }; // QUIZ: Do we have access to the\n points[0] = { 0.0 }; // attributes weights and points ?\n break;\n case 2:\n ...\n default:\n throw \"Invalid argument\";\n }\n }\n};\n```"
},
{
"metadata": {
@@ -933,7 +970,7 @@
},
"id": "a6edea7c",
"cell_type": "markdown",
"source": "# Program design, revisited\n<center><img src='plots/lecture2_program_design_02.png' width=\"700px\"></center>"
"source": "# Program design, revisited\n\n<center><img src='plots/lecture2_program_design_02.png' width=\"700px\"></center>"
},
{
"metadata": {
@@ -943,7 +980,7 @@
},
"id": "050778a8",
"cell_type": "markdown",
"source": "# Program design, revisited\n<center><img src='plots/lecture2_program_design_03.png' width=\"700px\"></center>"
"source": "# Program design, revisited\n\n<center><img src='plots/lecture2_program_design_03.png' width=\"700px\"></center>"
},
{
"metadata": {
@@ -953,7 +990,7 @@
},
"id": "07f62799",
"cell_type": "markdown",
"source": "# Class <code>GaussRule</code>\n<ul>\n <li>Attributes from base class are now visible in derived class\n </li>\n <li>Class <span style=color:blue;>GaussRule</span> implements functions <span style=color:blue;>factor</span> and <span style=color:blue;>mapping</span>\n </li>\n <li>Class <span style=color:blue;>GaussRule</span> inherits the virtual function <span style=color:blue;>integrate</span> from class <span style=color:blue;>Quadrature</span>\n </li>\n</ul>"
"source": "# Class ```GaussRule```\n\n- Attributes from base class are now visible in derived class\n- Class ```GaussRule``` implements functions ```factor``` and ```mapping```\n- Class ```GaussRule``` inherits the virtual function ```integrate``` from class ```Quadrature```"
},
{
"metadata": {
@@ -977,7 +1014,7 @@
},
"id": "82c832b4",
"cell_type": "markdown",
"source": "# Keyword: override (C++11)\n<ul>\n <li>With the <span style=color:red;>override</span> keyword you can force the compiler to explicitly check that the function in a derived class\n<span style=color:red;>overrides</span> a (pure) virtual function from the base class\n </li>\n</ul>"
"source": "# Keyword: ```override``` (C++11)\n\n- With the ```override``` keyword you can force the compiler to explicitly check that the function in a derived class __overrides__ a (pure) virtual function from the base class"
},
{
"metadata": {
@@ -1002,7 +1039,7 @@
},
"id": "f28abb55",
"cell_type": "markdown",
"source": "<ul>\n <li>If the base class Quadrature does not specify a (pure) virtual function <span style=color:blue;>factor</span> an error will be thrown</li>\n</ul>"
"source": "- If the base class Quadrature does not specify a (pure) virtual function ```factor``` an error will be thrown"
},
{
"metadata": {
@@ -1012,7 +1049,7 @@
},
"id": "b90f4ef1",
"cell_type": "markdown",
"source": "# Keyword: final (C++11)\n<ul>\n <li>With the <span style=color:red;>final</span> keyword you can force the compiler to\nexplicitly prevent further overriding of functions</li>\n</ul>"
"source": "# Keyword: ```final``` (C++11)\n\n- With the ```final``` keyword you can force the compiler to explicitly prevent further overriding of functions"
},
{
"metadata": {
@@ -1037,14 +1074,14 @@
},
"id": "2320350a",
"cell_type": "markdown",
"source": "<ul>\n <li>If a class <span style=color:blue;>GaussRuleImproved</span> derived from <span style=color:blue;>GaussRule</span> tries to override the function <span style=color:blue;>factor</span> an error will be thrown</li>\n</ul>"
"source": "- If a class ```GaussRuleImproved``` derived from ```GaussRule``` tries to override the function ```factor``` an error will be thrown"
},
{
"metadata": {
"trusted": false,
"slideshow": {
"slide_type": "fragment"
}
},
"trusted": false
},
"id": "dc1b07d9",
"cell_type": "code",

0 comments on commit ed2817d

Please sign in to comment.