├── Chapter 03 - Computing with Base n Numbers ├── CustomerList.csv ├── Chapter3.ipynb └── .ipynb_checkpoints │ └── Chapter3-checkpoint.ipynb ├── LICENSE ├── Chapter 01 - Introduction ├── Chapter1.ipynb └── .ipynb_checkpoints │ └── Chapter1-checkpoint.ipynb ├── README.md ├── Chapter 04 - Combinatorics Using SciPy ├── Chapter4.ipynb └── .ipynb_checkpoints │ └── Chapter4-checkpoint.ipynb ├── Chapter 08 - Storage and Feature Extraction of Graphs, Trees, and Networks ├── Chapter8.ipynb └── .ipynb_checkpoints │ └── Chapter8-checkpoint.ipynb ├── Chapter 12 - Principal Components Analysis with scikit-learn └── pizza.csv ├── Chapter 10 - Regression Analysis └── auto_dataset.csv ├── Chapter 06 - Computational Algorithms in Linear Algebra ├── Chapter6.ipynb └── .ipynb_checkpoints │ └── Chapter6-checkpoint.ipynb ├── Chapter 07 - Computational Requirements for Algorithms ├── Chapter7.ipynb └── .ipynb_checkpoints │ └── Chapter7-checkpoint.ipynb ├── Chapter 05 - Elements of Discrete Probability ├── Chapter5.ipynb └── .ipynb_checkpoints │ └── Chapter5-checkpoint.ipynb └── Chapter 09 - Searching Data Structures and Finding Shortest Paths └── Chapter9.ipynb /Chapter 03 - Computing with Base n Numbers/CustomerList.csv: -------------------------------------------------------------------------------- 1 | CustomerID,Country,State,City,Zip Code 2 | 1,USA,Georgia,Atlanta,30332 3 | 2,USA,Georgia,Atlanta,30331 4 | 3,USA,Florida,Melbourne,30912 5 | 4,USA,Florida,Tampa,30123 6 | 5,India,Karnataka,Bangalore ,560001 7 | 6,India,Maharashtra,Mumbai,578234 8 | 7,India,Karnataka,Hubli,569823 9 | 8,India ,Maharashtra,Mumbai,578234 10 | 9,Germany,Bavaria,Munich,80331 11 | 10,Canada,Ontario,Toronto,M4B 1B3 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Chapter 01 - Introduction/Chapter1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Chapter 1 - Introduction: Key Concepts, Notation, Set Theory, Relations, and Functions\n", 8 | "\n", 9 | "This notebook contains code accompanying Chapter 1 Introduction: Key Concepts, Notation, Set Theory, Relations, and Functions in *Practical Discrete Mathematics* by Ryan T. White and Archana Tikayat Ray\n", 10 | "\n", 11 | "## Functions and Relations\n", 12 | "\n", 13 | "### The `sort()` function" 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 3, 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "name": "stdout", 23 | "output_type": "stream", 24 | "text": [ 25 | "[1, 2, 3, 4, 5, 8, 9, 12]\n", 26 | "['Brandon', 'Elise', 'Eugene', 'Kumar', 'Wyatt']\n" 27 | ] 28 | } 29 | ], 30 | "source": [ 31 | "numbers = [3, 1, 4, 12, 8, 5, 2, 9]\n", 32 | "names = ['Wyatt', 'Brandon', 'Kumar', 'Eugene', 'Elise']\n", 33 | "\n", 34 | "# Apply the sort() function to the lists\n", 35 | "numbers.sort()\n", 36 | "names.sort()\n", 37 | "\n", 38 | "# Display the output\n", 39 | "print(numbers)\n", 40 | "print(names)" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "### The `shuffle()` function" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 6, 53 | "metadata": {}, 54 | "outputs": [ 55 | { 56 | "name": "stdout", 57 | "output_type": "stream", 58 | "text": [ 59 | "[12, 2, 1, 5, 9, 3, 8, 4]\n", 60 | "[4, 2, 8, 3, 1, 12, 5, 9]\n", 61 | "[4, 5, 1, 9, 3, 8, 12, 2]\n", 62 | "[9, 12, 2, 8, 5, 3, 4, 1]\n", 63 | "[9, 8, 4, 3, 12, 1, 5, 2]\n" 64 | ] 65 | } 66 | ], 67 | "source": [ 68 | "import random\n", 69 | "\n", 70 | "# Set a random seed so the code is reproducible\n", 71 | "random.seed(1)\n", 72 | "\n", 73 | "# Run the random.shuffle() function 5 times and display the outputs\n", 74 | "for i in range(0,5):\n", 75 | " numbers = [3, 1, 4, 12, 8, 5, 2, 9]\n", 76 | " random.shuffle(numbers)\n", 77 | " print(numbers)" 78 | ] 79 | } 80 | ], 81 | "metadata": { 82 | "kernelspec": { 83 | "display_name": "Python 3.7 (DL)", 84 | "language": "python", 85 | "name": "dl" 86 | }, 87 | "language_info": { 88 | "codemirror_mode": { 89 | "name": "ipython", 90 | "version": 3 91 | }, 92 | "file_extension": ".py", 93 | "mimetype": "text/x-python", 94 | "name": "python", 95 | "nbconvert_exporter": "python", 96 | "pygments_lexer": "ipython3", 97 | "version": "3.7.7" 98 | } 99 | }, 100 | "nbformat": 4, 101 | "nbformat_minor": 4 102 | } 103 | -------------------------------------------------------------------------------- /Chapter 01 - Introduction/.ipynb_checkpoints/Chapter1-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Chapter 1 - Introduction: Key Concepts, Notation, Set Theory, Relations, and Functions\n", 8 | "\n", 9 | "This notebook contains code accompanying Chapter 1 Introduction: Key Concepts, Notation, Set Theory, Relations, and Functions in *Practical Discrete Mathematics* by Ryan T. White and Archana Tikayat Ray\n", 10 | "\n", 11 | "## Functions and Relations\n", 12 | "\n", 13 | "### The `sort()` function" 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 3, 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "name": "stdout", 23 | "output_type": "stream", 24 | "text": [ 25 | "[1, 2, 3, 4, 5, 8, 9, 12]\n", 26 | "['Brandon', 'Elise', 'Eugene', 'Kumar', 'Wyatt']\n" 27 | ] 28 | } 29 | ], 30 | "source": [ 31 | "numbers = [3, 1, 4, 12, 8, 5, 2, 9]\n", 32 | "names = ['Wyatt', 'Brandon', 'Kumar', 'Eugene', 'Elise']\n", 33 | "\n", 34 | "# Apply the sort() function to the lists\n", 35 | "numbers.sort()\n", 36 | "names.sort()\n", 37 | "\n", 38 | "# Display the output\n", 39 | "print(numbers)\n", 40 | "print(names)" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "### The `shuffle()` function" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 6, 53 | "metadata": {}, 54 | "outputs": [ 55 | { 56 | "name": "stdout", 57 | "output_type": "stream", 58 | "text": [ 59 | "[12, 2, 1, 5, 9, 3, 8, 4]\n", 60 | "[4, 2, 8, 3, 1, 12, 5, 9]\n", 61 | "[4, 5, 1, 9, 3, 8, 12, 2]\n", 62 | "[9, 12, 2, 8, 5, 3, 4, 1]\n", 63 | "[9, 8, 4, 3, 12, 1, 5, 2]\n" 64 | ] 65 | } 66 | ], 67 | "source": [ 68 | "import random\n", 69 | "\n", 70 | "# Set a random seed so the code is reproducible\n", 71 | "random.seed(1)\n", 72 | "\n", 73 | "# Run the random.shuffle() function 5 times and display the outputs\n", 74 | "for i in range(0,5):\n", 75 | " numbers = [3, 1, 4, 12, 8, 5, 2, 9]\n", 76 | " random.shuffle(numbers)\n", 77 | " print(numbers)" 78 | ] 79 | } 80 | ], 81 | "metadata": { 82 | "kernelspec": { 83 | "display_name": "Python 3.7 (DL)", 84 | "language": "python", 85 | "name": "dl" 86 | }, 87 | "language_info": { 88 | "codemirror_mode": { 89 | "name": "ipython", 90 | "version": 3 91 | }, 92 | "file_extension": ".py", 93 | "mimetype": "text/x-python", 94 | "name": "python", 95 | "nbconvert_exporter": "python", 96 | "pygments_lexer": "ipython3", 97 | "version": "3.7.7" 98 | } 99 | }, 100 | "nbformat": 4, 101 | "nbformat_minor": 4 102 | } 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Machine Learning Summit 2025

2 | 3 | ## Machine Learning Summit 2025 4 | **Bridging Theory and Practice: ML Solutions for Today’s Challenges** 5 | 6 | 3 days, 20+ experts, and 25+ tech sessions and talks covering critical aspects of: 7 | - **Agentic and Generative AI** 8 | - **Applied Machine Learning in the Real World** 9 | - **ML Engineering and Optimization** 10 | 11 | 👉 [Book your ticket now >>](https://packt.link/mlsumgh) 12 | 13 | --- 14 | 15 | ## Join Our Newsletters 📬 16 | 17 | ### DataPro 18 | *The future of AI is unfolding. Don’t fall behind.* 19 | 20 |

DataPro QR

21 | 22 | Stay ahead with [**DataPro**](https://landing.packtpub.com/subscribe-datapronewsletter/?link_from_packtlink=yes), the free weekly newsletter for data scientists, AI/ML researchers, and data engineers. 23 | From trending tools like **PyTorch**, **scikit-learn**, **XGBoost**, and **BentoML** to hands-on insights on **database optimization** and real-world **ML workflows**, you’ll get what matters, fast. 24 | 25 | > Stay sharp with [DataPro](https://landing.packtpub.com/subscribe-datapronewsletter/?link_from_packtlink=yes). Join **115K+ data professionals** who never miss a beat. 26 | 27 | --- 28 | 29 | ### BIPro 30 | *Business runs on data. Make sure yours tells the right story.* 31 | 32 |

BIPro QR

33 | 34 | [**BIPro**](https://landing.packtpub.com/subscribe-bipro-newsletter/?link_from_packtlink=yes) is your free weekly newsletter for BI professionals, analysts, and data leaders. 35 | Get practical tips on **dashboarding**, **data visualization**, and **analytics strategy** with tools like **Power BI**, **Tableau**, **Looker**, **SQL**, and **dbt**. 36 | 37 | > Get smarter with [BIPro](https://landing.packtpub.com/subscribe-bipro-newsletter/?link_from_packtlink=yes). Trusted by **35K+ BI professionals**, see what you’re missing. 38 | 39 | 40 | 41 | 42 | # Practical Discrete Mathematics 43 | 44 | Practical Discrete Mathematics 45 | 46 | This is the code repository for [Practical Discrete Mathematics](https://www.packtpub.com/product/practical-discrete-mathematics/9781838983147), published by Packt. 47 | 48 | **Discover math principles that fuel algorithms for computer science and machine learning with Python** 49 | 50 | ## What is this book about? 51 | Discrete mathematics deals with studying countable, distinct elements, and its principles are widely used in building algorithms for computer science and data science. The knowledge of discrete math concepts can help you understand algorithms, binary, and general mathematics that sit at the core of data-driven tasks. 52 | Practical Discrete Mathematics with Python is a comprehensive introduction for those who are new to the mathematics of countable objects. This book will help you get up to speed with using discrete math principles to take your computer science skills to a more advanced level. 53 | 54 | This book covers the following exciting features: 55 | * Understand the terminology and methods in discrete math and their usage in algorithms and data problems 56 | * Use Boolean algebra in formal logic and elementary control structures 57 | * Implement combinatorics to measure computational complexity and manage memory allocation 58 | * Use random variables, calculate descriptive statistics, and find average-case computational complexity 59 | * Solve graph problems involved in routing, pathfinding, and graph searches, such as depth-first search 60 | * Perform ML tasks such as data visualization, regression, and dimensionality reduction 61 | 62 | If you feel this book is for you, get your [copy](https://www.amazon.com/dp/1838983147) today! 63 | 64 | https://www.packtpub.com/ 65 | 66 | ## Instructions and Navigations 67 | All of the code is organized into folders. For example, Chapter02. 68 | 69 | The code will look like the following: 70 | ``` 71 | if (test expression) 72 | { 73 | Statement upon condition is true 74 | } 75 | ``` 76 | 77 | **Following is what you need for this book:** 78 | This book is for computer scientists looking to expand their knowledge of discrete math. Students looking to get hands-on with computer science, mathematics, statistics, engineering, or related disciplines will also find this book useful. Basic programming skills in any language and knowledge of elementary real-number algebra are required to get started with this book. 79 | 80 | With the following software and hardware list you can run all code files present in the book (Chapter 1-12). 81 | 82 | ### Software and Hardware List 83 | 84 | | Chapter | Software required | OS required | 85 | | -------- | ------------------------------------| -----------------------------------| 86 | | 1 to 12 | Python 3.0 or above | Windows, Mac OS X, and Linux (Any) | 87 | | 1 to 12 | Python libraries: NumPy, matplotlib, pandas, scikit-learn, SciPy, seaborn | Windows, Mac OS X, and Linux (Any) | 88 | 89 | We also provide a PDF file that has color images of the screenshots/diagrams used in this book. [Click here to download it](https://static.packt-cdn.com/downloads/9781838983147_ColorImages.pdf). 90 | 91 | ### Related products 92 | * Applying Math with Python [[Packt]](https://www.packtpub.com/product/applying-math-with-python/9781838989750) [[Amazon]](https://www.amazon.com/dp/1838989757) 93 | 94 | * Hands-On Mathematics for Deep Learning [[Packt]](https://www.packtpub.com/product/hands-on-mathematics-for-deep-learning/9781838647292) [[Amazon]](https://www.amazon.com/dp/1838647295) 95 | 96 | ## Get to Know the Authors 97 | **Ryan T. White** 98 | is a Ph.D. in Applied Mathematics. He works as a professor at Florida Institute of Technology and researcher working on authoring educational materials/graphics, financial modeling, statistical modeling, and data science with R, Python, Matlab, and LateX. 99 | 100 | **Archana Tikayat Ray** 101 | has an M.S. in Aerospace Engineering from Georgia Institute of Technology and is currently working towards her Ph.D. at the same institution. Her research work is focused on data analysis, visualization, machine learning, and Natural Language Processing. 102 | ### Download a free PDF 103 | 104 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
105 |

https://packt.link/free-ebook/9781838983147

-------------------------------------------------------------------------------- /Chapter 03 - Computing with Base n Numbers/Chapter3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Chapter 3 - Computing with Base-$n$ Numbers\n", 8 | "\n", 9 | "This notebook contains code accompanying Chapter 3 Computing with Base-$n$ Numbers in *Practical Discrete Mathematics* by Ryan T. White and Archana Tikayat Ray.\n", 10 | "\n", 11 | "## Converting between Bases\n", 12 | "\n", 13 | "Below, we can convert a user-input number in base-10 (decimal) to numbers in base-16 (hexadecimal) and base-2 (binary)." 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 7, 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "name": "stdin", 23 | "output_type": "stream", 24 | "text": [ 25 | "Enter a number with base 10\n", 26 | " 123456\n" 27 | ] 28 | }, 29 | { 30 | "name": "stdout", 31 | "output_type": "stream", 32 | "text": [ 33 | "Hexadecimal form of 123456 is 1e240\n", 34 | "Binary form of 123456 is 11110001001000000\n" 35 | ] 36 | } 37 | ], 38 | "source": [ 39 | "# TypeConversion from decimal with base 10 to hexadecimal form with base 16 to binary form with the base 2 \n", 40 | "\n", 41 | "# Taking input from user - an integer with base 10\n", 42 | "number = int(input(\"Enter a number with base 10\\n\"))\n", 43 | "# Converting the decimal number input by user to Hexadecimal \n", 44 | "print(\"Hexadecimal form of \" + str(number) + \" is \" + hex(number).lstrip(\"0x\").rstrip(\"L\"))\n", 45 | "# Converting the decimal number input by user to Binary \n", 46 | "print(\"Binary form of \" + str(number) + \" is \" + bin(number).lstrip(\"0b\").rstrip(\"L\"))" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "## Binary Numbers and their Applications\n", 54 | "\n", 55 | "Below is an example showing how we can use Boolean algebra with a dataset of Netflix users." 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 2, 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "name": "stdout", 65 | "output_type": "stream", 66 | "text": [ 67 | "Example for AND operator\n", 68 | " CustomerID Country State City Zip Code\n", 69 | "0 1 USA Georgia Atlanta 30332\n", 70 | "1 2 USA Georgia Atlanta 30331\n", 71 | "Example for OR operator\n", 72 | " CustomerID Country State City Zip Code\n", 73 | "0 1 USA Georgia Atlanta 30332\n", 74 | "1 2 USA Georgia Atlanta 30331\n", 75 | "2 3 USA Florida Melbourne 30912\n", 76 | "3 4 USA Florida Tampa 30123\n", 77 | "9 10 Canada Ontario Toronto M4B 1B3\n", 78 | "Example for NOT operator\n", 79 | " CustomerID Country State City Zip Code\n", 80 | "4 5 India Karnataka Bangalore 560001\n", 81 | "5 6 India Maharashtra Mumbai 578234\n", 82 | "6 7 India Karnataka Hubli 569823\n", 83 | "7 8 India Maharashtra Mumbai 578234\n", 84 | "8 9 Germany Bavaria Munich 80331\n", 85 | "9 10 Canada Ontario Toronto M4B 1B3\n" 86 | ] 87 | } 88 | ], 89 | "source": [ 90 | "# Import packages with the functions we need\n", 91 | "import pandas as pd\n", 92 | "\n", 93 | "# Import the file you are trying to work with\n", 94 | "customer_df = pd.read_csv(\"CustomerList.csv\")\n", 95 | "\n", 96 | "# Using AND operator\n", 97 | "print(\"Example for AND operator\")\n", 98 | "print(customer_df.loc[(customer_df['Country'] == 'USA') & (customer_df['State'] == 'Georgia')])\n", 99 | "\n", 100 | "# Using OR operator \n", 101 | "print(\"Example for OR operator\")\n", 102 | "print(customer_df.loc[(customer_df['Country'] == 'USA') | (customer_df['State'] == 'Ontario')])\n", 103 | "\n", 104 | "# Using NOT operator\n", 105 | "print(\"Example for NOT operator\")\n", 106 | "print(customer_df.loc[(customer_df['Country'] != 'USA')])" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "## Hexadecimal Numbers and Their Applications\n", 114 | "\n", 115 | "### Example: Defining locations in computer memory" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 4, 121 | "metadata": {}, 122 | "outputs": [ 123 | { 124 | "name": "stdout", 125 | "output_type": "stream", 126 | "text": [ 127 | "The memory location of variable peanut_butter is: 140719185764912\n", 128 | "The memory location of variable sandwich is: 140719185764912\n", 129 | "We can see that the memory location of both the variables is the same because they were assigned the same value\n", 130 | "After setting the values of both variables equal to each other, we have: \n", 131 | "The value of variable sandwich is now set to: 7\n", 132 | "The value of variable peanut_butter is now set to: 7\n", 133 | "The value of sandwich variable was changed to 10, let's see whether it affects the value of peanut_butter\n", 134 | "The value of variable peanut_butter: 7\n", 135 | "The value of peanut_butter did NOT change even though we changed the value of sandwich\n", 136 | "The memory location of variable peanut_butter is: 140719185764944\n" 137 | ] 138 | } 139 | ], 140 | "source": [ 141 | "# Variable 1: peanut_butter\n", 142 | "peanut_butter = 6\n", 143 | "print(\"The memory location of variable peanut_butter is: \",id(peanut_butter))\n", 144 | "\n", 145 | "# Variable 2: sandwich\n", 146 | "sandwich = 6\n", 147 | "print(\"The memory location of variable sandwich is: \",id(sandwich))\n", 148 | "print(\"We can see that the memory location of both the variables is the same because they were assigned the same value\")\n", 149 | "\n", 150 | "# Setting value of sandwich variable to a new number\n", 151 | "sandwich = 7\n", 152 | "\n", 153 | "# Setting both the variables equal to each other:\n", 154 | "peanut_butter = sandwich\n", 155 | "print(\"After setting the values of both variables equal to each other, we have: \")\n", 156 | "print(\"The value of variable sandwich is now set to: \",sandwich)\n", 157 | "print(\"The value of variable peanut_butter is now set to: \",peanut_butter)\n", 158 | "print(\"The value of sandwich variable was changed to 10, let's see whether it affects the value of peanut_butter\")\n", 159 | "\n", 160 | "# Setting value of sandwich variable to a new number\n", 161 | "sandwich = 10\n", 162 | "\n", 163 | "print(\"The value of variable peanut_butter: \" ,peanut_butter)\n", 164 | "print(\"The value of peanut_butter did NOT change even though we changed the value of sandwich\")\n", 165 | "print(\"The memory location of variable peanut_butter is: \",id(peanut_butter))" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": {}, 171 | "source": [ 172 | "### Example: Media Access Control (MAC) Addresses\n", 173 | "\n", 174 | "Note the MAC address generated by the code below will vary for different users, but they will be stored in a hexadecimal form." 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": null, 180 | "metadata": {}, 181 | "outputs": [], 182 | "source": [ 183 | "import uuid\n", 184 | "\n", 185 | "# address using uuid and getnode() function making use of hexadecimal number system\n", 186 | "print (hex(uuid.getnode()))" 187 | ] 188 | } 189 | ], 190 | "metadata": { 191 | "kernelspec": { 192 | "display_name": "Python 3.7 (DL)", 193 | "language": "python", 194 | "name": "dl" 195 | }, 196 | "language_info": { 197 | "codemirror_mode": { 198 | "name": "ipython", 199 | "version": 3 200 | }, 201 | "file_extension": ".py", 202 | "mimetype": "text/x-python", 203 | "name": "python", 204 | "nbconvert_exporter": "python", 205 | "pygments_lexer": "ipython3", 206 | "version": "3.7.7" 207 | } 208 | }, 209 | "nbformat": 4, 210 | "nbformat_minor": 4 211 | } 212 | -------------------------------------------------------------------------------- /Chapter 03 - Computing with Base n Numbers/.ipynb_checkpoints/Chapter3-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Chapter 3 - Computing with Base-$n$ Numbers\n", 8 | "\n", 9 | "This notebook contains code accompanying Chapter 3 Computing with Base-$n$ Numbers in *Practical Discrete Mathematics* by Ryan T. White and Archana Tikayat Ray.\n", 10 | "\n", 11 | "## Converting between Bases\n", 12 | "\n", 13 | "Below, we can convert a user-input number in base-10 (decimal) to numbers in base-16 (hexadecimal) and base-2 (binary)." 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 7, 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "name": "stdin", 23 | "output_type": "stream", 24 | "text": [ 25 | "Enter a number with base 10\n", 26 | " 123456\n" 27 | ] 28 | }, 29 | { 30 | "name": "stdout", 31 | "output_type": "stream", 32 | "text": [ 33 | "Hexadecimal form of 123456 is 1e240\n", 34 | "Binary form of 123456 is 11110001001000000\n" 35 | ] 36 | } 37 | ], 38 | "source": [ 39 | "# TypeConversion from decimal with base 10 to hexadecimal form with base 16 to binary form with the base 2 \n", 40 | "\n", 41 | "# Taking input from user - an integer with base 10\n", 42 | "number = int(input(\"Enter a number with base 10\\n\"))\n", 43 | "# Converting the decimal number input by user to Hexadecimal \n", 44 | "print(\"Hexadecimal form of \" + str(number) + \" is \" + hex(number).lstrip(\"0x\").rstrip(\"L\"))\n", 45 | "# Converting the decimal number input by user to Binary \n", 46 | "print(\"Binary form of \" + str(number) + \" is \" + bin(number).lstrip(\"0b\").rstrip(\"L\"))" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "## Binary Numbers and their Applications\n", 54 | "\n", 55 | "Below is an example showing how we can use Boolean algebra with a dataset of Netflix users." 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 2, 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "name": "stdout", 65 | "output_type": "stream", 66 | "text": [ 67 | "Example for AND operator\n", 68 | " CustomerID Country State City Zip Code\n", 69 | "0 1 USA Georgia Atlanta 30332\n", 70 | "1 2 USA Georgia Atlanta 30331\n", 71 | "Example for OR operator\n", 72 | " CustomerID Country State City Zip Code\n", 73 | "0 1 USA Georgia Atlanta 30332\n", 74 | "1 2 USA Georgia Atlanta 30331\n", 75 | "2 3 USA Florida Melbourne 30912\n", 76 | "3 4 USA Florida Tampa 30123\n", 77 | "9 10 Canada Ontario Toronto M4B 1B3\n", 78 | "Example for NOT operator\n", 79 | " CustomerID Country State City Zip Code\n", 80 | "4 5 India Karnataka Bangalore 560001\n", 81 | "5 6 India Maharashtra Mumbai 578234\n", 82 | "6 7 India Karnataka Hubli 569823\n", 83 | "7 8 India Maharashtra Mumbai 578234\n", 84 | "8 9 Germany Bavaria Munich 80331\n", 85 | "9 10 Canada Ontario Toronto M4B 1B3\n" 86 | ] 87 | } 88 | ], 89 | "source": [ 90 | "# Import packages with the functions we need\n", 91 | "import pandas as pd\n", 92 | "\n", 93 | "# Import the file you are trying to work with\n", 94 | "customer_df = pd.read_csv(\"CustomerList.csv\")\n", 95 | "\n", 96 | "# Using AND operator\n", 97 | "print(\"Example for AND operator\")\n", 98 | "print(customer_df.loc[(customer_df['Country'] == 'USA') & (customer_df['State'] == 'Georgia')])\n", 99 | "\n", 100 | "# Using OR operator \n", 101 | "print(\"Example for OR operator\")\n", 102 | "print(customer_df.loc[(customer_df['Country'] == 'USA') | (customer_df['State'] == 'Ontario')])\n", 103 | "\n", 104 | "# Using NOT operator\n", 105 | "print(\"Example for NOT operator\")\n", 106 | "print(customer_df.loc[(customer_df['Country'] != 'USA')])" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "## Hexadecimal Numbers and Their Applications\n", 114 | "\n", 115 | "### Example: Defining locations in computer memory" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 4, 121 | "metadata": {}, 122 | "outputs": [ 123 | { 124 | "name": "stdout", 125 | "output_type": "stream", 126 | "text": [ 127 | "The memory location of variable peanut_butter is: 140719185764912\n", 128 | "The memory location of variable sandwich is: 140719185764912\n", 129 | "We can see that the memory location of both the variables is the same because they were assigned the same value\n", 130 | "After setting the values of both variables equal to each other, we have: \n", 131 | "The value of variable sandwich is now set to: 7\n", 132 | "The value of variable peanut_butter is now set to: 7\n", 133 | "The value of sandwich variable was changed to 10, let's see whether it affects the value of peanut_butter\n", 134 | "The value of variable peanut_butter: 7\n", 135 | "The value of peanut_butter did NOT change even though we changed the value of sandwich\n", 136 | "The memory location of variable peanut_butter is: 140719185764944\n" 137 | ] 138 | } 139 | ], 140 | "source": [ 141 | "# Variable 1: peanut_butter\n", 142 | "peanut_butter = 6\n", 143 | "print(\"The memory location of variable peanut_butter is: \",id(peanut_butter))\n", 144 | "\n", 145 | "# Variable 2: sandwich\n", 146 | "sandwich = 6\n", 147 | "print(\"The memory location of variable sandwich is: \",id(sandwich))\n", 148 | "print(\"We can see that the memory location of both the variables is the same because they were assigned the same value\")\n", 149 | "\n", 150 | "# Setting value of sandwich variable to a new number\n", 151 | "sandwich = 7\n", 152 | "\n", 153 | "# Setting both the variables equal to each other:\n", 154 | "peanut_butter = sandwich\n", 155 | "print(\"After setting the values of both variables equal to each other, we have: \")\n", 156 | "print(\"The value of variable sandwich is now set to: \",sandwich)\n", 157 | "print(\"The value of variable peanut_butter is now set to: \",peanut_butter)\n", 158 | "print(\"The value of sandwich variable was changed to 10, let's see whether it affects the value of peanut_butter\")\n", 159 | "\n", 160 | "# Setting value of sandwich variable to a new number\n", 161 | "sandwich = 10\n", 162 | "\n", 163 | "print(\"The value of variable peanut_butter: \" ,peanut_butter)\n", 164 | "print(\"The value of peanut_butter did NOT change even though we changed the value of sandwich\")\n", 165 | "print(\"The memory location of variable peanut_butter is: \",id(peanut_butter))" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": {}, 171 | "source": [ 172 | "### Example: Media Access Control (MAC) Addresses\n", 173 | "\n", 174 | "Note the MAC address generated by the code below will vary for different users, but they will be stored in a hexadecimal form." 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": null, 180 | "metadata": {}, 181 | "outputs": [], 182 | "source": [ 183 | "import uuid\n", 184 | "\n", 185 | "# address using uuid and getnode() function making use of hexadecimal number system\n", 186 | "print (hex(uuid.getnode()))" 187 | ] 188 | } 189 | ], 190 | "metadata": { 191 | "kernelspec": { 192 | "display_name": "Python 3.7 (DL)", 193 | "language": "python", 194 | "name": "dl" 195 | }, 196 | "language_info": { 197 | "codemirror_mode": { 198 | "name": "ipython", 199 | "version": 3 200 | }, 201 | "file_extension": ".py", 202 | "mimetype": "text/x-python", 203 | "name": "python", 204 | "nbconvert_exporter": "python", 205 | "pygments_lexer": "ipython3", 206 | "version": "3.7.7" 207 | } 208 | }, 209 | "nbformat": 4, 210 | "nbformat_minor": 4 211 | } 212 | -------------------------------------------------------------------------------- /Chapter 04 - Combinatorics Using SciPy/Chapter4.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Chapter 4 - Combinatorics Using SciPy\n", 8 | "\n", 9 | "This notebook contains code accompanying Chapter 4 Combinatorics Using SciPy in *Practical Discrete Mathematics* by Ryan T. White and Archana Tikayat Ray.\n", 10 | "\n", 11 | "## Counting Permutations and Combinations of Objects\n", 12 | "\n", 13 | "### Growth of Factorials\n", 14 | "\n", 15 | "Below, we compute some factorials, which count permutations." 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 2, 21 | "metadata": {}, 22 | "outputs": [ 23 | { 24 | "name": "stdout", 25 | "output_type": "stream", 26 | "text": [ 27 | "2432902008176640000\n", 28 | "93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000\n" 29 | ] 30 | } 31 | ], 32 | "source": [ 33 | "import math\n", 34 | "print(math.factorial(20))\n", 35 | "print(math.factorial(100))" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "### Example: Counting playlists\n", 43 | "\n", 44 | "The number of 10-permutations of the 20-song list can be computed with Python as follows." 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 4, 50 | "metadata": {}, 51 | "outputs": [ 52 | { 53 | "name": "stdout", 54 | "output_type": "stream", 55 | "text": [ 56 | "670442572800.0\n" 57 | ] 58 | } 59 | ], 60 | "source": [ 61 | "import math\n", 62 | "print(math.factorial(20)/math.factorial(20-10))" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "### Example: Teambuilding\n", 70 | "\n", 71 | "The code below finds the number of possible 4-person teams we could build from four of twenty people." 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 5, 77 | "metadata": {}, 78 | "outputs": [ 79 | { 80 | "name": "stdout", 81 | "output_type": "stream", 82 | "text": [ 83 | "4845.0\n", 84 | "4845.0\n" 85 | ] 86 | } 87 | ], 88 | "source": [ 89 | "# using the factorial function\n", 90 | "import math\n", 91 | "print(math.factorial(20) / math.factorial(4) / math.factorial(20-4))\n", 92 | "\n", 93 | "# import the special functions from sciPy\n", 94 | "import scipy.special\n", 95 | "print(scipy.special.binom(20,4))" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "## Applications to Memory Allocation\n", 103 | "\n", 104 | "### Example: Pre-allocating Memory\n", 105 | "\n", 106 | "Suppose we wish to create a large list of 1,000,000 numbers. The simplest way is to just run a loop, adding one element at a time to the vector. (Note that the runtime will vary depending on the hardware where you run the code.)" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 9, 112 | "metadata": {}, 113 | "outputs": [ 114 | { 115 | "name": "stdout", 116 | "output_type": "stream", 117 | "text": [ 118 | "0.13155269622802734\n" 119 | ] 120 | } 121 | ], 122 | "source": [ 123 | "import time\n", 124 | "\n", 125 | "number = 1000000\n", 126 | "\n", 127 | "# Check the current time\n", 128 | "startTime = time.time()\n", 129 | "\n", 130 | "# Create an empty list\n", 131 | "list = []\n", 132 | "\n", 133 | "# Add items to the list one by one\n", 134 | "for counter in range(number):\n", 135 | " list.append(counter)\n", 136 | "\n", 137 | "# Display the run time\n", 138 | "print(time.time() - startTime)" 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "metadata": {}, 144 | "source": [ 145 | "The code below can pre-allocate an array with 1,000,000 and fill it in with 1, 2, ..., 1,000,000. (Note that the runtime will vary depending on the hardware where you run the code.)" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": 11, 151 | "metadata": {}, 152 | "outputs": [ 153 | { 154 | "name": "stdout", 155 | "output_type": "stream", 156 | "text": [ 157 | "0.10027527809143066\n" 158 | ] 159 | } 160 | ], 161 | "source": [ 162 | "import time\n", 163 | "number = 1000000\n", 164 | "\n", 165 | "# Check the current time\n", 166 | "startTime = time.time()\n", 167 | "\n", 168 | "# Create a list of 1000000 zeros\n", 169 | "list = [None]*number\n", 170 | "\n", 171 | "# Add items to the list one by one\n", 172 | "for counter in range(number):\n", 173 | " list[counter] = counter\n", 174 | "\n", 175 | "# Display the run time\n", 176 | "print(time.time() - startTime)" 177 | ] 178 | }, 179 | { 180 | "cell_type": "markdown", 181 | "metadata": {}, 182 | "source": [ 183 | "## Efficacy of Brute Force Algorithms\n", 184 | "\n", 185 | "### Example: Caesar Cipher\n", 186 | "\n", 187 | "A brute force check of how the text would be decoded for each possible Caesar cipher." 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": 12, 193 | "metadata": {}, 194 | "outputs": [ 195 | { 196 | "name": "stdout", 197 | "output_type": "stream", 198 | "text": [ 199 | "0 nzohfu gur rarzl ng avtug\n", 200 | "1 oapigv hvs sbsam oh bwuvh\n", 201 | "2 pbqjhw iwt tctbn pi cxvwi\n", 202 | "3 qcrkix jxu uduco qj dywxj\n", 203 | "4 rdsljy kyv vevdp rk ezxyk\n", 204 | "5 setmkz lzw wfweq sl fayzl\n", 205 | "6 tfunla max xgxfr tm gbzam\n", 206 | "7 ugvomb nby yhygs un hcabn\n", 207 | "8 vhwpnc ocz zizht vo idbco\n", 208 | "9 wixqod pda ajaiu wp jecdp\n", 209 | "10 xjyrpe qeb bkbjv xq kfdeq\n", 210 | "11 ykzsqf rfc clckw yr lgefr\n", 211 | "12 zlatrg sgd dmdlx zs mhfgs\n", 212 | "13 ambush the enemy at night\n", 213 | "14 bncvti uif fofnz bu ojhiu\n", 214 | "15 codwuj vjg gpgoa cv pkijv\n", 215 | "16 dpexvk wkh hqhpb dw qljkw\n", 216 | "17 eqfywl xli iriqc ex rmklx\n", 217 | "18 frgzxm ymj jsjrd fy snlmy\n", 218 | "19 gshayn znk ktkse gz tomnz\n", 219 | "20 htibzo aol lultf ha upnoa\n", 220 | "21 iujcap bpm mvmug ib vqopb\n", 221 | "22 jvkdbq cqn nwnvh jc wrpqc\n", 222 | "23 kwlecr dro oxowi kd xsqrd\n", 223 | "24 lxmfds esp pypxj le ytrse\n", 224 | "25 mynget ftq qzqyk mf zustf\n" 225 | ] 226 | } 227 | ], 228 | "source": [ 229 | "# Intercepted message\n", 230 | "codedMessage = 'nzohfu gur rarzl ng avtug'\n", 231 | "\n", 232 | "# We will shift by 0, shift by 1, shift by 2, ... and print the results\n", 233 | "for counter in range(26):\n", 234 | " # Start with no guess\n", 235 | " guessedMessage = ''\n", 236 | " \n", 237 | " # Loop through each letter in the coded message\n", 238 | " for x in codedMessage:\n", 239 | " \n", 240 | " # If x is not a space\n", 241 | " if x != ' ':\n", 242 | " \n", 243 | " # Shift the letter forward by counter\n", 244 | " if ord(x)+counter <= 122:\n", 245 | " x = chr(ord(x)+counter)\n", 246 | " \n", 247 | " # Subtract 26 if we go beyond z\n", 248 | " else:\n", 249 | " x = chr(ord(x)+counter-26)\n", 250 | " \n", 251 | " # Build a guess for the message one letter at a time\n", 252 | " guessedMessage = guessedMessage + x \n", 253 | "\n", 254 | " # Print the counter (the shift) and the message\n", 255 | " print(counter, guessedMessage)\n" 256 | ] 257 | }, 258 | { 259 | "cell_type": "markdown", 260 | "metadata": {}, 261 | "source": [ 262 | "Clearly, the length of the shift is 13 letters as only this one produces an intelligible message." 263 | ] 264 | } 265 | ], 266 | "metadata": { 267 | "kernelspec": { 268 | "display_name": "Python 3.7 (DL)", 269 | "language": "python", 270 | "name": "dl" 271 | }, 272 | "language_info": { 273 | "codemirror_mode": { 274 | "name": "ipython", 275 | "version": 3 276 | }, 277 | "file_extension": ".py", 278 | "mimetype": "text/x-python", 279 | "name": "python", 280 | "nbconvert_exporter": "python", 281 | "pygments_lexer": "ipython3", 282 | "version": "3.7.7" 283 | } 284 | }, 285 | "nbformat": 4, 286 | "nbformat_minor": 4 287 | } 288 | -------------------------------------------------------------------------------- /Chapter 04 - Combinatorics Using SciPy/.ipynb_checkpoints/Chapter4-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Chapter 4 - Combinatorics Using SciPy\n", 8 | "\n", 9 | "This notebook contains code accompanying Chapter 4 Combinatorics Using SciPy in *Practical Discrete Mathematics* by Ryan T. White and Archana Tikayat Ray.\n", 10 | "\n", 11 | "## Counting Permutations and Combinations of Objects\n", 12 | "\n", 13 | "### Growth of Factorials\n", 14 | "\n", 15 | "Below, we compute some factorials, which count permutations." 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 2, 21 | "metadata": {}, 22 | "outputs": [ 23 | { 24 | "name": "stdout", 25 | "output_type": "stream", 26 | "text": [ 27 | "2432902008176640000\n", 28 | "93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000\n" 29 | ] 30 | } 31 | ], 32 | "source": [ 33 | "import math\n", 34 | "print(math.factorial(20))\n", 35 | "print(math.factorial(100))" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "### Example: Counting playlists\n", 43 | "\n", 44 | "The number of 10-permutations of the 20-song list can be computed with Python as follows." 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 4, 50 | "metadata": {}, 51 | "outputs": [ 52 | { 53 | "name": "stdout", 54 | "output_type": "stream", 55 | "text": [ 56 | "670442572800.0\n" 57 | ] 58 | } 59 | ], 60 | "source": [ 61 | "import math\n", 62 | "print(math.factorial(20)/math.factorial(20-10))" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "### Example: Teambuilding\n", 70 | "\n", 71 | "The code below finds the number of possible 4-person teams we could build from four of twenty people." 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 5, 77 | "metadata": {}, 78 | "outputs": [ 79 | { 80 | "name": "stdout", 81 | "output_type": "stream", 82 | "text": [ 83 | "4845.0\n", 84 | "4845.0\n" 85 | ] 86 | } 87 | ], 88 | "source": [ 89 | "# using the factorial function\n", 90 | "import math\n", 91 | "print(math.factorial(20) / math.factorial(4) / math.factorial(20-4))\n", 92 | "\n", 93 | "# import the special functions from sciPy\n", 94 | "import scipy.special\n", 95 | "print(scipy.special.binom(20,4))" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "## Applications to Memory Allocation\n", 103 | "\n", 104 | "### Example: Pre-allocating Memory\n", 105 | "\n", 106 | "Suppose we wish to create a large list of 1,000,000 numbers. The simplest way is to just run a loop, adding one element at a time to the vector. (Note that the runtime will vary depending on the hardware where you run the code.)" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 9, 112 | "metadata": {}, 113 | "outputs": [ 114 | { 115 | "name": "stdout", 116 | "output_type": "stream", 117 | "text": [ 118 | "0.13155269622802734\n" 119 | ] 120 | } 121 | ], 122 | "source": [ 123 | "import time\n", 124 | "\n", 125 | "number = 1000000\n", 126 | "\n", 127 | "# Check the current time\n", 128 | "startTime = time.time()\n", 129 | "\n", 130 | "# Create an empty list\n", 131 | "list = []\n", 132 | "\n", 133 | "# Add items to the list one by one\n", 134 | "for counter in range(number):\n", 135 | " list.append(counter)\n", 136 | "\n", 137 | "# Display the run time\n", 138 | "print(time.time() - startTime)" 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "metadata": {}, 144 | "source": [ 145 | "The code below can pre-allocate an array with 1,000,000 and fill it in with 1, 2, ..., 1,000,000. (Note that the runtime will vary depending on the hardware where you run the code.)" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": 11, 151 | "metadata": {}, 152 | "outputs": [ 153 | { 154 | "name": "stdout", 155 | "output_type": "stream", 156 | "text": [ 157 | "0.10027527809143066\n" 158 | ] 159 | } 160 | ], 161 | "source": [ 162 | "import time\n", 163 | "number = 1000000\n", 164 | "\n", 165 | "# Check the current time\n", 166 | "startTime = time.time()\n", 167 | "\n", 168 | "# Create a list of 1000000 zeros\n", 169 | "list = [None]*number\n", 170 | "\n", 171 | "# Add items to the list one by one\n", 172 | "for counter in range(number):\n", 173 | " list[counter] = counter\n", 174 | "\n", 175 | "# Display the run time\n", 176 | "print(time.time() - startTime)" 177 | ] 178 | }, 179 | { 180 | "cell_type": "markdown", 181 | "metadata": {}, 182 | "source": [ 183 | "## Efficacy of Brute Force Algorithms\n", 184 | "\n", 185 | "### Example: Caesar Cipher\n", 186 | "\n", 187 | "A brute force check of how the text would be decoded for each possible Caesar cipher." 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": 12, 193 | "metadata": {}, 194 | "outputs": [ 195 | { 196 | "name": "stdout", 197 | "output_type": "stream", 198 | "text": [ 199 | "0 nzohfu gur rarzl ng avtug\n", 200 | "1 oapigv hvs sbsam oh bwuvh\n", 201 | "2 pbqjhw iwt tctbn pi cxvwi\n", 202 | "3 qcrkix jxu uduco qj dywxj\n", 203 | "4 rdsljy kyv vevdp rk ezxyk\n", 204 | "5 setmkz lzw wfweq sl fayzl\n", 205 | "6 tfunla max xgxfr tm gbzam\n", 206 | "7 ugvomb nby yhygs un hcabn\n", 207 | "8 vhwpnc ocz zizht vo idbco\n", 208 | "9 wixqod pda ajaiu wp jecdp\n", 209 | "10 xjyrpe qeb bkbjv xq kfdeq\n", 210 | "11 ykzsqf rfc clckw yr lgefr\n", 211 | "12 zlatrg sgd dmdlx zs mhfgs\n", 212 | "13 ambush the enemy at night\n", 213 | "14 bncvti uif fofnz bu ojhiu\n", 214 | "15 codwuj vjg gpgoa cv pkijv\n", 215 | "16 dpexvk wkh hqhpb dw qljkw\n", 216 | "17 eqfywl xli iriqc ex rmklx\n", 217 | "18 frgzxm ymj jsjrd fy snlmy\n", 218 | "19 gshayn znk ktkse gz tomnz\n", 219 | "20 htibzo aol lultf ha upnoa\n", 220 | "21 iujcap bpm mvmug ib vqopb\n", 221 | "22 jvkdbq cqn nwnvh jc wrpqc\n", 222 | "23 kwlecr dro oxowi kd xsqrd\n", 223 | "24 lxmfds esp pypxj le ytrse\n", 224 | "25 mynget ftq qzqyk mf zustf\n" 225 | ] 226 | } 227 | ], 228 | "source": [ 229 | "# Intercepted message\n", 230 | "codedMessage = 'nzohfu gur rarzl ng avtug'\n", 231 | "\n", 232 | "# We will shift by 0, shift by 1, shift by 2, ... and print the results\n", 233 | "for counter in range(26):\n", 234 | " # Start with no guess\n", 235 | " guessedMessage = ''\n", 236 | " \n", 237 | " # Loop through each letter in the coded message\n", 238 | " for x in codedMessage:\n", 239 | " \n", 240 | " # If x is not a space\n", 241 | " if x != ' ':\n", 242 | " \n", 243 | " # Shift the letter forward by counter\n", 244 | " if ord(x)+counter <= 122:\n", 245 | " x = chr(ord(x)+counter)\n", 246 | " \n", 247 | " # Subtract 26 if we go beyond z\n", 248 | " else:\n", 249 | " x = chr(ord(x)+counter-26)\n", 250 | " \n", 251 | " # Build a guess for the message one letter at a time\n", 252 | " guessedMessage = guessedMessage + x \n", 253 | "\n", 254 | " # Print the counter (the shift) and the message\n", 255 | " print(counter, guessedMessage)\n" 256 | ] 257 | }, 258 | { 259 | "cell_type": "markdown", 260 | "metadata": {}, 261 | "source": [ 262 | "Clearly, the length of the shift is 13 letters as only this one produces an intelligible message." 263 | ] 264 | } 265 | ], 266 | "metadata": { 267 | "kernelspec": { 268 | "display_name": "Python 3.7 (DL)", 269 | "language": "python", 270 | "name": "dl" 271 | }, 272 | "language_info": { 273 | "codemirror_mode": { 274 | "name": "ipython", 275 | "version": 3 276 | }, 277 | "file_extension": ".py", 278 | "mimetype": "text/x-python", 279 | "name": "python", 280 | "nbconvert_exporter": "python", 281 | "pygments_lexer": "ipython3", 282 | "version": "3.7.7" 283 | } 284 | }, 285 | "nbformat": 4, 286 | "nbformat_minor": 4 287 | } 288 | -------------------------------------------------------------------------------- /Chapter 08 - Storage and Feature Extraction of Graphs, Trees, and Networks/Chapter8.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Chapter 8 - Storage and Feature Extraction of Graphs, Trees, and Networks\n", 8 | "\n", 9 | "This notebook contains code accompanying Chapter 8 Storage and Feature Extraction of Graphs, Trees, and Networks in *Practical Discrete Mathematics* by Ryan T. White and Archana Tikayat Ray.\n", 10 | "\n", 11 | "## Storage of Graphs and Networks\n", 12 | "\n", 13 | "Below are adjacency matrices for storing the graphs in Figure 8.1 and Figure 8.8 as well as an adjacency matrix for the directed graph in Figure 8.6." 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 2, 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "name": "stdout", 23 | "output_type": "stream", 24 | "text": [ 25 | "A1 = [[0 1 1 0 1 0]\n", 26 | " [1 0 1 1 0 1]\n", 27 | " [1 1 0 1 1 0]\n", 28 | " [0 1 1 0 1 0]\n", 29 | " [1 0 1 1 0 0]\n", 30 | " [0 1 0 0 0 0]]\n", 31 | "\n", 32 | " A2 = [[0 1 0 0 0 0]\n", 33 | " [1 0 0 0 0 1]\n", 34 | " [0 0 0 1 1 0]\n", 35 | " [0 0 1 0 1 0]\n", 36 | " [0 0 1 1 0 0]\n", 37 | " [0 1 0 0 0 0]]\n", 38 | "\n", 39 | " A3 = [[0 0 1 0 0 0]\n", 40 | " [1 0 0 0 0 1]\n", 41 | " [0 0 0 0 1 0]\n", 42 | " [0 1 1 0 1 0]\n", 43 | " [1 0 1 1 0 0]\n", 44 | " [0 0 0 0 0 1]]\n" 45 | ] 46 | } 47 | ], 48 | "source": [ 49 | "import numpy \n", 50 | "\n", 51 | "# Create an adjacency matrix for the graph in Figure 8.1\n", 52 | "A1 = numpy.array([[0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1],\n", 53 | " [1, 1, 0, 1, 1, 0], [0, 1, 1, 0, 1, 0],\n", 54 | " [1, 0, 1, 1, 0, 0], [0, 1, 0, 0, 0, 0]])\n", 55 | " \n", 56 | "# Create an adjacency matrix for the graph in Figure 8.8\n", 57 | "A2 = numpy.array([[0, 1, 0, 0, 0, 0], [1, 0, 0, 0, 0, 1],\n", 58 | " [0, 0, 0, 1, 1, 0], [0, 0, 1, 0, 1, 0],\n", 59 | " [0, 0, 1, 1, 0, 0], [0, 1, 0, 0, 0, 0]])\n", 60 | "\n", 61 | "# Create an adjacency matrix for the directed graph in Figure 8.6\n", 62 | "A3 = numpy.array([[0, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 1],\n", 63 | " [0, 0, 0, 0, 1, 0], [0, 1, 1, 0, 1, 0],\n", 64 | " [1, 0, 1, 1, 0, 0], [0, 0, 0, 0, 0, 1]])\n", 65 | "\n", 66 | "# print the adjacency matrices\n", 67 | "print(\"A1 =\", A1)\n", 68 | "print(\"\\n A2 =\", A2)\n", 69 | "print(\"\\n A3 =\", A3)" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": {}, 75 | "source": [ 76 | "Below are weight matrices for the networks in Figure 8.5 and Figure 8.7." 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 3, 82 | "metadata": {}, 83 | "outputs": [ 84 | { 85 | "name": "stdout", 86 | "output_type": "stream", 87 | "text": [ 88 | "W1 = [[0 4 1 0 2 0]\n", 89 | " [4 0 2 1 0 1]\n", 90 | " [1 2 0 1 1 0]\n", 91 | " [0 1 1 0 2 0]\n", 92 | " [2 0 1 2 0 0]\n", 93 | " [0 1 0 0 0 0]]\n", 94 | "\n", 95 | " W2 = [[0 0 2 0 0 0]\n", 96 | " [1 0 0 0 0 2]\n", 97 | " [0 0 0 0 2 0]\n", 98 | " [0 2 3 0 4 0]\n", 99 | " [3 0 1 1 0 0]\n", 100 | " [0 0 0 0 0 1]]\n" 101 | ] 102 | } 103 | ], 104 | "source": [ 105 | "import numpy\n", 106 | "\n", 107 | "# Create a weight matrix for the network in Figure 8.5\n", 108 | "W1 = numpy.array([[0, 4, 1, 0, 2, 0], [4, 0, 2, 1, 0, 1],\n", 109 | " [1, 2, 0, 1, 1, 0], [0, 1, 1, 0, 2, 0],\n", 110 | " [2, 0, 1, 2, 0, 0], [0, 1, 0, 0, 0, 0]])\n", 111 | "\n", 112 | "# Create a weight matrix for the directed network in Figure 8.7\n", 113 | "W2 = numpy.array([[0, 0, 2, 0, 0, 0], [1, 0, 0, 0, 0, 2],\n", 114 | " [0, 0, 0, 0, 2, 0], [0, 2, 3, 0, 4, 0],\n", 115 | " [3, 0, 1, 1, 0, 0], [0, 0, 0, 0, 0, 1]])\n", 116 | "\n", 117 | "# Print the weight matrices\n", 118 | "print(\"W1 =\", W1)\n", 119 | "print(\"\\n W2 =\", W2)" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "## Feature Extraction of Graphs" 127 | ] 128 | }, 129 | { 130 | "cell_type": "markdown", 131 | "metadata": {}, 132 | "source": [ 133 | "Below is how we can find the degrees of the vertices of the graph in Figure 8.1." 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": 6, 139 | "metadata": {}, 140 | "outputs": [ 141 | { 142 | "name": "stdout", 143 | "output_type": "stream", 144 | "text": [ 145 | "[3 4 4 3 3 1]\n", 146 | "[3 4 4 3 3 1]\n" 147 | ] 148 | } 149 | ], 150 | "source": [ 151 | "# Find the degrees of each vertex of the graph in Figure 8.1\n", 152 | "\n", 153 | "# Using column sums\n", 154 | "print(numpy.sum(A1, axis=0))\n", 155 | "\n", 156 | "# Using row sums\n", 157 | "print(numpy.sum(A1, axis=1))" 158 | ] 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "metadata": {}, 163 | "source": [ 164 | "Below is how we can find the in-degrees and out-degrees of the vertices of the directed graph in Figure 8.6." 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 7, 170 | "metadata": {}, 171 | "outputs": [ 172 | { 173 | "name": "stdout", 174 | "output_type": "stream", 175 | "text": [ 176 | "[1 2 1 3 3 1]\n", 177 | "[2 1 3 1 2 2]\n", 178 | "11\n", 179 | "11\n" 180 | ] 181 | } 182 | ], 183 | "source": [ 184 | "# Find out-degrees for each vertex in the directed graph in Figure 8.6\n", 185 | "outdegrees = numpy.sum(A3, axis=1)\n", 186 | "print(outdegrees)\n", 187 | "\n", 188 | "# Find in-degrees for each vertex in the directed graph in Figure 8.6\n", 189 | "indegrees = numpy.sum(A3, axis=0)\n", 190 | "print(indegrees)\n", 191 | "\n", 192 | "print(numpy.sum(outdegrees))\n", 193 | "print(numpy.sum(indegrees))" 194 | ] 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "metadata": {}, 199 | "source": [ 200 | "Below is code to find the second and third powers of the adjacency matrix of the graph from Figure 8.1. The number in row $i$, column $j$ of each power represents the number of 2-edge and 3-edge paths between vertex $v_{i-1}$ and $v_{j-1}$, respectively." 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 8, 206 | "metadata": {}, 207 | "outputs": [ 208 | { 209 | "name": "stdout", 210 | "output_type": "stream", 211 | "text": [ 212 | "[[3 1 2 3 1 1]\n", 213 | " [1 4 2 1 3 0]\n", 214 | " [2 2 4 2 2 1]\n", 215 | " [3 1 2 3 1 1]\n", 216 | " [1 3 2 1 3 0]\n", 217 | " [1 0 1 1 0 1]]\n", 218 | "\n", 219 | " [[4 9 8 4 8 1]\n", 220 | " [9 4 9 9 4 4]\n", 221 | " [8 9 8 8 8 2]\n", 222 | " [4 9 8 4 8 1]\n", 223 | " [8 4 8 8 4 3]\n", 224 | " [1 4 2 1 3 0]]\n" 225 | ] 226 | } 227 | ], 228 | "source": [ 229 | "# Find the second power of adjacency matrix A1\n", 230 | "print(numpy.linalg.matrix_power(A1,2))\n", 231 | "\n", 232 | "# Find the third power of adjacency matrix A1\n", 233 | "print(\"\\n\", numpy.linalg.matrix_power(A1,3))" 234 | ] 235 | }, 236 | { 237 | "cell_type": "markdown", 238 | "metadata": {}, 239 | "source": [ 240 | "The code below finds the number of paths between several pairs of vertices of different lengths for the directed graph in Figure 8.8." 241 | ] 242 | }, 243 | { 244 | "cell_type": "code", 245 | "execution_count": 10, 246 | "metadata": {}, 247 | "outputs": [ 248 | { 249 | "name": "stdout", 250 | "output_type": "stream", 251 | "text": [ 252 | "There are 0 paths of length 1 from v1 to v6\n", 253 | "There are 1 paths of length 2 from v1 to v6\n", 254 | "There are 0 paths of length 3 from v1 to v6\n", 255 | "There are 2 paths of length 4 from v1 to v6\n", 256 | "There are 0 paths of length 5 from v1 to v6\n", 257 | "There are 4 paths of length 6 from v1 to v6\n", 258 | "There are 0 paths of length 1 from v2 to v3\n", 259 | "There are 0 paths of length 2 from v2 to v3\n", 260 | "There are 0 paths of length 3 from v2 to v3\n", 261 | "There are 0 paths of length 4 from v2 to v3\n", 262 | "There are 0 paths of length 5 from v2 to v3\n", 263 | "There are 0 paths of length 6 from v2 to v3\n" 264 | ] 265 | } 266 | ], 267 | "source": [ 268 | "# Print the number of paths from v1 to v6 of each length from 1 to 6\n", 269 | "for counter in range(1,7):\n", 270 | " A2counter = numpy.linalg.matrix_power(A2,counter)\n", 271 | " print(\"There are\", A2counter[0,5], \"paths of length\", counter, \"from v1 to v6\")\n", 272 | "\n", 273 | "# Print the number of paths from v2 to v3 of each length from 1 to 6\n", 274 | "for counter in range(1,7):\n", 275 | " A2counter = numpy.linalg.matrix_power(A2,counter)\n", 276 | " print(\"There are\", A2counter[1,2], \"paths of length\", counter, \"from v2 to v3\")" 277 | ] 278 | } 279 | ], 280 | "metadata": { 281 | "kernelspec": { 282 | "display_name": "Python [conda env:dl]", 283 | "language": "python", 284 | "name": "conda-env-dl-py" 285 | }, 286 | "language_info": { 287 | "codemirror_mode": { 288 | "name": "ipython", 289 | "version": 3 290 | }, 291 | "file_extension": ".py", 292 | "mimetype": "text/x-python", 293 | "name": "python", 294 | "nbconvert_exporter": "python", 295 | "pygments_lexer": "ipython3", 296 | "version": "3.7.7" 297 | } 298 | }, 299 | "nbformat": 4, 300 | "nbformat_minor": 4 301 | } 302 | -------------------------------------------------------------------------------- /Chapter 08 - Storage and Feature Extraction of Graphs, Trees, and Networks/.ipynb_checkpoints/Chapter8-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Chapter 8 - Storage and Feature Extraction of Graphs, Trees, and Networks\n", 8 | "\n", 9 | "This notebook contains code accompanying Chapter 8 Storage and Feature Extraction of Graphs, Trees, and Networks in *Practical Discrete Mathematics* by Ryan T. White and Archana Tikayat Ray\n", 10 | "\n", 11 | "## Storage of Graphs and Networks\n", 12 | "\n", 13 | "Below are adjacency matrices for storing the graphs in Figure 8.1 and Figure 8.8 as well as an adjacency matrix for the directed graph in Figure 8.6." 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 2, 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "name": "stdout", 23 | "output_type": "stream", 24 | "text": [ 25 | "A1 = [[0 1 1 0 1 0]\n", 26 | " [1 0 1 1 0 1]\n", 27 | " [1 1 0 1 1 0]\n", 28 | " [0 1 1 0 1 0]\n", 29 | " [1 0 1 1 0 0]\n", 30 | " [0 1 0 0 0 0]]\n", 31 | "\n", 32 | " A2 = [[0 1 0 0 0 0]\n", 33 | " [1 0 0 0 0 1]\n", 34 | " [0 0 0 1 1 0]\n", 35 | " [0 0 1 0 1 0]\n", 36 | " [0 0 1 1 0 0]\n", 37 | " [0 1 0 0 0 0]]\n", 38 | "\n", 39 | " A3 = [[0 0 1 0 0 0]\n", 40 | " [1 0 0 0 0 1]\n", 41 | " [0 0 0 0 1 0]\n", 42 | " [0 1 1 0 1 0]\n", 43 | " [1 0 1 1 0 0]\n", 44 | " [0 0 0 0 0 1]]\n" 45 | ] 46 | } 47 | ], 48 | "source": [ 49 | "import numpy \n", 50 | "\n", 51 | "# Create an adjacency matrix for the graph in Figure 8.1\n", 52 | "A1 = numpy.array([[0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1],\n", 53 | " [1, 1, 0, 1, 1, 0], [0, 1, 1, 0, 1, 0],\n", 54 | " [1, 0, 1, 1, 0, 0], [0, 1, 0, 0, 0, 0]])\n", 55 | " \n", 56 | "# Create an adjacency matrix for the graph in Figure 8.8\n", 57 | "A2 = numpy.array([[0, 1, 0, 0, 0, 0], [1, 0, 0, 0, 0, 1],\n", 58 | " [0, 0, 0, 1, 1, 0], [0, 0, 1, 0, 1, 0],\n", 59 | " [0, 0, 1, 1, 0, 0], [0, 1, 0, 0, 0, 0]])\n", 60 | "\n", 61 | "# Create an adjacency matrix for the directed graph in Figure 8.6\n", 62 | "A3 = numpy.array([[0, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 1],\n", 63 | " [0, 0, 0, 0, 1, 0], [0, 1, 1, 0, 1, 0],\n", 64 | " [1, 0, 1, 1, 0, 0], [0, 0, 0, 0, 0, 1]])\n", 65 | "\n", 66 | "# print the adjacency matrices\n", 67 | "print(\"A1 =\", A1)\n", 68 | "print(\"\\n A2 =\", A2)\n", 69 | "print(\"\\n A3 =\", A3)" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": {}, 75 | "source": [ 76 | "Below are weight matrices for the networks in Figure 8.5 and Figure 8.7." 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 3, 82 | "metadata": {}, 83 | "outputs": [ 84 | { 85 | "name": "stdout", 86 | "output_type": "stream", 87 | "text": [ 88 | "W1 = [[0 4 1 0 2 0]\n", 89 | " [4 0 2 1 0 1]\n", 90 | " [1 2 0 1 1 0]\n", 91 | " [0 1 1 0 2 0]\n", 92 | " [2 0 1 2 0 0]\n", 93 | " [0 1 0 0 0 0]]\n", 94 | "\n", 95 | " W2 = [[0 0 2 0 0 0]\n", 96 | " [1 0 0 0 0 2]\n", 97 | " [0 0 0 0 2 0]\n", 98 | " [0 2 3 0 4 0]\n", 99 | " [3 0 1 1 0 0]\n", 100 | " [0 0 0 0 0 1]]\n" 101 | ] 102 | } 103 | ], 104 | "source": [ 105 | "import numpy\n", 106 | "\n", 107 | "# Create a weight matrix for the network in Figure 8.5\n", 108 | "W1 = numpy.array([[0, 4, 1, 0, 2, 0], [4, 0, 2, 1, 0, 1],\n", 109 | " [1, 2, 0, 1, 1, 0], [0, 1, 1, 0, 2, 0],\n", 110 | " [2, 0, 1, 2, 0, 0], [0, 1, 0, 0, 0, 0]])\n", 111 | "\n", 112 | "# Create a weight matrix for the directed network in Figure 8.7\n", 113 | "W2 = numpy.array([[0, 0, 2, 0, 0, 0], [1, 0, 0, 0, 0, 2],\n", 114 | " [0, 0, 0, 0, 2, 0], [0, 2, 3, 0, 4, 0],\n", 115 | " [3, 0, 1, 1, 0, 0], [0, 0, 0, 0, 0, 1]])\n", 116 | "\n", 117 | "# Print the weight matrices\n", 118 | "print(\"W1 =\", W1)\n", 119 | "print(\"\\n W2 =\", W2)" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "## Feature Extraction of Graphs" 127 | ] 128 | }, 129 | { 130 | "cell_type": "markdown", 131 | "metadata": {}, 132 | "source": [ 133 | "Below is how we can find the degrees of the vertices of the graph in Figure 8.1." 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": 6, 139 | "metadata": {}, 140 | "outputs": [ 141 | { 142 | "name": "stdout", 143 | "output_type": "stream", 144 | "text": [ 145 | "[3 4 4 3 3 1]\n", 146 | "[3 4 4 3 3 1]\n" 147 | ] 148 | } 149 | ], 150 | "source": [ 151 | "# Find the degrees of each vertex of the graph in Figure 8.1\n", 152 | "\n", 153 | "# Using column sums\n", 154 | "print(numpy.sum(A1, axis=0))\n", 155 | "\n", 156 | "# Using row sums\n", 157 | "print(numpy.sum(A1, axis=1))" 158 | ] 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "metadata": {}, 163 | "source": [ 164 | "Below is how we can find the in-degrees and out-degrees of the vertices of the directed graph in Figure 8.6." 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 7, 170 | "metadata": {}, 171 | "outputs": [ 172 | { 173 | "name": "stdout", 174 | "output_type": "stream", 175 | "text": [ 176 | "[1 2 1 3 3 1]\n", 177 | "[2 1 3 1 2 2]\n", 178 | "11\n", 179 | "11\n" 180 | ] 181 | } 182 | ], 183 | "source": [ 184 | "# Find out-degrees for each vertex in the directed graph in Figure 8.6\n", 185 | "outdegrees = numpy.sum(A3, axis=1)\n", 186 | "print(outdegrees)\n", 187 | "\n", 188 | "# Find in-degrees for each vertex in the directed graph in Figure 8.6\n", 189 | "indegrees = numpy.sum(A3, axis=0)\n", 190 | "print(indegrees)\n", 191 | "\n", 192 | "print(numpy.sum(outdegrees))\n", 193 | "print(numpy.sum(indegrees))" 194 | ] 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "metadata": {}, 199 | "source": [ 200 | "Below is code to find the second and third powers of the adjacency matrix of the graph from Figure 8.1. The number in row $i$, column $j$ of each power represents the number of 2-edge and 3-edge paths between vertex $v_{i-1}$ and $v_{j-1}$, respectively." 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 8, 206 | "metadata": {}, 207 | "outputs": [ 208 | { 209 | "name": "stdout", 210 | "output_type": "stream", 211 | "text": [ 212 | "[[3 1 2 3 1 1]\n", 213 | " [1 4 2 1 3 0]\n", 214 | " [2 2 4 2 2 1]\n", 215 | " [3 1 2 3 1 1]\n", 216 | " [1 3 2 1 3 0]\n", 217 | " [1 0 1 1 0 1]]\n", 218 | "\n", 219 | " [[4 9 8 4 8 1]\n", 220 | " [9 4 9 9 4 4]\n", 221 | " [8 9 8 8 8 2]\n", 222 | " [4 9 8 4 8 1]\n", 223 | " [8 4 8 8 4 3]\n", 224 | " [1 4 2 1 3 0]]\n" 225 | ] 226 | } 227 | ], 228 | "source": [ 229 | "# Find the second power of adjacency matrix A1\n", 230 | "print(numpy.linalg.matrix_power(A1,2))\n", 231 | "\n", 232 | "# Find the third power of adjacency matrix A1\n", 233 | "print(\"\\n\", numpy.linalg.matrix_power(A1,3))" 234 | ] 235 | }, 236 | { 237 | "cell_type": "markdown", 238 | "metadata": {}, 239 | "source": [ 240 | "The code below finds the number of paths between several pairs of vertices of different lengths for the directed graph in Figure 8.8." 241 | ] 242 | }, 243 | { 244 | "cell_type": "code", 245 | "execution_count": 10, 246 | "metadata": {}, 247 | "outputs": [ 248 | { 249 | "name": "stdout", 250 | "output_type": "stream", 251 | "text": [ 252 | "There are 0 paths of length 1 from v1 to v6\n", 253 | "There are 1 paths of length 2 from v1 to v6\n", 254 | "There are 0 paths of length 3 from v1 to v6\n", 255 | "There are 2 paths of length 4 from v1 to v6\n", 256 | "There are 0 paths of length 5 from v1 to v6\n", 257 | "There are 4 paths of length 6 from v1 to v6\n", 258 | "There are 0 paths of length 1 from v2 to v3\n", 259 | "There are 0 paths of length 2 from v2 to v3\n", 260 | "There are 0 paths of length 3 from v2 to v3\n", 261 | "There are 0 paths of length 4 from v2 to v3\n", 262 | "There are 0 paths of length 5 from v2 to v3\n", 263 | "There are 0 paths of length 6 from v2 to v3\n" 264 | ] 265 | } 266 | ], 267 | "source": [ 268 | "# Print the number of paths from v1 to v6 of each length from 1 to 6\n", 269 | "for counter in range(1,7):\n", 270 | " A2counter = numpy.linalg.matrix_power(A2,counter)\n", 271 | " print(\"There are\", A2counter[0,5], \"paths of length\", counter, \"from v1 to v6\")\n", 272 | "\n", 273 | "# Print the number of paths from v2 to v3 of each length from 1 to 6\n", 274 | "for counter in range(1,7):\n", 275 | " A2counter = numpy.linalg.matrix_power(A2,counter)\n", 276 | " print(\"There are\", A2counter[1,2], \"paths of length\", counter, \"from v2 to v3\")" 277 | ] 278 | } 279 | ], 280 | "metadata": { 281 | "kernelspec": { 282 | "display_name": "Python [conda env:dl]", 283 | "language": "python", 284 | "name": "conda-env-dl-py" 285 | }, 286 | "language_info": { 287 | "codemirror_mode": { 288 | "name": "ipython", 289 | "version": 3 290 | }, 291 | "file_extension": ".py", 292 | "mimetype": "text/x-python", 293 | "name": "python", 294 | "nbconvert_exporter": "python", 295 | "pygments_lexer": "ipython3", 296 | "version": "3.7.7" 297 | } 298 | }, 299 | "nbformat": 4, 300 | "nbformat_minor": 4 301 | } 302 | -------------------------------------------------------------------------------- /Chapter 12 - Principal Components Analysis with scikit-learn/pizza.csv: -------------------------------------------------------------------------------- 1 | brand,moisture,protein,fat,ash,sodium,carbohydrates,calories 2 | A,27.82,21.43,44.87,5.11,1.77,0.77,4.93 3 | A,28.49,21.26,43.89,5.34,1.79,1.02,4.84 4 | A,28.35,19.99,45.78,5.08,1.63,0.8,4.95 5 | A,30.55,20.15,43.13,4.79,1.61,1.38,4.74 6 | A,30.49,21.28,41.65,4.82,1.64,1.76,4.67 7 | A,31.14,20.23,42.31,4.92,1.65,1.4,4.67 8 | A,31.21,20.97,41.34,4.71,1.58,1.77,4.63 9 | A,28.76,21.41,41.6,5.28,1.75,2.95,4.72 10 | A,28.22,20.48,45.1,5.02,1.71,1.18,4.93 11 | A,27.72,21.19,45.29,5.16,1.66,0.64,4.95 12 | A,27.35,21.2,45.59,4.94,1.65,0.92,4.98 13 | A,26.98,21.2,45.03,5.15,1.67,1.64,4.97 14 | A,28.7,20,45.12,4.93,1.56,1.25,4.91 15 | A,30.91,19.65,42.45,4.81,1.65,2.81,4.72 16 | A,30.91,20.77,42.03,4.9,1.61,1.39,4.67 17 | A,30.83,17.88,44.33,5.26,1.76,1.7,4.77 18 | A,32.73,20.06,39.74,5.24,1.69,2.23,4.47 19 | A,34.58,17.53,40.87,5.05,1.61,1.97,4.46 20 | A,31.8,20.35,40.44,5.43,1.61,1.98,4.53 21 | A,31.02,19.05,42.29,5.27,1.71,2.37,4.66 22 | A,27.02,19.56,47.2,4.95,1.65,1.27,5.08 23 | A,27.78,20.01,45.59,4.97,1.7,1.65,4.97 24 | A,30.88,20.58,42.26,4.96,1.63,1.32,4.68 25 | A,32.2,19.25,43.42,4.62,1.5,0.51,4.7 26 | A,33.19,18.05,41.88,5.22,1.7,1.66,4.56 27 | A,30.43,19.78,44.2,4.8,1.61,0.79,4.8 28 | A,28.93,19.99,45.2,4.78,1.62,1.1,4.91 29 | A,30.41,18.71,43.99,4.86,1.62,2.03,4.79 30 | A,29.62,21.1,43.37,5.05,1.69,0.86,4.78 31 | B,49.57,13.7,29.07,3.62,1.1,4.04,3.33 32 | B,52.68,14.38,25.72,3.26,0.93,3.96,3.05 33 | B,48.53,13.14,30.38,3.55,0.99,4.4,3.44 34 | B,50.19,13.78,28.39,3.56,1,4.08,3.27 35 | B,50.67,13.21,27.66,3.64,1,4.82,3.21 36 | B,49.99,13.35,29.2,3.52,1.05,3.94,3.32 37 | B,50.72,12.93,29.88,3.6,1.03,2.87,3.32 38 | B,50.81,12.56,29.95,2.99,0.81,3.69,3.35 39 | B,54.08,13.28,25.25,3.1,0.8,4.29,2.98 40 | B,51.9,14.27,24.92,3.85,1.06,5.06,3.02 41 | B,50.33,13.96,29.25,3.42,0.96,3.04,3.31 42 | B,49.69,13.63,29.59,3.41,0.98,3.68,3.36 43 | B,51.12,14.02,27.37,3.71,1.11,3.78,3.18 44 | B,49.77,13.24,28.91,3.59,1.06,4.49,3.31 45 | B,54.96,14.26,22.99,3.19,0.9,4.6,2.82 46 | B,55.11,14.87,21.9,3.29,0.86,4.83,2.76 47 | B,54.12,14.06,24.95,3.14,0.82,3.73,2.96 48 | B,49.34,13.79,29.57,3.52,0.95,3.78,3.36 49 | B,50.65,13.14,28.79,3.73,1.09,3.69,3.26 50 | B,52.46,14.18,24.6,3.57,1.12,5.19,2.99 51 | B,49.96,13.4,28.84,3.48,0.98,4.32,3.3 52 | B,49.57,13.17,29.39,3.59,1.06,4.28,3.35 53 | B,49.34,13.06,29.46,3.51,1.04,4.63,3.36 54 | B,50.87,13.85,27.64,3.71,1.1,3.93,3.2 55 | B,51.03,13.9,27.56,3.73,1.08,3.78,3.19 56 | B,53.98,14.05,24.73,3.32,0.92,3.92,2.94 57 | B,52.23,13.64,27.04,3.57,0.98,3.52,3.12 58 | B,51.74,13.95,27.75,3.6,1.04,2.96,3.17 59 | B,51.52,13.72,28.28,3.62,1.05,2.86,3.21 60 | B,51.86,13.13,28.82,2.94,0.8,3.25,3.25 61 | B,51.75,13.18,28.38,3.04,0.86,3.65,3.23 62 | C,48.4,26.05,21.4,3.44,0.5,0.71,3 63 | C,48.69,28.48,17.37,3.53,0.43,1.93,2.78 64 | C,48.88,25.23,20.89,3.22,0.47,1.78,2.96 65 | C,48.97,25.63,19.28,3.48,0.55,2.64,2.87 66 | C,48.84,23.98,23.37,3,0.52,0.81,3.09 67 | C,49.73,25.65,19.98,2.51,0.52,2.13,2.91 68 | C,50.18,28.3,15.79,3.47,0.45,2.26,2.64 69 | C,48.15,27.98,18.69,3.58,0.48,1.7,2.87 70 | C,49.72,27.31,16.89,3.08,0.25,3,2.73 71 | C,51.59,26.24,16.41,3.61,0.6,2.15,2.61 72 | C,52.26,26.31,14.77,3.51,0.53,3.15,2.51 73 | C,49.35,25.23,20.03,3.02,0.44,2.37,2.91 74 | C,47.91,26.03,21.54,3.71,0.6,0.81,3.01 75 | C,47.83,25.82,20.79,3.33,0.54,2.23,2.99 76 | C,47.9,25.55,21.1,3.04,0.43,2.41,3.02 77 | C,49.1,24.53,21.08,2.84,0.34,2.45,2.98 78 | C,50.04,24.13,19.75,3.21,0.52,2.87,2.86 79 | C,52.19,26,16.64,4.17,0.61,1,2.58 80 | C,47.11,26.17,21.29,3.36,0.48,2.07,3.05 81 | C,48.48,26.76,19.99,3.64,0.46,1.13,2.91 82 | C,52.22,26.25,16.45,3.92,0.38,1.16,2.58 83 | C,49.57,26.91,18,2.21,0.41,3.31,2.83 84 | C,51.71,24.98,17.2,3.01,0.34,3.1,2.67 85 | C,49.27,27.42,17.42,3.05,0.33,2.84,2.78 86 | C,47.25,23.95,24.24,3.47,0.57,1.09,3.18 87 | C,50.98,26.34,16.47,3.2,0.43,3.01,2.66 88 | C,49.57,25.46,20.79,3.04,0.37,1.14,2.94 89 | D,46.64,21.38,24.96,4.6,0.77,2.42,3.2 90 | D,45.93,21.6,25.87,4.51,0.73,2.09,3.28 91 | D,47.6,22.07,21.13,4.07,0.72,5.13,2.99 92 | D,47.61,22.44,19.61,4.06,0.6,6.28,2.91 93 | D,46.91,21.79,21.17,4.06,0.76,6.07,3.02 94 | D,46.88,21.71,23.6,4.59,0.75,3.22,3.12 95 | D,47.49,21.75,20.83,4.01,0.67,5.92,2.98 96 | D,48.03,21.96,20.88,4.02,0.7,5.11,2.96 97 | D,49.16,27.99,17.49,3.29,0.39,2.07,2.78 98 | D,47.17,22.29,21.3,4.08,0.74,5.16,3.02 99 | D,47.29,21.48,21.69,4.03,0.67,5.51,3.03 100 | D,47.53,21.11,21.54,4.02,0.7,5.8,3.02 101 | D,47.86,22.25,19.53,4.04,0.68,6.32,2.9 102 | D,48.09,22.65,21.59,5.22,0.93,2.45,2.95 103 | D,47.73,22.38,21.39,5.21,0.99,3.29,2.95 104 | D,48.44,22.73,21.05,5.22,0.98,2.56,2.91 105 | D,47.43,22.13,21.01,4.09,0.72,5.34,2.99 106 | D,47.68,21.84,20.45,4.06,0.71,5.97,2.95 107 | D,48.05,22.05,20.57,4.04,0.7,5.29,2.94 108 | D,48.01,21.31,21.05,4.01,0.73,5.62,2.97 109 | D,47.45,22.37,20.97,4.06,0.7,5.15,2.99 110 | D,47.8,22.36,20.39,4.02,0.7,5.43,2.95 111 | D,48.31,22.49,19.53,4.18,0.62,5.49,2.88 112 | D,46.19,21.19,25.18,4.66,0.8,2.78,3.23 113 | D,48.81,22.43,18.68,4.1,0.72,5.98,2.82 114 | D,48.89,22.95,21.93,5.26,0.85,0.97,2.93 115 | D,47.91,22.22,20.4,4.07,0.56,5.4,2.94 116 | D,46.28,21.51,25.44,4.58,0.6,2.19,3.24 117 | D,46.29,21.43,26,4.71,0.69,1.57,3.26 118 | D,47.03,20.84,25.68,4.52,0.69,1.93,3.22 119 | D,46.8,20.7,25.1,4.55,0.7,2.85,3.2 120 | D,52.19,26,16.64,4.17,0.61,1,2.58 121 | E,34.58,7.44,16.24,1.31,0.39,40.43,3.38 122 | E,36.84,7.77,17.07,1.37,0.4,36.95,3.33 123 | E,35.14,8.05,15.77,1.38,0.41,39.66,3.33 124 | E,39.25,8.67,4.44,1.54,0.51,46.1,2.59 125 | E,34.51,7.75,14.87,1.42,0.42,41.45,3.31 126 | E,39.59,8.36,4.39,1.52,0.48,46.14,2.58 127 | E,34.94,7.81,13.67,1.36,0.4,42.22,3.23 128 | E,39.36,8.1,16.44,1.45,0.44,34.65,3.19 129 | E,36.04,7.74,15.49,1.45,0.45,39.28,3.27 130 | E,36.54,7.75,15.67,1.43,0.44,38.61,3.26 131 | E,37.78,8.3,13.05,1.64,0.49,39.23,3.08 132 | E,35.3,7.92,13.85,1.46,0.4,41.47,3.22 133 | E,34.47,7.62,19.07,1.44,0.44,37.4,3.52 134 | E,33.24,7.54,19.56,1.32,0.43,38.34,3.6 135 | E,37.34,7.33,19.61,1.6,0.45,34.12,3.42 136 | E,37.59,7.93,13.58,1.43,0.45,39.47,3.12 137 | E,36.5,7.52,12.46,1.51,0.47,42.01,3.1 138 | E,37.34,7.33,19.61,1.6,0.45,34.12,3.42 139 | E,34.31,7.98,14.54,1.46,0.49,41.71,3.3 140 | E,36.69,7.8,14.77,1.46,0.46,39.28,3.21 141 | E,34.23,7.75,17.94,1.61,0.44,38.47,3.46 142 | E,35.54,7.47,17.67,1.44,0.47,37.88,3.4 143 | E,35.21,6.98,20.02,1.35,0.46,36.44,3.54 144 | E,33.65,7.11,19.5,1.48,0.45,38.26,3.57 145 | E,34.77,7.26,18.8,1.58,0.43,37.59,3.49 146 | E,37.32,7.4,8.18,1.63,0.53,45.47,2.85 147 | E,37.78,8.3,13.05,1.64,0.49,39.23,3.08 148 | E,34.48,7.54,13.93,1.45,0.44,42.6,3.26 149 | F,28.03,7.65,18.39,1.53,0.49,44.4,3.74 150 | F,30.09,7.99,15.16,1.46,0.48,45.3,3.5 151 | F,29.79,8.17,14.35,1.49,0.46,46.2,3.46 152 | F,30.07,8.02,20.39,1.45,0.45,40.07,3.76 153 | F,28.46,7.7,18.88,1.4,0.43,43.56,3.75 154 | F,30.29,8.09,14.82,1.52,0.51,45.28,3.47 155 | F,28.66,7.67,16.12,1.41,0.43,46.14,3.6 156 | F,30.96,8.31,13.42,1.49,0.43,45.82,3.37 157 | F,29.78,8.2,14.51,1.5,0.5,46.01,3.47 158 | F,30.28,7.76,16.04,1.4,0.42,44.52,3.53 159 | F,29.92,8.11,19.23,1.51,0.48,41.23,3.7 160 | F,29.54,7.79,15.08,1.41,0.45,46.18,3.52 161 | F,28.93,8.18,19.35,1.39,0.58,42.15,3.75 162 | F,29.89,7.95,15.08,1.45,0.47,45.63,3.5 163 | F,27.65,7.78,17.3,1.29,0.4,46.25,3.72 164 | F,28.33,7.82,17.96,1.41,0.45,44.48,3.71 165 | F,29.1,8.07,20.05,1.45,0.45,41.33,3.78 166 | F,29.59,8.05,14.07,1.44,0.45,46.22,3.49 167 | F,27.93,7.88,17.49,1.44,0.47,45.26,3.96 168 | F,30.53,8.02,14.17,1.49,0.47,45.79,3.43 169 | F,30.68,8.11,12.92,1.56,0.47,46.73,3.36 170 | F,30.15,8.06,12.23,1.5,0.47,48.06,3.35 171 | F,29.3,8.02,16.34,1.43,0.45,44.91,3.59 172 | F,29.69,7.63,15.71,1.63,0.46,45.34,3.53 173 | F,29,7.51,17.78,1.58,0.43,44.13,3.67 174 | F,28.98,7.7,16.67,1.48,0.47,45.17,3.62 175 | F,28.84,7.88,17.21,1.42,0.46,44.65,3.65 176 | F,28.34,7.6,18.51,1.45,0.46,44.1,3.73 177 | F,28.36,7.62,19.29,1.45,0.47,43.28,3.77 178 | F,30.97,7.6,14.22,1.78,0.45,45.43,3.4 179 | G,28.15,8.23,15.45,1.41,0.45,46.76,3.59 180 | G,28.35,8.19,14.9,1.4,0.43,47.16,3.56 181 | G,30.85,8.03,13.67,1.41,0.42,46.04,3.39 182 | G,28.21,8.3,15,1.41,0.43,47.08,3.57 183 | G,28.83,8.26,20.1,1.37,0.42,41.44,3.8 184 | G,28.29,8.05,16.72,1.31,0.43,45.63,3.65 185 | G,28.68,8.3,16.07,1.41,0.45,45.54,3.6 186 | G,27.71,8.28,15.62,1.53,0.5,46.86,3.61 187 | G,28.03,8.27,16.4,1.37,0.41,45.93,3.64 188 | G,28.13,8.34,16.19,1.42,0.45,45.92,3.63 189 | G,28.09,8.42,14.06,1.47,0.45,47.96,3.52 190 | G,28.19,8.57,14.16,1.76,0.42,47.32,3.51 191 | G,28.63,8.42,15.24,1.43,0.43,46.28,3.56 192 | G,33.09,7.87,12.07,1.37,0.44,45.6,3.23 193 | G,26.33,8.03,19.98,1.43,0.45,44.23,3.89 194 | G,27.28,8.55,15.18,1.51,0.46,47.48,3.61 195 | G,27.56,8.25,14.65,1.45,0.46,48.09,3.57 196 | G,27.72,8.06,15.34,1.35,0.42,47.53,3.6 197 | G,30.63,8.21,17.33,1.39,0.42,42.44,3.59 198 | G,29.06,8.46,14.12,1.47,0.47,46.89,3.48 199 | G,28.55,8.25,17.3,1.48,0.47,44.42,3.66 200 | G,27.16,8.27,14.68,1.79,0.46,48.1,3.58 201 | G,28.33,8.17,13.64,1.45,0.47,48.41,3.49 202 | G,26.19,7.99,17.53,1.42,0.44,46.87,3.77 203 | G,26.45,7.89,17.97,1.3,0.39,46.39,3.79 204 | G,27.72,8.24,15.16,1.46,0.45,47.42,3.59 205 | G,25,8.49,16.87,1.45,0.47,48.19,3.79 206 | G,29.14,8.46,12.25,1.51,0.46,48.64,3.39 207 | G,28.64,8.01,16.02,1.43,0.45,45.9,3.6 208 | H,36.12,8.33,11.9,1.42,0.39,42.23,3.09 209 | H,35.1,8.04,19.07,1.36,0.41,36.43,3.5 210 | H,35.48,7.66,15.39,1.37,0.46,40.1,3.3 211 | H,35.66,9.04,6.24,1.5,0.42,47.56,2.83 212 | H,35.61,8.07,16.15,1.41,0.4,38.81,3.33 213 | H,35.68,8.01,16.36,1.3,0.39,38.65,3.34 214 | H,40.72,8.34,4.96,1.42,0.43,44.56,2.56 215 | H,35.55,7.32,16.4,1.76,0.36,38.97,3.33 216 | H,33.05,7.34,15.78,1.34,0.42,42.49,3.41 217 | H,33.75,8.07,14.93,1.31,0.4,41.94,3.34 218 | H,38.84,8.55,4.38,1.41,0.43,46.82,2.61 219 | H,33.44,7.45,18.49,1.39,0.4,39.23,3.53 220 | H,36.43,8.67,15.05,1.35,0.38,38.5,3.24 221 | H,35.84,7.9,14.09,1.25,0.42,40.92,3.22 222 | H,36.63,8.38,12.59,1.36,0.41,41.04,3.11 223 | H,35.5,8.11,13.45,1.34,0.42,41.59,3.2 224 | H,36.87,7.82,14.58,1.32,0.4,39.41,3.2 225 | H,35.5,7.51,15.63,1.42,0.42,39.94,3.3 226 | H,33.9,7.76,15.84,1.3,0.42,41.2,3.38 227 | H,35.8,7.82,14.08,1.43,0.42,40.87,3.21 228 | H,35.74,7.86,14.27,1.4,0.44,40.73,3.23 229 | H,35.74,7.47,19.14,1.34,0.4,36.31,3.47 230 | H,35.99,8.23,16.6,1.4,0.45,37.78,3.33 231 | H,35.5,7.9,13.83,1.41,0.46,41.36,3.22 232 | H,35.91,7.41,16.41,1.75,0.43,38.52,3.31 233 | H,36.01,7.7,15.6,1.37,0.43,39.32,3.28 234 | H,36.73,7.42,18.16,1.17,0.39,36.52,3.39 235 | H,35.86,7.47,14.72,1.67,0.4,40.28,3.23 236 | H,36.32,8.06,12.54,1.35,0.43,41.73,3.12 237 | H,34.61,7.17,17.88,1.29,0.4,39.05,3.46 238 | H,36.67,7.81,9.34,1.64,0.44,44.54,2.93 239 | H,35.94,7.97,13.5,1.45,0.42,41.14,3.18 240 | H,35.74,7.86,14.27,1.4,0.44,40.73,3.23 241 | I,54.64,10.36,12.89,2.21,0.53,19.9,2.37 242 | I,54.52,9.85,13.55,2.04,0.47,20.05,2.42 243 | I,53.84,10.22,13.05,2.07,0.48,20.82,2.42 244 | I,54.32,10.66,14.04,2.03,0.46,18.95,2.45 245 | I,52.9,10.19,14.35,2.02,0.49,20.54,2.52 246 | I,55,11.11,11.3,2.05,0.47,20.54,2.28 247 | I,56.24,9.06,11.49,1.93,0.48,21.28,2.25 248 | I,56.25,9.96,13.22,2.05,0.46,18.52,2.33 249 | I,54.43,9.61,12.18,2.16,0.51,21.62,2.35 250 | I,53.69,11,15.23,2.25,0.55,17.83,2.52 251 | I,54.69,10.32,13.77,2.15,0.48,19.07,2.41 252 | I,53.16,11.17,13.83,2.18,0.47,19.66,2.48 253 | I,55.15,10.92,12.51,2.2,0.51,19.22,2.33 254 | I,54.87,10.78,13.65,2.08,0.5,18.62,2.4 255 | I,55.43,10.46,12.37,2.17,0.51,19.57,2.31 256 | I,55.6,9.69,13.89,1.99,0.48,18.83,2.39 257 | I,54.51,9.93,12.66,2.07,0.53,20.83,2.37 258 | I,54.74,10.18,12.6,2.06,0.48,20.42,2.36 259 | I,54.17,10.67,12.18,2.08,0.49,20.9,2.36 260 | I,52.75,10.78,12.98,2.12,0.49,21.37,2.45 261 | I,54.36,11.43,13.09,2.24,0.48,18.88,2.39 262 | I,54.28,10.75,13.87,2.13,0.46,18.97,2.4 263 | I,54.54,10.4,13.22,2.1,0.47,19.74,2.4 264 | I,54.06,10.68,13.53,2.04,0.46,19.69,2.43 265 | I,57.22,9.66,10.95,2.04,0.47,20.13,2.18 266 | I,54.8,10.57,13.42,2.08,0.5,19.13,2.4 267 | I,54.17,10.13,13.25,2.07,0.46,20.38,2.41 268 | I,53.57,10.73,12.78,2.16,0.48,20.76,2.41 269 | I,55.29,9.84,12.91,2.08,0.51,19.88,2.35 270 | J,46.16,10.34,16.14,2.47,0.67,24.89,2.86 271 | J,43.8,10.97,16.49,2.46,0.65,26.28,2.97 272 | J,47.6,10.43,15.18,2.32,0.56,24.47,2.76 273 | J,46.84,9.91,15.5,2.27,0.57,25.48,2.81 274 | J,46.1,9.87,15.97,2.19,0.53,25.87,2.87 275 | J,47.84,10.16,14.56,2.27,0.54,25.17,2.72 276 | J,45.86,10.5,17.07,2.33,0.61,24.24,2.93 277 | J,46.55,10.75,16.72,2.24,0.61,23.74,2.88 278 | J,46.13,10.71,17.24,2.36,0.61,23.56,2.92 279 | J,48.58,9.76,16.01,2.3,0.6,23.35,2.77 280 | J,44.76,12.91,15.56,2.34,0.61,24.43,2.89 281 | J,46.13,10.84,13.99,2.38,0.64,26.66,2.76 282 | J,47.43,10.45,16.5,2.35,0.61,23.27,2.83 283 | J,46.22,11.26,15.93,2.47,0.63,24.12,2.85 284 | J,45.2,10.67,16.38,2.44,0.6,25.31,2.91 285 | J,47.05,10.46,15.16,2.34,0.64,24.99,2.78 286 | J,43.45,10.81,19.49,2.51,0.68,23.74,3.14 287 | J,47.74,10.23,16.31,2.5,0.67,23.22,2.81 288 | J,45.17,10.42,17.2,2.34,0.61,24.87,2.96 289 | J,44.77,10.52,16.12,2.44,0.66,26.15,2.92 290 | J,47.91,10.75,16,2.4,0.64,22.94,2.79 291 | J,45.69,10.23,16.5,2.3,0.59,25.28,2.91 292 | J,46.12,10.3,16.38,2.35,0.61,24.85,2.88 293 | J,47.35,10.31,15.45,2.34,0.62,24.55,2.78 294 | J,45.21,9.39,16.23,2.14,0.55,27.03,2.92 295 | J,46.34,10,17.73,2.32,0.59,23.61,2.94 296 | J,44.07,10.96,18.39,2.56,0.66,24.02,3.05 297 | J,44.91,11.07,17,2.49,0.66,25.36,2.91 298 | J,43.15,11.79,18.46,2.43,0.67,24.17,3.1 299 | J,44.55,11.01,16.03,2.43,0.64,25.98,2.92 300 | J,47.6,10.43,15.18,2.32,0.56,24.47,2.76 301 | J,46.84,9.91,15.5,2.27,0.57,25.48,2.81 302 | -------------------------------------------------------------------------------- /Chapter 10 - Regression Analysis/auto_dataset.csv: -------------------------------------------------------------------------------- 1 | ,mpg,cylinders,displacement,horsepower,weight,acceleration 2 | 0,18.0,8,307.0,130.0,3504,12.0 3 | 1,15.0,8,350.0,165.0,3693,11.5 4 | 2,18.0,8,318.0,150.0,3436,11.0 5 | 3,16.0,8,304.0,150.0,3433,12.0 6 | 4,17.0,8,302.0,140.0,3449,10.5 7 | 5,15.0,8,429.0,198.0,4341,10.0 8 | 6,14.0,8,454.0,220.0,4354,9.0 9 | 7,14.0,8,440.0,215.0,4312,8.5 10 | 8,14.0,8,455.0,225.0,4425,10.0 11 | 9,15.0,8,390.0,190.0,3850,8.5 12 | 10,15.0,8,383.0,170.0,3563,10.0 13 | 11,14.0,8,340.0,160.0,3609,8.0 14 | 12,15.0,8,400.0,150.0,3761,9.5 15 | 13,14.0,8,455.0,225.0,3086,10.0 16 | 14,24.0,4,113.0,95.0,2372,15.0 17 | 15,22.0,6,198.0,95.0,2833,15.5 18 | 16,18.0,6,199.0,97.0,2774,15.5 19 | 17,21.0,6,200.0,85.0,2587,16.0 20 | 18,27.0,4,97.0,88.0,2130,14.5 21 | 19,26.0,4,97.0,46.0,1835,20.5 22 | 20,25.0,4,110.0,87.0,2672,17.5 23 | 21,24.0,4,107.0,90.0,2430,14.5 24 | 22,25.0,4,104.0,95.0,2375,17.5 25 | 23,26.0,4,121.0,113.0,2234,12.5 26 | 24,21.0,6,199.0,90.0,2648,15.0 27 | 25,10.0,8,360.0,215.0,4615,14.0 28 | 26,10.0,8,307.0,200.0,4376,15.0 29 | 27,11.0,8,318.0,210.0,4382,13.5 30 | 28,9.0,8,304.0,193.0,4732,18.5 31 | 29,27.0,4,97.0,88.0,2130,14.5 32 | 30,28.0,4,140.0,90.0,2264,15.5 33 | 31,25.0,4,113.0,95.0,2228,14.0 34 | 33,19.0,6,232.0,100.0,2634,13.0 35 | 34,16.0,6,225.0,105.0,3439,15.5 36 | 35,17.0,6,250.0,100.0,3329,15.5 37 | 36,19.0,6,250.0,88.0,3302,15.5 38 | 37,18.0,6,232.0,100.0,3288,15.5 39 | 38,14.0,8,350.0,165.0,4209,12.0 40 | 39,14.0,8,400.0,175.0,4464,11.5 41 | 40,14.0,8,351.0,153.0,4154,13.5 42 | 41,14.0,8,318.0,150.0,4096,13.0 43 | 42,12.0,8,383.0,180.0,4955,11.5 44 | 43,13.0,8,400.0,170.0,4746,12.0 45 | 44,13.0,8,400.0,175.0,5140,12.0 46 | 45,18.0,6,258.0,110.0,2962,13.5 47 | 46,22.0,4,140.0,72.0,2408,19.0 48 | 47,19.0,6,250.0,100.0,3282,15.0 49 | 48,18.0,6,250.0,88.0,3139,14.5 50 | 49,23.0,4,122.0,86.0,2220,14.0 51 | 50,28.0,4,116.0,90.0,2123,14.0 52 | 51,30.0,4,79.0,70.0,2074,19.5 53 | 52,30.0,4,88.0,76.0,2065,14.5 54 | 53,31.0,4,71.0,65.0,1773,19.0 55 | 54,35.0,4,72.0,69.0,1613,18.0 56 | 55,27.0,4,97.0,60.0,1834,19.0 57 | 56,26.0,4,91.0,70.0,1955,20.5 58 | 57,24.0,4,113.0,95.0,2278,15.5 59 | 58,25.0,4,97.5,80.0,2126,17.0 60 | 59,23.0,4,97.0,54.0,2254,23.5 61 | 60,20.0,4,140.0,90.0,2408,19.5 62 | 61,21.0,4,122.0,86.0,2226,16.5 63 | 62,13.0,8,350.0,165.0,4274,12.0 64 | 63,14.0,8,400.0,175.0,4385,12.0 65 | 64,15.0,8,318.0,150.0,4135,13.5 66 | 65,14.0,8,351.0,153.0,4129,13.0 67 | 66,17.0,8,304.0,150.0,3672,11.5 68 | 67,11.0,8,429.0,208.0,4633,11.0 69 | 68,13.0,8,350.0,155.0,4502,13.5 70 | 69,12.0,8,350.0,160.0,4456,13.5 71 | 70,13.0,8,400.0,190.0,4422,12.5 72 | 71,19.0,3,70.0,97.0,2330,13.5 73 | 72,15.0,8,304.0,150.0,3892,12.5 74 | 73,13.0,8,307.0,130.0,4098,14.0 75 | 74,13.0,8,302.0,140.0,4294,16.0 76 | 75,14.0,8,318.0,150.0,4077,14.0 77 | 76,18.0,4,121.0,112.0,2933,14.5 78 | 77,22.0,4,121.0,76.0,2511,18.0 79 | 78,21.0,4,120.0,87.0,2979,19.5 80 | 79,26.0,4,96.0,69.0,2189,18.0 81 | 80,22.0,4,122.0,86.0,2395,16.0 82 | 81,28.0,4,97.0,92.0,2288,17.0 83 | 82,23.0,4,120.0,97.0,2506,14.5 84 | 83,28.0,4,98.0,80.0,2164,15.0 85 | 84,27.0,4,97.0,88.0,2100,16.5 86 | 85,13.0,8,350.0,175.0,4100,13.0 87 | 86,14.0,8,304.0,150.0,3672,11.5 88 | 87,13.0,8,350.0,145.0,3988,13.0 89 | 88,14.0,8,302.0,137.0,4042,14.5 90 | 89,15.0,8,318.0,150.0,3777,12.5 91 | 90,12.0,8,429.0,198.0,4952,11.5 92 | 91,13.0,8,400.0,150.0,4464,12.0 93 | 92,13.0,8,351.0,158.0,4363,13.0 94 | 93,14.0,8,318.0,150.0,4237,14.5 95 | 94,13.0,8,440.0,215.0,4735,11.0 96 | 95,12.0,8,455.0,225.0,4951,11.0 97 | 96,13.0,8,360.0,175.0,3821,11.0 98 | 97,18.0,6,225.0,105.0,3121,16.5 99 | 98,16.0,6,250.0,100.0,3278,18.0 100 | 99,18.0,6,232.0,100.0,2945,16.0 101 | 100,18.0,6,250.0,88.0,3021,16.5 102 | 101,23.0,6,198.0,95.0,2904,16.0 103 | 102,26.0,4,97.0,46.0,1950,21.0 104 | 103,11.0,8,400.0,150.0,4997,14.0 105 | 104,12.0,8,400.0,167.0,4906,12.5 106 | 105,13.0,8,360.0,170.0,4654,13.0 107 | 106,12.0,8,350.0,180.0,4499,12.5 108 | 107,18.0,6,232.0,100.0,2789,15.0 109 | 108,20.0,4,97.0,88.0,2279,19.0 110 | 109,21.0,4,140.0,72.0,2401,19.5 111 | 110,22.0,4,108.0,94.0,2379,16.5 112 | 111,18.0,3,70.0,90.0,2124,13.5 113 | 112,19.0,4,122.0,85.0,2310,18.5 114 | 113,21.0,6,155.0,107.0,2472,14.0 115 | 114,26.0,4,98.0,90.0,2265,15.5 116 | 115,15.0,8,350.0,145.0,4082,13.0 117 | 116,16.0,8,400.0,230.0,4278,9.5 118 | 117,29.0,4,68.0,49.0,1867,19.5 119 | 118,24.0,4,116.0,75.0,2158,15.5 120 | 119,20.0,4,114.0,91.0,2582,14.0 121 | 120,19.0,4,121.0,112.0,2868,15.5 122 | 121,15.0,8,318.0,150.0,3399,11.0 123 | 122,24.0,4,121.0,110.0,2660,14.0 124 | 123,20.0,6,156.0,122.0,2807,13.5 125 | 124,11.0,8,350.0,180.0,3664,11.0 126 | 125,20.0,6,198.0,95.0,3102,16.5 127 | 127,19.0,6,232.0,100.0,2901,16.0 128 | 128,15.0,6,250.0,100.0,3336,17.0 129 | 129,31.0,4,79.0,67.0,1950,19.0 130 | 130,26.0,4,122.0,80.0,2451,16.5 131 | 131,32.0,4,71.0,65.0,1836,21.0 132 | 132,25.0,4,140.0,75.0,2542,17.0 133 | 133,16.0,6,250.0,100.0,3781,17.0 134 | 134,16.0,6,258.0,110.0,3632,18.0 135 | 135,18.0,6,225.0,105.0,3613,16.5 136 | 136,16.0,8,302.0,140.0,4141,14.0 137 | 137,13.0,8,350.0,150.0,4699,14.5 138 | 138,14.0,8,318.0,150.0,4457,13.5 139 | 139,14.0,8,302.0,140.0,4638,16.0 140 | 140,14.0,8,304.0,150.0,4257,15.5 141 | 141,29.0,4,98.0,83.0,2219,16.5 142 | 142,26.0,4,79.0,67.0,1963,15.5 143 | 143,26.0,4,97.0,78.0,2300,14.5 144 | 144,31.0,4,76.0,52.0,1649,16.5 145 | 145,32.0,4,83.0,61.0,2003,19.0 146 | 146,28.0,4,90.0,75.0,2125,14.5 147 | 147,24.0,4,90.0,75.0,2108,15.5 148 | 148,26.0,4,116.0,75.0,2246,14.0 149 | 149,24.0,4,120.0,97.0,2489,15.0 150 | 150,26.0,4,108.0,93.0,2391,15.5 151 | 151,31.0,4,79.0,67.0,2000,16.0 152 | 152,19.0,6,225.0,95.0,3264,16.0 153 | 153,18.0,6,250.0,105.0,3459,16.0 154 | 154,15.0,6,250.0,72.0,3432,21.0 155 | 155,15.0,6,250.0,72.0,3158,19.5 156 | 156,16.0,8,400.0,170.0,4668,11.5 157 | 157,15.0,8,350.0,145.0,4440,14.0 158 | 158,16.0,8,318.0,150.0,4498,14.5 159 | 159,14.0,8,351.0,148.0,4657,13.5 160 | 160,17.0,6,231.0,110.0,3907,21.0 161 | 161,16.0,6,250.0,105.0,3897,18.5 162 | 162,15.0,6,258.0,110.0,3730,19.0 163 | 163,18.0,6,225.0,95.0,3785,19.0 164 | 164,21.0,6,231.0,110.0,3039,15.0 165 | 165,20.0,8,262.0,110.0,3221,13.5 166 | 166,13.0,8,302.0,129.0,3169,12.0 167 | 167,29.0,4,97.0,75.0,2171,16.0 168 | 168,23.0,4,140.0,83.0,2639,17.0 169 | 169,20.0,6,232.0,100.0,2914,16.0 170 | 170,23.0,4,140.0,78.0,2592,18.5 171 | 171,24.0,4,134.0,96.0,2702,13.5 172 | 172,25.0,4,90.0,71.0,2223,16.5 173 | 173,24.0,4,119.0,97.0,2545,17.0 174 | 174,18.0,6,171.0,97.0,2984,14.5 175 | 175,29.0,4,90.0,70.0,1937,14.0 176 | 176,19.0,6,232.0,90.0,3211,17.0 177 | 177,23.0,4,115.0,95.0,2694,15.0 178 | 178,23.0,4,120.0,88.0,2957,17.0 179 | 179,22.0,4,121.0,98.0,2945,14.5 180 | 180,25.0,4,121.0,115.0,2671,13.5 181 | 181,33.0,4,91.0,53.0,1795,17.5 182 | 182,28.0,4,107.0,86.0,2464,15.5 183 | 183,25.0,4,116.0,81.0,2220,16.9 184 | 184,25.0,4,140.0,92.0,2572,14.9 185 | 185,26.0,4,98.0,79.0,2255,17.7 186 | 186,27.0,4,101.0,83.0,2202,15.3 187 | 187,17.5,8,305.0,140.0,4215,13.0 188 | 188,16.0,8,318.0,150.0,4190,13.0 189 | 189,15.5,8,304.0,120.0,3962,13.9 190 | 190,14.5,8,351.0,152.0,4215,12.8 191 | 191,22.0,6,225.0,100.0,3233,15.4 192 | 192,22.0,6,250.0,105.0,3353,14.5 193 | 193,24.0,6,200.0,81.0,3012,17.6 194 | 194,22.5,6,232.0,90.0,3085,17.6 195 | 195,29.0,4,85.0,52.0,2035,22.2 196 | 196,24.5,4,98.0,60.0,2164,22.1 197 | 197,29.0,4,90.0,70.0,1937,14.2 198 | 198,33.0,4,91.0,53.0,1795,17.4 199 | 199,20.0,6,225.0,100.0,3651,17.7 200 | 200,18.0,6,250.0,78.0,3574,21.0 201 | 201,18.5,6,250.0,110.0,3645,16.2 202 | 202,17.5,6,258.0,95.0,3193,17.8 203 | 203,29.5,4,97.0,71.0,1825,12.2 204 | 204,32.0,4,85.0,70.0,1990,17.0 205 | 205,28.0,4,97.0,75.0,2155,16.4 206 | 206,26.5,4,140.0,72.0,2565,13.6 207 | 207,20.0,4,130.0,102.0,3150,15.7 208 | 208,13.0,8,318.0,150.0,3940,13.2 209 | 209,19.0,4,120.0,88.0,3270,21.9 210 | 210,19.0,6,156.0,108.0,2930,15.5 211 | 211,16.5,6,168.0,120.0,3820,16.7 212 | 212,16.5,8,350.0,180.0,4380,12.1 213 | 213,13.0,8,350.0,145.0,4055,12.0 214 | 214,13.0,8,302.0,130.0,3870,15.0 215 | 215,13.0,8,318.0,150.0,3755,14.0 216 | 216,31.5,4,98.0,68.0,2045,18.5 217 | 217,30.0,4,111.0,80.0,2155,14.8 218 | 218,36.0,4,79.0,58.0,1825,18.6 219 | 219,25.5,4,122.0,96.0,2300,15.5 220 | 220,33.5,4,85.0,70.0,1945,16.8 221 | 221,17.5,8,305.0,145.0,3880,12.5 222 | 222,17.0,8,260.0,110.0,4060,19.0 223 | 223,15.5,8,318.0,145.0,4140,13.7 224 | 224,15.0,8,302.0,130.0,4295,14.9 225 | 225,17.5,6,250.0,110.0,3520,16.4 226 | 226,20.5,6,231.0,105.0,3425,16.9 227 | 227,19.0,6,225.0,100.0,3630,17.7 228 | 228,18.5,6,250.0,98.0,3525,19.0 229 | 229,16.0,8,400.0,180.0,4220,11.1 230 | 230,15.5,8,350.0,170.0,4165,11.4 231 | 231,15.5,8,400.0,190.0,4325,12.2 232 | 232,16.0,8,351.0,149.0,4335,14.5 233 | 233,29.0,4,97.0,78.0,1940,14.5 234 | 234,24.5,4,151.0,88.0,2740,16.0 235 | 235,26.0,4,97.0,75.0,2265,18.2 236 | 236,25.5,4,140.0,89.0,2755,15.8 237 | 237,30.5,4,98.0,63.0,2051,17.0 238 | 238,33.5,4,98.0,83.0,2075,15.9 239 | 239,30.0,4,97.0,67.0,1985,16.4 240 | 240,30.5,4,97.0,78.0,2190,14.1 241 | 241,22.0,6,146.0,97.0,2815,14.5 242 | 242,21.5,4,121.0,110.0,2600,12.8 243 | 243,21.5,3,80.0,110.0,2720,13.5 244 | 244,43.1,4,90.0,48.0,1985,21.5 245 | 245,36.1,4,98.0,66.0,1800,14.4 246 | 246,32.8,4,78.0,52.0,1985,19.4 247 | 247,39.4,4,85.0,70.0,2070,18.6 248 | 248,36.1,4,91.0,60.0,1800,16.4 249 | 249,19.9,8,260.0,110.0,3365,15.5 250 | 250,19.4,8,318.0,140.0,3735,13.2 251 | 251,20.2,8,302.0,139.0,3570,12.8 252 | 252,19.2,6,231.0,105.0,3535,19.2 253 | 253,20.5,6,200.0,95.0,3155,18.2 254 | 254,20.2,6,200.0,85.0,2965,15.8 255 | 255,25.1,4,140.0,88.0,2720,15.4 256 | 256,20.5,6,225.0,100.0,3430,17.2 257 | 257,19.4,6,232.0,90.0,3210,17.2 258 | 258,20.6,6,231.0,105.0,3380,15.8 259 | 259,20.8,6,200.0,85.0,3070,16.7 260 | 260,18.6,6,225.0,110.0,3620,18.7 261 | 261,18.1,6,258.0,120.0,3410,15.1 262 | 262,19.2,8,305.0,145.0,3425,13.2 263 | 263,17.7,6,231.0,165.0,3445,13.4 264 | 264,18.1,8,302.0,139.0,3205,11.2 265 | 265,17.5,8,318.0,140.0,4080,13.7 266 | 266,30.0,4,98.0,68.0,2155,16.5 267 | 267,27.5,4,134.0,95.0,2560,14.2 268 | 268,27.2,4,119.0,97.0,2300,14.7 269 | 269,30.9,4,105.0,75.0,2230,14.5 270 | 270,21.1,4,134.0,95.0,2515,14.8 271 | 271,23.2,4,156.0,105.0,2745,16.7 272 | 272,23.8,4,151.0,85.0,2855,17.6 273 | 273,23.9,4,119.0,97.0,2405,14.9 274 | 274,20.3,5,131.0,103.0,2830,15.9 275 | 275,17.0,6,163.0,125.0,3140,13.6 276 | 276,21.6,4,121.0,115.0,2795,15.7 277 | 277,16.2,6,163.0,133.0,3410,15.8 278 | 278,31.5,4,89.0,71.0,1990,14.9 279 | 279,29.5,4,98.0,68.0,2135,16.6 280 | 280,21.5,6,231.0,115.0,3245,15.4 281 | 281,19.8,6,200.0,85.0,2990,18.2 282 | 282,22.3,4,140.0,88.0,2890,17.3 283 | 283,20.2,6,232.0,90.0,3265,18.2 284 | 284,20.6,6,225.0,110.0,3360,16.6 285 | 285,17.0,8,305.0,130.0,3840,15.4 286 | 286,17.6,8,302.0,129.0,3725,13.4 287 | 287,16.5,8,351.0,138.0,3955,13.2 288 | 288,18.2,8,318.0,135.0,3830,15.2 289 | 289,16.9,8,350.0,155.0,4360,14.9 290 | 290,15.5,8,351.0,142.0,4054,14.3 291 | 291,19.2,8,267.0,125.0,3605,15.0 292 | 292,18.5,8,360.0,150.0,3940,13.0 293 | 293,31.9,4,89.0,71.0,1925,14.0 294 | 294,34.1,4,86.0,65.0,1975,15.2 295 | 295,35.7,4,98.0,80.0,1915,14.4 296 | 296,27.4,4,121.0,80.0,2670,15.0 297 | 297,25.4,5,183.0,77.0,3530,20.1 298 | 298,23.0,8,350.0,125.0,3900,17.4 299 | 299,27.2,4,141.0,71.0,3190,24.8 300 | 300,23.9,8,260.0,90.0,3420,22.2 301 | 301,34.2,4,105.0,70.0,2200,13.2 302 | 302,34.5,4,105.0,70.0,2150,14.9 303 | 303,31.8,4,85.0,65.0,2020,19.2 304 | 304,37.3,4,91.0,69.0,2130,14.7 305 | 305,28.4,4,151.0,90.0,2670,16.0 306 | 306,28.8,6,173.0,115.0,2595,11.3 307 | 307,26.8,6,173.0,115.0,2700,12.9 308 | 308,33.5,4,151.0,90.0,2556,13.2 309 | 309,41.5,4,98.0,76.0,2144,14.7 310 | 310,38.1,4,89.0,60.0,1968,18.8 311 | 311,32.1,4,98.0,70.0,2120,15.5 312 | 312,37.2,4,86.0,65.0,2019,16.4 313 | 313,28.0,4,151.0,90.0,2678,16.5 314 | 314,26.4,4,140.0,88.0,2870,18.1 315 | 315,24.3,4,151.0,90.0,3003,20.1 316 | 316,19.1,6,225.0,90.0,3381,18.7 317 | 317,34.3,4,97.0,78.0,2188,15.8 318 | 318,29.8,4,134.0,90.0,2711,15.5 319 | 319,31.3,4,120.0,75.0,2542,17.5 320 | 320,37.0,4,119.0,92.0,2434,15.0 321 | 321,32.2,4,108.0,75.0,2265,15.2 322 | 322,46.6,4,86.0,65.0,2110,17.9 323 | 323,27.9,4,156.0,105.0,2800,14.4 324 | 324,40.8,4,85.0,65.0,2110,19.2 325 | 325,44.3,4,90.0,48.0,2085,21.7 326 | 326,43.4,4,90.0,48.0,2335,23.7 327 | 327,36.4,5,121.0,67.0,2950,19.9 328 | 328,30.0,4,146.0,67.0,3250,21.8 329 | 329,44.6,4,91.0,67.0,1850,13.8 330 | 331,33.8,4,97.0,67.0,2145,18.0 331 | 332,29.8,4,89.0,62.0,1845,15.3 332 | 333,32.7,6,168.0,132.0,2910,11.4 333 | 334,23.7,3,70.0,100.0,2420,12.5 334 | 335,35.0,4,122.0,88.0,2500,15.1 335 | 337,32.4,4,107.0,72.0,2290,17.0 336 | 338,27.2,4,135.0,84.0,2490,15.7 337 | 339,26.6,4,151.0,84.0,2635,16.4 338 | 340,25.8,4,156.0,92.0,2620,14.4 339 | 341,23.5,6,173.0,110.0,2725,12.6 340 | 342,30.0,4,135.0,84.0,2385,12.9 341 | 343,39.1,4,79.0,58.0,1755,16.9 342 | 344,39.0,4,86.0,64.0,1875,16.4 343 | 345,35.1,4,81.0,60.0,1760,16.1 344 | 346,32.3,4,97.0,67.0,2065,17.8 345 | 347,37.0,4,85.0,65.0,1975,19.4 346 | 348,37.7,4,89.0,62.0,2050,17.3 347 | 349,34.1,4,91.0,68.0,1985,16.0 348 | 350,34.7,4,105.0,63.0,2215,14.9 349 | 351,34.4,4,98.0,65.0,2045,16.2 350 | 352,29.9,4,98.0,65.0,2380,20.7 351 | 353,33.0,4,105.0,74.0,2190,14.2 352 | 355,33.7,4,107.0,75.0,2210,14.4 353 | 356,32.4,4,108.0,75.0,2350,16.8 354 | 357,32.9,4,119.0,100.0,2615,14.8 355 | 358,31.6,4,120.0,74.0,2635,18.3 356 | 359,28.1,4,141.0,80.0,3230,20.4 357 | 360,30.7,6,145.0,76.0,3160,19.6 358 | 361,25.4,6,168.0,116.0,2900,12.6 359 | 362,24.2,6,146.0,120.0,2930,13.8 360 | 363,22.4,6,231.0,110.0,3415,15.8 361 | 364,26.6,8,350.0,105.0,3725,19.0 362 | 365,20.2,6,200.0,88.0,3060,17.1 363 | 366,17.6,6,225.0,85.0,3465,16.6 364 | 367,28.0,4,112.0,88.0,2605,19.6 365 | 368,27.0,4,112.0,88.0,2640,18.6 366 | 369,34.0,4,112.0,88.0,2395,18.0 367 | 370,31.0,4,112.0,85.0,2575,16.2 368 | 371,29.0,4,135.0,84.0,2525,16.0 369 | 372,27.0,4,151.0,90.0,2735,18.0 370 | 373,24.0,4,140.0,92.0,2865,16.4 371 | 375,36.0,4,105.0,74.0,1980,15.3 372 | 376,37.0,4,91.0,68.0,2025,18.2 373 | 377,31.0,4,91.0,68.0,1970,17.6 374 | 378,38.0,4,105.0,63.0,2125,14.7 375 | 379,36.0,4,98.0,70.0,2125,17.3 376 | 380,36.0,4,120.0,88.0,2160,14.5 377 | 381,36.0,4,107.0,75.0,2205,14.5 378 | 382,34.0,4,108.0,70.0,2245,16.9 379 | 383,38.0,4,91.0,67.0,1965,15.0 380 | 384,32.0,4,91.0,67.0,1965,15.7 381 | 385,38.0,4,91.0,67.0,1995,16.2 382 | 386,25.0,6,181.0,110.0,2945,16.4 383 | 387,38.0,6,262.0,85.0,3015,17.0 384 | 388,26.0,4,156.0,92.0,2585,14.5 385 | 389,22.0,6,232.0,112.0,2835,14.7 386 | 390,32.0,4,144.0,96.0,2665,13.9 387 | 391,36.0,4,135.0,84.0,2370,13.0 388 | 392,27.0,4,151.0,90.0,2950,17.3 389 | 393,27.0,4,140.0,86.0,2790,15.6 390 | 394,44.0,4,97.0,52.0,2130,24.6 391 | 395,32.0,4,135.0,84.0,2295,11.6 392 | 396,28.0,4,120.0,79.0,2625,18.6 393 | 397,31.0,4,119.0,82.0,2720,19.4 394 | -------------------------------------------------------------------------------- /Chapter 06 - Computational Algorithms in Linear Algebra/Chapter6.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Chapter 6 - Computational Algorithms in Linear Algebra\n", 8 | "\n", 9 | "This notebook contains code accompanying Chapter 6 Computational Algorithms in Linear Algebra in *Practical Discrete Mathematics* by Ryan T. White and Archana Tikayat Ray.\n", 10 | "\n", 11 | "## Matrices and Matrix Representations of Linear Systems\n", 12 | "\n", 13 | "The code below stores matrices as `NumPy` arrays and prints specified entries of the matrices." 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 2, 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "name": "stdout", 23 | "output_type": "stream", 24 | "text": [ 25 | "3\n", 26 | "1\n" 27 | ] 28 | } 29 | ], 30 | "source": [ 31 | "import numpy \n", 32 | "\n", 33 | "# initialize matrices \n", 34 | "A = numpy.array([[3, 2, 1], [9, 0, 1], [3, 4, 1]]) \n", 35 | "B = numpy.array([[1, 1, 2], [8, 4, 1], [0, 0, 3]])\n", 36 | "\n", 37 | "# print the entry in the first row and first column of A\n", 38 | "print(A[0,0])\n", 39 | "\n", 40 | "# print the entry in the second row and third column of B\n", 41 | "print(B[1,2])" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": {}, 47 | "source": [ 48 | "### Example: Matrix Addition and Subtraction" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 3, 54 | "metadata": {}, 55 | "outputs": [ 56 | { 57 | "name": "stdout", 58 | "output_type": "stream", 59 | "text": [ 60 | "[[ 4 3 3]\n", 61 | " [17 4 2]\n", 62 | " [ 3 4 4]]\n", 63 | "[[ 2 1 -1]\n", 64 | " [ 1 -4 0]\n", 65 | " [ 3 4 -2]]\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "# Add A and B\n", 71 | "print(numpy.add(A,B))\n", 72 | "\n", 73 | "# Subtract A and B\n", 74 | "print(numpy.subtract(A,B))" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "metadata": {}, 80 | "source": [ 81 | "### Example: Scalar Multiplication and Transpose" 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": 8, 87 | "metadata": {}, 88 | "outputs": [ 89 | { 90 | "name": "stdout", 91 | "output_type": "stream", 92 | "text": [ 93 | "[[15 10 5]\n", 94 | " [45 0 5]\n", 95 | " [15 20 5]]\n", 96 | "[[3 9 3]\n", 97 | " [2 0 4]\n", 98 | " [1 1 1]]\n" 99 | ] 100 | } 101 | ], 102 | "source": [ 103 | "# Multiply A by a scalar 5\n", 104 | "print(numpy.multiply(5,A))\n", 105 | "\n", 106 | "# Find the transpose of A\n", 107 | "print(numpy.transpose(A))" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "### Example: Matrix Multiplication and Transpose" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": 9, 120 | "metadata": {}, 121 | "outputs": [ 122 | { 123 | "name": "stdout", 124 | "output_type": "stream", 125 | "text": [ 126 | "[[19 11 11]\n", 127 | " [ 9 9 21]\n", 128 | " [35 19 13]]\n" 129 | ] 130 | } 131 | ], 132 | "source": [ 133 | "# Multiply A and B\n", 134 | "print(numpy.dot(A,B))" 135 | ] 136 | }, 137 | { 138 | "cell_type": "markdown", 139 | "metadata": {}, 140 | "source": [ 141 | "## Solving Large Linear Systems with `NumPy`\n", 142 | "\n", 143 | "### Example: Solving $\\mathbf{Ax}=\\mathbf{b}$ for $\\mathbf{x}$" 144 | ] 145 | }, 146 | { 147 | "cell_type": "code", 148 | "execution_count": 10, 149 | "metadata": {}, 150 | "outputs": [ 151 | { 152 | "data": { 153 | "text/plain": [ 154 | "array([ 5., 1., -2.])" 155 | ] 156 | }, 157 | "execution_count": 10, 158 | "metadata": {}, 159 | "output_type": "execute_result" 160 | } 161 | ], 162 | "source": [ 163 | "import numpy\n", 164 | "\n", 165 | "# Create A and b matrices\n", 166 | "A = numpy.array([[2, -6, 6], [2, 3, -1], [4, -3, -1]])\n", 167 | "b = numpy.array([-8, 15, 19])\n", 168 | "\n", 169 | "# Solve Ax = b\n", 170 | "numpy.linalg.solve(A,b)\n" 171 | ] 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "metadata": {}, 176 | "source": [ 177 | "### Example: Inconsistent and Dependent Systems with `NumPy`" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 14, 183 | "metadata": {}, 184 | "outputs": [ 185 | { 186 | "ename": "LinAlgError", 187 | "evalue": "Singular matrix", 188 | "output_type": "error", 189 | "traceback": [ 190 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 191 | "\u001b[1;31mLinAlgError\u001b[0m Traceback (most recent call last)", 192 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mb\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnumpy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marray\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 7\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnumpy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlinalg\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msolve\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mA\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mb\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 193 | "\u001b[1;32m<__array_function__ internals>\u001b[0m in \u001b[0;36msolve\u001b[1;34m(*args, **kwargs)\u001b[0m\n", 194 | "\u001b[1;32m~\\anaconda3\\envs\\DL\\lib\\site-packages\\numpy\\linalg\\linalg.py\u001b[0m in \u001b[0;36msolve\u001b[1;34m(a, b)\u001b[0m\n\u001b[0;32m 392\u001b[0m \u001b[0msignature\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m'DD->D'\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0misComplexType\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mt\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32melse\u001b[0m \u001b[1;34m'dd->d'\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 393\u001b[0m \u001b[0mextobj\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mget_linalg_error_extobj\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0m_raise_linalgerror_singular\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 394\u001b[1;33m \u001b[0mr\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgufunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mb\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msignature\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0msignature\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mextobj\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mextobj\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 395\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 396\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mwrap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mr\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mastype\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mresult_t\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 195 | "\u001b[1;32m~\\anaconda3\\envs\\DL\\lib\\site-packages\\numpy\\linalg\\linalg.py\u001b[0m in \u001b[0;36m_raise_linalgerror_singular\u001b[1;34m(err, flag)\u001b[0m\n\u001b[0;32m 86\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 87\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_raise_linalgerror_singular\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0merr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mflag\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 88\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mLinAlgError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Singular matrix\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 89\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 90\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_raise_linalgerror_nonposdef\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0merr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mflag\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 196 | "\u001b[1;31mLinAlgError\u001b[0m: Singular matrix" 197 | ] 198 | } 199 | ], 200 | "source": [ 201 | "import numpy\n", 202 | "\n", 203 | "# inconsistent system\n", 204 | "A = numpy.array([[2, 1], [6, 3]])\n", 205 | "b = numpy.array([3, 3])\n", 206 | "\n", 207 | "print(numpy.linalg.solve(A,b))" 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "metadata": {}, 213 | "source": [ 214 | "Note that the code throws an error because the matrix $\\mathbf{A}$ is singular since the system is inconsistent--i.e. there are no solutions." 215 | ] 216 | }, 217 | { 218 | "cell_type": "code", 219 | "execution_count": 19, 220 | "metadata": {}, 221 | "outputs": [ 222 | { 223 | "ename": "LinAlgError", 224 | "evalue": "Singular matrix", 225 | "output_type": "error", 226 | "traceback": [ 227 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 228 | "\u001b[1;31mLinAlgError\u001b[0m Traceback (most recent call last)", 229 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mb\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnumpy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marray\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnumpy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlinalg\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msolve\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mA\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mb\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 230 | "\u001b[1;32m<__array_function__ internals>\u001b[0m in \u001b[0;36msolve\u001b[1;34m(*args, **kwargs)\u001b[0m\n", 231 | "\u001b[1;32m~\\anaconda3\\envs\\DL\\lib\\site-packages\\numpy\\linalg\\linalg.py\u001b[0m in \u001b[0;36msolve\u001b[1;34m(a, b)\u001b[0m\n\u001b[0;32m 392\u001b[0m \u001b[0msignature\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m'DD->D'\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0misComplexType\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mt\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32melse\u001b[0m \u001b[1;34m'dd->d'\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 393\u001b[0m \u001b[0mextobj\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mget_linalg_error_extobj\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0m_raise_linalgerror_singular\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 394\u001b[1;33m \u001b[0mr\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgufunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mb\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msignature\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0msignature\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mextobj\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mextobj\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 395\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 396\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mwrap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mr\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mastype\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mresult_t\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 232 | "\u001b[1;32m~\\anaconda3\\envs\\DL\\lib\\site-packages\\numpy\\linalg\\linalg.py\u001b[0m in \u001b[0;36m_raise_linalgerror_singular\u001b[1;34m(err, flag)\u001b[0m\n\u001b[0;32m 86\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 87\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_raise_linalgerror_singular\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0merr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mflag\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 88\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mLinAlgError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Singular matrix\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 89\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 90\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_raise_linalgerror_nonposdef\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0merr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mflag\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 233 | "\u001b[1;31mLinAlgError\u001b[0m: Singular matrix" 234 | ] 235 | } 236 | ], 237 | "source": [ 238 | "# dependent system\n", 239 | "A = numpy.array([[2, 1], [6, 3]])\n", 240 | "b = numpy.array([1, 3])\n", 241 | "\n", 242 | "print(numpy.linalg.solve(A,b))" 243 | ] 244 | }, 245 | { 246 | "cell_type": "markdown", 247 | "metadata": {}, 248 | "source": [ 249 | "Note that the code throws an error because the matrix $\\mathbf{A}$ is singular since the system is dependent--i.e. there are infinitely many solutions, as we can confirm below." 250 | ] 251 | }, 252 | { 253 | "cell_type": "code", 254 | "execution_count": 20, 255 | "metadata": {}, 256 | "outputs": [ 257 | { 258 | "name": "stdout", 259 | "output_type": "stream", 260 | "text": [ 261 | "0.0\n" 262 | ] 263 | } 264 | ], 265 | "source": [ 266 | "A = numpy.array([[2, 1], [6, 3]])\n", 267 | "print(numpy.linalg.det(A))" 268 | ] 269 | }, 270 | { 271 | "cell_type": "markdown", 272 | "metadata": {}, 273 | "source": [ 274 | "### Example: 10-by-10 Linear System (with `NumPy`)" 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": 21, 280 | "metadata": {}, 281 | "outputs": [ 282 | { 283 | "name": "stdout", 284 | "output_type": "stream", 285 | "text": [ 286 | "[ 0.09118027 -1.51451319 -2.48186344 -2.94076307 0.07912968 2.76425416\n", 287 | " 2.48851394 -0.30974375 -1.97943716 0.75619575]\n" 288 | ] 289 | }, 290 | { 291 | "data": { 292 | "text/plain": [ 293 | "2.1538326677728037e-14" 294 | ] 295 | }, 296 | "execution_count": 21, 297 | "metadata": {}, 298 | "output_type": "execute_result" 299 | } 300 | ], 301 | "source": [ 302 | "import numpy\n", 303 | "\n", 304 | "numpy.random.seed(1)\n", 305 | "\n", 306 | "# Create A and b matrices with random\n", 307 | "A = 10*numpy.random.rand(10,10)-5\n", 308 | "b = 10*numpy.random.rand(10)-5\n", 309 | "\n", 310 | "# Solve Ax = b\n", 311 | "solution = numpy.linalg.solve(A,b)\n", 312 | "print(solution)\n", 313 | "\n", 314 | "# To verify the solution works, show Ax - b is near 0\n", 315 | "sum(abs(numpy.dot(A,solution) - b))" 316 | ] 317 | } 318 | ], 319 | "metadata": { 320 | "kernelspec": { 321 | "display_name": "Python 3.7 (DL)", 322 | "language": "python", 323 | "name": "dl" 324 | }, 325 | "language_info": { 326 | "codemirror_mode": { 327 | "name": "ipython", 328 | "version": 3 329 | }, 330 | "file_extension": ".py", 331 | "mimetype": "text/x-python", 332 | "name": "python", 333 | "nbconvert_exporter": "python", 334 | "pygments_lexer": "ipython3", 335 | "version": "3.7.7" 336 | } 337 | }, 338 | "nbformat": 4, 339 | "nbformat_minor": 4 340 | } 341 | -------------------------------------------------------------------------------- /Chapter 06 - Computational Algorithms in Linear Algebra/.ipynb_checkpoints/Chapter6-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Chapter 6 - Computational Algorithms in Linear Algebra\n", 8 | "\n", 9 | "This notebook contains code accompanying Chapter 6 Computational Algorithms in Linear Algebra in *Practical Discrete Mathematics* by Ryan T. White and Archana Tikayat Ray.\n", 10 | "\n", 11 | "## Matrices and Matrix Representations of Linear Systems\n", 12 | "\n", 13 | "The code below stores matrices as `NumPy` arrays and prints specified entries of the matrices." 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 2, 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "name": "stdout", 23 | "output_type": "stream", 24 | "text": [ 25 | "3\n", 26 | "1\n" 27 | ] 28 | } 29 | ], 30 | "source": [ 31 | "import numpy \n", 32 | "\n", 33 | "# initialize matrices \n", 34 | "A = numpy.array([[3, 2, 1], [9, 0, 1], [3, 4, 1]]) \n", 35 | "B = numpy.array([[1, 1, 2], [8, 4, 1], [0, 0, 3]])\n", 36 | "\n", 37 | "# print the entry in the first row and first column of A\n", 38 | "print(A[0,0])\n", 39 | "\n", 40 | "# print the entry in the second row and third column of B\n", 41 | "print(B[1,2])" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": {}, 47 | "source": [ 48 | "### Example: Matrix Addition and Subtraction" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 3, 54 | "metadata": {}, 55 | "outputs": [ 56 | { 57 | "name": "stdout", 58 | "output_type": "stream", 59 | "text": [ 60 | "[[ 4 3 3]\n", 61 | " [17 4 2]\n", 62 | " [ 3 4 4]]\n", 63 | "[[ 2 1 -1]\n", 64 | " [ 1 -4 0]\n", 65 | " [ 3 4 -2]]\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "# Add A and B\n", 71 | "print(numpy.add(A,B))\n", 72 | "\n", 73 | "# Subtract A and B\n", 74 | "print(numpy.subtract(A,B))" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "metadata": {}, 80 | "source": [ 81 | "### Example: Scalar Multiplication and Transpose" 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": 8, 87 | "metadata": {}, 88 | "outputs": [ 89 | { 90 | "name": "stdout", 91 | "output_type": "stream", 92 | "text": [ 93 | "[[15 10 5]\n", 94 | " [45 0 5]\n", 95 | " [15 20 5]]\n", 96 | "[[3 9 3]\n", 97 | " [2 0 4]\n", 98 | " [1 1 1]]\n" 99 | ] 100 | } 101 | ], 102 | "source": [ 103 | "# Multiply A by a scalar 5\n", 104 | "print(numpy.multiply(5,A))\n", 105 | "\n", 106 | "# Find the transpose of A\n", 107 | "print(numpy.transpose(A))" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "### Example: Matrix Multiplication and Transpose" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": 9, 120 | "metadata": {}, 121 | "outputs": [ 122 | { 123 | "name": "stdout", 124 | "output_type": "stream", 125 | "text": [ 126 | "[[19 11 11]\n", 127 | " [ 9 9 21]\n", 128 | " [35 19 13]]\n" 129 | ] 130 | } 131 | ], 132 | "source": [ 133 | "# Multiply A and B\n", 134 | "print(numpy.dot(A,B))" 135 | ] 136 | }, 137 | { 138 | "cell_type": "markdown", 139 | "metadata": {}, 140 | "source": [ 141 | "## Solving Large Linear Systems with `NumPy`\n", 142 | "\n", 143 | "### Example: Solving $\\mathbf{Ax}=\\mathbf{b}$ for $\\mathbf{x}$" 144 | ] 145 | }, 146 | { 147 | "cell_type": "code", 148 | "execution_count": 10, 149 | "metadata": {}, 150 | "outputs": [ 151 | { 152 | "data": { 153 | "text/plain": [ 154 | "array([ 5., 1., -2.])" 155 | ] 156 | }, 157 | "execution_count": 10, 158 | "metadata": {}, 159 | "output_type": "execute_result" 160 | } 161 | ], 162 | "source": [ 163 | "import numpy\n", 164 | "\n", 165 | "# Create A and b matrices\n", 166 | "A = numpy.array([[2, -6, 6], [2, 3, -1], [4, -3, -1]])\n", 167 | "b = numpy.array([-8, 15, 19])\n", 168 | "\n", 169 | "# Solve Ax = b\n", 170 | "numpy.linalg.solve(A,b)\n" 171 | ] 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "metadata": {}, 176 | "source": [ 177 | "### Example: Inconsistent and Dependent Systems with `NumPy`" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 14, 183 | "metadata": {}, 184 | "outputs": [ 185 | { 186 | "ename": "LinAlgError", 187 | "evalue": "Singular matrix", 188 | "output_type": "error", 189 | "traceback": [ 190 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 191 | "\u001b[1;31mLinAlgError\u001b[0m Traceback (most recent call last)", 192 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mb\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnumpy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marray\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 7\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnumpy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlinalg\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msolve\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mA\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mb\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 193 | "\u001b[1;32m<__array_function__ internals>\u001b[0m in \u001b[0;36msolve\u001b[1;34m(*args, **kwargs)\u001b[0m\n", 194 | "\u001b[1;32m~\\anaconda3\\envs\\DL\\lib\\site-packages\\numpy\\linalg\\linalg.py\u001b[0m in \u001b[0;36msolve\u001b[1;34m(a, b)\u001b[0m\n\u001b[0;32m 392\u001b[0m \u001b[0msignature\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m'DD->D'\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0misComplexType\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mt\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32melse\u001b[0m \u001b[1;34m'dd->d'\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 393\u001b[0m \u001b[0mextobj\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mget_linalg_error_extobj\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0m_raise_linalgerror_singular\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 394\u001b[1;33m \u001b[0mr\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgufunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mb\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msignature\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0msignature\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mextobj\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mextobj\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 395\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 396\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mwrap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mr\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mastype\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mresult_t\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 195 | "\u001b[1;32m~\\anaconda3\\envs\\DL\\lib\\site-packages\\numpy\\linalg\\linalg.py\u001b[0m in \u001b[0;36m_raise_linalgerror_singular\u001b[1;34m(err, flag)\u001b[0m\n\u001b[0;32m 86\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 87\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_raise_linalgerror_singular\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0merr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mflag\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 88\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mLinAlgError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Singular matrix\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 89\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 90\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_raise_linalgerror_nonposdef\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0merr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mflag\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 196 | "\u001b[1;31mLinAlgError\u001b[0m: Singular matrix" 197 | ] 198 | } 199 | ], 200 | "source": [ 201 | "import numpy\n", 202 | "\n", 203 | "# inconsistent system\n", 204 | "A = numpy.array([[2, 1], [6, 3]])\n", 205 | "b = numpy.array([3, 3])\n", 206 | "\n", 207 | "print(numpy.linalg.solve(A,b))" 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "metadata": {}, 213 | "source": [ 214 | "Note that the code throws an error because the matrix $\\mathbf{A}$ is singular since the system is inconsistent--i.e. there are no solutions." 215 | ] 216 | }, 217 | { 218 | "cell_type": "code", 219 | "execution_count": 19, 220 | "metadata": {}, 221 | "outputs": [ 222 | { 223 | "ename": "LinAlgError", 224 | "evalue": "Singular matrix", 225 | "output_type": "error", 226 | "traceback": [ 227 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 228 | "\u001b[1;31mLinAlgError\u001b[0m Traceback (most recent call last)", 229 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mb\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnumpy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marray\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnumpy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlinalg\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msolve\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mA\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mb\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 230 | "\u001b[1;32m<__array_function__ internals>\u001b[0m in \u001b[0;36msolve\u001b[1;34m(*args, **kwargs)\u001b[0m\n", 231 | "\u001b[1;32m~\\anaconda3\\envs\\DL\\lib\\site-packages\\numpy\\linalg\\linalg.py\u001b[0m in \u001b[0;36msolve\u001b[1;34m(a, b)\u001b[0m\n\u001b[0;32m 392\u001b[0m \u001b[0msignature\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m'DD->D'\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0misComplexType\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mt\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32melse\u001b[0m \u001b[1;34m'dd->d'\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 393\u001b[0m \u001b[0mextobj\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mget_linalg_error_extobj\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0m_raise_linalgerror_singular\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 394\u001b[1;33m \u001b[0mr\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgufunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mb\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msignature\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0msignature\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mextobj\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mextobj\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 395\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 396\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mwrap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mr\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mastype\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mresult_t\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 232 | "\u001b[1;32m~\\anaconda3\\envs\\DL\\lib\\site-packages\\numpy\\linalg\\linalg.py\u001b[0m in \u001b[0;36m_raise_linalgerror_singular\u001b[1;34m(err, flag)\u001b[0m\n\u001b[0;32m 86\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 87\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_raise_linalgerror_singular\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0merr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mflag\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 88\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mLinAlgError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Singular matrix\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 89\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 90\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_raise_linalgerror_nonposdef\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0merr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mflag\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 233 | "\u001b[1;31mLinAlgError\u001b[0m: Singular matrix" 234 | ] 235 | } 236 | ], 237 | "source": [ 238 | "# dependent system\n", 239 | "A = numpy.array([[2, 1], [6, 3]])\n", 240 | "b = numpy.array([1, 3])\n", 241 | "\n", 242 | "print(numpy.linalg.solve(A,b))" 243 | ] 244 | }, 245 | { 246 | "cell_type": "markdown", 247 | "metadata": {}, 248 | "source": [ 249 | "Note that the code throws an error because the matrix $\\mathbf{A}$ is singular since the system is dependent--i.e. there are infinitely many solutions, as we can confirm below." 250 | ] 251 | }, 252 | { 253 | "cell_type": "code", 254 | "execution_count": 20, 255 | "metadata": {}, 256 | "outputs": [ 257 | { 258 | "name": "stdout", 259 | "output_type": "stream", 260 | "text": [ 261 | "0.0\n" 262 | ] 263 | } 264 | ], 265 | "source": [ 266 | "A = numpy.array([[2, 1], [6, 3]])\n", 267 | "print(numpy.linalg.det(A))" 268 | ] 269 | }, 270 | { 271 | "cell_type": "markdown", 272 | "metadata": {}, 273 | "source": [ 274 | "### Example: 10-by-10 Linear System (with `NumPy`)" 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": 21, 280 | "metadata": {}, 281 | "outputs": [ 282 | { 283 | "name": "stdout", 284 | "output_type": "stream", 285 | "text": [ 286 | "[ 0.09118027 -1.51451319 -2.48186344 -2.94076307 0.07912968 2.76425416\n", 287 | " 2.48851394 -0.30974375 -1.97943716 0.75619575]\n" 288 | ] 289 | }, 290 | { 291 | "data": { 292 | "text/plain": [ 293 | "2.1538326677728037e-14" 294 | ] 295 | }, 296 | "execution_count": 21, 297 | "metadata": {}, 298 | "output_type": "execute_result" 299 | } 300 | ], 301 | "source": [ 302 | "import numpy\n", 303 | "\n", 304 | "numpy.random.seed(1)\n", 305 | "\n", 306 | "# Create A and b matrices with random\n", 307 | "A = 10*numpy.random.rand(10,10)-5\n", 308 | "b = 10*numpy.random.rand(10)-5\n", 309 | "\n", 310 | "# Solve Ax = b\n", 311 | "solution = numpy.linalg.solve(A,b)\n", 312 | "print(solution)\n", 313 | "\n", 314 | "# To verify the solution works, show Ax - b is near 0\n", 315 | "sum(abs(numpy.dot(A,solution) - b))" 316 | ] 317 | } 318 | ], 319 | "metadata": { 320 | "kernelspec": { 321 | "display_name": "Python 3.7 (DL)", 322 | "language": "python", 323 | "name": "dl" 324 | }, 325 | "language_info": { 326 | "codemirror_mode": { 327 | "name": "ipython", 328 | "version": 3 329 | }, 330 | "file_extension": ".py", 331 | "mimetype": "text/x-python", 332 | "name": "python", 333 | "nbconvert_exporter": "python", 334 | "pygments_lexer": "ipython3", 335 | "version": "3.7.7" 336 | } 337 | }, 338 | "nbformat": 4, 339 | "nbformat_minor": 4 340 | } 341 | -------------------------------------------------------------------------------- /Chapter 07 - Computational Requirements for Algorithms/Chapter7.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Chapter 7 - Computational Requirements for Algorithms\n", 8 | "\n", 9 | "This notebook contains code accompanying Chapter 7 Computational Requirements for Algorithms in *Practical Discrete Mathematics* by Ryan T. White and Archana Tikayat Ray.\n", 10 | "\n", 11 | "## Computational complexity of algorithms \n", 12 | "\n", 13 | "### Example: A simple algorithm" 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 2, 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "name": "stdin", 23 | "output_type": "stream", 24 | "text": [ 25 | "Please enter a fruit name: Apple\n" 26 | ] 27 | }, 28 | { 29 | "name": "stdout", 30 | "output_type": "stream", 31 | "text": [ 32 | "The updated list is: ['Jackfruit', 'Honeydew', 'Grapes', 'Apple']\n" 33 | ] 34 | }, 35 | { 36 | "name": "stdin", 37 | "output_type": "stream", 38 | "text": [ 39 | "Please enter the name of the fruit you want to delete: Apple\n" 40 | ] 41 | }, 42 | { 43 | "name": "stdout", 44 | "output_type": "stream", 45 | "text": [ 46 | "The updated list is: ['Jackfruit', 'Honeydew', 'Grapes']\n" 47 | ] 48 | } 49 | ], 50 | "source": [ 51 | "#Type of algorithm - inserting new element to pre-existing list\n", 52 | "fruit_name = [\"Jackfruit\", \"Honeydew\", \"Grapes\"]\n", 53 | "user_input1 = input(\"Please enter a fruit name: \")\n", 54 | "fruit_name.append(user_input1)\n", 55 | "print('The updated list is: ' + str(fruit_name))\n", 56 | "\n", 57 | "#Type of algorithm - deleting element from list\n", 58 | "user_input2 = input(\"Please enter the name of the fruit you want to delete: \")\n", 59 | "fruit_name.remove(user_input2)\n", 60 | "print('The updated list is: ' + str(fruit_name))" 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "### Example: Execution Time" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 6, 73 | "metadata": {}, 74 | "outputs": [ 75 | { 76 | "name": "stdin", 77 | "output_type": "stream", 78 | "text": [ 79 | "Please input a number of your choice: 1\n" 80 | ] 81 | }, 82 | { 83 | "name": "stdout", 84 | "output_type": "stream", 85 | "text": [ 86 | "Yes No No No No No No No \n", 87 | "The time elapsed for this computation is: 0.3815207999999757seconds\n" 88 | ] 89 | } 90 | ], 91 | "source": [ 92 | "# a is a list containing some numbers\n", 93 | "# We will compare the number input by user with the numbers in this list\n", 94 | "import timeit\n", 95 | "tic=timeit.default_timer()\n", 96 | "\n", 97 | "a=[1,2,3,4,5,6,7,8]\n", 98 | "\n", 99 | "INPUT = input(\"Please input a number of your choice: \")\n", 100 | "number = int(INPUT)\n", 101 | "\n", 102 | "for i in range(len(a)):\n", 103 | " if a[i]== number:\n", 104 | " print(\"Yes\", end=' ')\n", 105 | " else:\n", 106 | " print(\"No\", end=' ')\n", 107 | " \n", 108 | "print()\n", 109 | "\n", 110 | "toc=timeit.default_timer()\n", 111 | "time_elapsed = toc - tic\n", 112 | "\n", 113 | "print(\"The time elapsed for this computation is: \" + str(time_elapsed) + \"seconds\")" 114 | ] 115 | }, 116 | { 117 | "cell_type": "markdown", 118 | "metadata": {}, 119 | "source": [ 120 | "## Understanding Big-O Notation\n", 121 | "\n", 122 | "### Constant complexity O(constant)" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 9, 128 | "metadata": {}, 129 | "outputs": [ 130 | { 131 | "name": "stdout", 132 | "output_type": "stream", 133 | "text": [ 134 | "The end result after running the algorithm is:8\n" 135 | ] 136 | } 137 | ], 138 | "source": [ 139 | "#Constant complexity function\n", 140 | "def constant_complexity(list):\n", 141 | " output = list[1] * list[1] * list[1]\n", 142 | " print(\"The end result after running the algorithm is:\" + str(output))\n", 143 | " \n", 144 | "constant_complexity([1,2,3,4,5,6,7])" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": {}, 150 | "source": [ 151 | "### Linear complexity $O(n)$" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": 10, 157 | "metadata": {}, 158 | "outputs": [ 159 | { 160 | "name": "stdout", 161 | "output_type": "stream", 162 | "text": [ 163 | "Iteration number 1\n", 164 | "Iteration number 2\n", 165 | "Iteration number 3\n", 166 | "Iteration number 4\n", 167 | "Iteration number 5\n", 168 | "Iteration number 6\n", 169 | "Iteration number 7\n" 170 | ] 171 | } 172 | ], 173 | "source": [ 174 | "# Linear complexity\n", 175 | "def linear_complexity(list):\n", 176 | " for i in list:\n", 177 | " print(\"Iteration number \" + str(i))\n", 178 | "\n", 179 | "linear_complexity([1,2,3,4,5,6,7])" 180 | ] 181 | }, 182 | { 183 | "cell_type": "markdown", 184 | "metadata": {}, 185 | "source": [ 186 | "### Quadratic complexity $O(n^2)$" 187 | ] 188 | }, 189 | { 190 | "cell_type": "code", 191 | "execution_count": 11, 192 | "metadata": {}, 193 | "outputs": [ 194 | { 195 | "name": "stdout", 196 | "output_type": "stream", 197 | "text": [ 198 | "1\t|First for loop iteration: 1 \t| Second for loop iteration:1\n", 199 | "2\t|First for loop iteration: 1 \t| Second for loop iteration:2\n", 200 | "3\t|First for loop iteration: 1 \t| Second for loop iteration:3\n", 201 | "4\t|First for loop iteration: 1 \t| Second for loop iteration:4\n", 202 | "5\t|First for loop iteration: 2 \t| Second for loop iteration:1\n", 203 | "6\t|First for loop iteration: 2 \t| Second for loop iteration:2\n", 204 | "7\t|First for loop iteration: 2 \t| Second for loop iteration:3\n", 205 | "8\t|First for loop iteration: 2 \t| Second for loop iteration:4\n", 206 | "9\t|First for loop iteration: 3 \t| Second for loop iteration:1\n", 207 | "10\t|First for loop iteration: 3 \t| Second for loop iteration:2\n", 208 | "11\t|First for loop iteration: 3 \t| Second for loop iteration:3\n", 209 | "12\t|First for loop iteration: 3 \t| Second for loop iteration:4\n", 210 | "13\t|First for loop iteration: 4 \t| Second for loop iteration:1\n", 211 | "14\t|First for loop iteration: 4 \t| Second for loop iteration:2\n", 212 | "15\t|First for loop iteration: 4 \t| Second for loop iteration:3\n", 213 | "16\t|First for loop iteration: 4 \t| Second for loop iteration:4\n" 214 | ] 215 | } 216 | ], 217 | "source": [ 218 | "#Quadratic complexity\n", 219 | "def quadratic_complexity(list):\n", 220 | " count = 0\n", 221 | " for i in list:\n", 222 | " for j in list:\n", 223 | " count += 1\n", 224 | " print(str(count) + \"\\t|First for loop iteration: \" + str(i), '\\t|', \"Second for loop iteration:\" + str(j))\n", 225 | " \n", 226 | "quadratic_complexity([1,2,3,4])" 227 | ] 228 | }, 229 | { 230 | "cell_type": "markdown", 231 | "metadata": {}, 232 | "source": [ 233 | "### Complexity of complex functions" 234 | ] 235 | }, 236 | { 237 | "cell_type": "code", 238 | "execution_count": 13, 239 | "metadata": {}, 240 | "outputs": [ 241 | { 242 | "name": "stdout", 243 | "output_type": "stream", 244 | "text": [ 245 | "Step: 1 \t Hello World!\n", 246 | "Step: 2 \t Hello World!\n", 247 | "Step: 3 \t Hello World!\n", 248 | "Step: 4 \t Hello World!\n", 249 | "Step: 5 \t Hello World!\n", 250 | "Step: 6 \t Hello World!\n", 251 | "Step: 7 \t 1\n", 252 | "Step: 8 \t 2\n", 253 | "Step: 9 \t 3\n", 254 | "Step: 10 \t 4\n", 255 | "Step: 11 \t 1\n", 256 | "Step: 12 \t 2\n", 257 | "Step: 13 \t 3\n", 258 | "Step: 14 \t 4\n" 259 | ] 260 | } 261 | ], 262 | "source": [ 263 | "#Complex function complexity\n", 264 | "def complex_func (list):\n", 265 | " count = 0\n", 266 | " for i in range(6):\n", 267 | " count += 1\n", 268 | " print(\"Step: \" + str(count) + \" \\t Hello World!\")\n", 269 | " \n", 270 | " for j in list:\n", 271 | " count += 1\n", 272 | " print(\"Step: \" + str(count) + \" \\t \" + str(j))\n", 273 | " \n", 274 | " for k in list:\n", 275 | " count += 1\n", 276 | " print(\"Step: \" + str(count) + \" \\t \" + str(k))\n", 277 | "\n", 278 | "complex_func([1,2,3,4])" 279 | ] 280 | }, 281 | { 282 | "cell_type": "markdown", 283 | "metadata": {}, 284 | "source": [ 285 | "## Complexity of algorithms with fundamental control structures\n", 286 | "\n", 287 | "### `if`-`elif`-`else`" 288 | ] 289 | }, 290 | { 291 | "cell_type": "code", 292 | "execution_count": 14, 293 | "metadata": {}, 294 | "outputs": [ 295 | { 296 | "name": "stdout", 297 | "output_type": "stream", 298 | "text": [ 299 | "b is less than a\n" 300 | ] 301 | } 302 | ], 303 | "source": [ 304 | "#Complexity of if-elif-else statements\n", 305 | "a = 10\n", 306 | "b = 5\n", 307 | "if b > a:\n", 308 | " print(\"b is greater than a\")\n", 309 | " \n", 310 | "elif b < a:\n", 311 | " print(\"b is less than a\")\n", 312 | " \n", 313 | "else:\n", 314 | " print(\"a and b are equal\")" 315 | ] 316 | }, 317 | { 318 | "cell_type": "markdown", 319 | "metadata": {}, 320 | "source": [ 321 | "### `for` Loops" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 18, 327 | "metadata": {}, 328 | "outputs": [ 329 | { 330 | "name": "stdout", 331 | "output_type": "stream", 332 | "text": [ 333 | "apple\n", 334 | "mango\n", 335 | "orange\n", 336 | "banana\n", 337 | "pomegranate\n" 338 | ] 339 | } 340 | ], 341 | "source": [ 342 | "#For loop\n", 343 | "fruits = [\"apple\", \"mango\", \"orange\", \"banana\", \"pomegranate\"]\n", 344 | "\n", 345 | "for x in fruits:\n", 346 | " print(x)" 347 | ] 348 | }, 349 | { 350 | "cell_type": "markdown", 351 | "metadata": {}, 352 | "source": [ 353 | "### Nested `for` Loops" 354 | ] 355 | }, 356 | { 357 | "cell_type": "code", 358 | "execution_count": 19, 359 | "metadata": {}, 360 | "outputs": [ 361 | { 362 | "name": "stdout", 363 | "output_type": "stream", 364 | "text": [ 365 | "tasty apple\n", 366 | "tasty mango\n", 367 | "tasty orange\n", 368 | "tasty banana\n", 369 | "tasty pomegranate\n", 370 | "juicy apple\n", 371 | "juicy mango\n", 372 | "juicy orange\n", 373 | "juicy banana\n", 374 | "juicy pomegranate\n", 375 | "fresh apple\n", 376 | "fresh mango\n", 377 | "fresh orange\n", 378 | "fresh banana\n", 379 | "fresh pomegranate\n" 380 | ] 381 | } 382 | ], 383 | "source": [ 384 | "#Nested for loop\n", 385 | "fruits = [\"apple\", \"mango\", \"orange\", \"banana\", \"pomegranate\"]\n", 386 | "adjectives = [\"tasty\", \"juicy\", \"fresh\"]\n", 387 | "\n", 388 | "for y in adjectives:\n", 389 | " for x in fruits:\n", 390 | " print(y, x)" 391 | ] 392 | }, 393 | { 394 | "cell_type": "markdown", 395 | "metadata": {}, 396 | "source": [ 397 | "### `while` Loops" 398 | ] 399 | }, 400 | { 401 | "cell_type": "code", 402 | "execution_count": 21, 403 | "metadata": {}, 404 | "outputs": [ 405 | { 406 | "name": "stdout", 407 | "output_type": "stream", 408 | "text": [ 409 | "Step: 1 The condition is satisfied\n", 410 | "Step: 2 The condition is satisfied\n", 411 | "Step: 3 The condition is satisfied\n", 412 | "Step: 4 The condition is satisfied\n", 413 | "Step: 5 The condition is satisfied\n", 414 | "Step: 6 The condition is satisfied\n", 415 | "Step: 7 The condition is satisfied\n", 416 | "Step: 8 The condition is satisfied\n", 417 | "Step: 9 The condition is satisfied\n" 418 | ] 419 | } 420 | ], 421 | "source": [ 422 | "#While loop\n", 423 | "i = 1\n", 424 | "while i < 10:\n", 425 | " print(\"Step: \" + str(i) + \" The condition is satisfied\")\n", 426 | " i += 1" 427 | ] 428 | }, 429 | { 430 | "cell_type": "markdown", 431 | "metadata": {}, 432 | "source": [ 433 | "## Complexity of common search algorithms\n", 434 | "\n", 435 | "### Linear search algorithm " 436 | ] 437 | }, 438 | { 439 | "cell_type": "code", 440 | "execution_count": 22, 441 | "metadata": {}, 442 | "outputs": [ 443 | { 444 | "name": "stdin", 445 | "output_type": "stream", 446 | "text": [ 447 | "Please input a number of your choice: 5\n" 448 | ] 449 | }, 450 | { 451 | "name": "stdout", 452 | "output_type": "stream", 453 | "text": [ 454 | "False \n", 455 | "False \n", 456 | "False \n", 457 | "False \n", 458 | "True \n", 459 | "False \n", 460 | "False \n", 461 | "False \n" 462 | ] 463 | } 464 | ], 465 | "source": [ 466 | "def linear_search(input):\n", 467 | " lists = [1, 2, 3, 4, 5, 6, 7, 8]\n", 468 | " number = int(input)\n", 469 | " \n", 470 | " for i in range(len(lists)):\n", 471 | " if lists[i] == number:\n", 472 | " print(\"True\", end=' ')\n", 473 | " \n", 474 | " else:\n", 475 | " print(\"False\", end=' ')\n", 476 | " \n", 477 | " print()\n", 478 | " \n", 479 | "INPUT = input(\"Please input a number of your choice: \")\n", 480 | "linear_search(INPUT)" 481 | ] 482 | }, 483 | { 484 | "cell_type": "markdown", 485 | "metadata": {}, 486 | "source": [ 487 | "### Binary search algorithm" 488 | ] 489 | }, 490 | { 491 | "cell_type": "code", 492 | "execution_count": 23, 493 | "metadata": {}, 494 | "outputs": [ 495 | { 496 | "name": "stdout", 497 | "output_type": "stream", 498 | "text": [ 499 | "Target element is present at index 9 of the list\n" 500 | ] 501 | } 502 | ], 503 | "source": [ 504 | "# Returns index of target (x) if present in the list\n", 505 | "def binary_search(list, l, r, target_value):\n", 506 | " # Check base case\n", 507 | " if r >= l:\n", 508 | " mid_index = l + (r - l) // 2\n", 509 | " \n", 510 | " # If target element matches with the mid-element of the list\n", 511 | " if list[mid_index] == target_value:\n", 512 | " return mid_index\n", 513 | "\n", 514 | " # If element is smaller than mid-element, then it can only be present in the left sublist\n", 515 | " elif list[mid_index] > target_value:\n", 516 | " return binary_search(list, l, mid_index - 1, target_value)\n", 517 | "\n", 518 | " # Else the element can only be present in the right sub-list\n", 519 | " else:\n", 520 | " return binary_search(list, mid_index + 1, r, target_value)\n", 521 | " \n", 522 | " else:\n", 523 | " # Element is not present in the array\n", 524 | " return -1\n", 525 | "\n", 526 | "# Test list\n", 527 | "list = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]\n", 528 | "target_value = 100\n", 529 | "\n", 530 | "# Function call\n", 531 | "result = binary_search(list, 0, len(list) - 1, target_value)\n", 532 | "\n", 533 | "if result != -1:\n", 534 | " print(\"Target element is present at index \" + str(result) + \" of the list\")\n", 535 | "\n", 536 | "else:\n", 537 | " print(\"Target element is not present in list\")" 538 | ] 539 | } 540 | ], 541 | "metadata": { 542 | "kernelspec": { 543 | "display_name": "Python 3.7 (DL)", 544 | "language": "python", 545 | "name": "dl" 546 | }, 547 | "language_info": { 548 | "codemirror_mode": { 549 | "name": "ipython", 550 | "version": 3 551 | }, 552 | "file_extension": ".py", 553 | "mimetype": "text/x-python", 554 | "name": "python", 555 | "nbconvert_exporter": "python", 556 | "pygments_lexer": "ipython3", 557 | "version": "3.7.7" 558 | } 559 | }, 560 | "nbformat": 4, 561 | "nbformat_minor": 4 562 | } 563 | -------------------------------------------------------------------------------- /Chapter 07 - Computational Requirements for Algorithms/.ipynb_checkpoints/Chapter7-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Chapter 7 - Computational Requirements for Algorithms\n", 8 | "\n", 9 | "This notebook contains code accompanying Chapter 7 Computational Requirements for Algorithms in *Practical Discrete Mathematics* by Ryan T. White and Archana Tikayat Ray.\n", 10 | "\n", 11 | "## Computational complexity of algorithms \n", 12 | "\n", 13 | "### Example: A simple algorithm" 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 2, 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "name": "stdin", 23 | "output_type": "stream", 24 | "text": [ 25 | "Please enter a fruit name: Apple\n" 26 | ] 27 | }, 28 | { 29 | "name": "stdout", 30 | "output_type": "stream", 31 | "text": [ 32 | "The updated list is: ['Jackfruit', 'Honeydew', 'Grapes', 'Apple']\n" 33 | ] 34 | }, 35 | { 36 | "name": "stdin", 37 | "output_type": "stream", 38 | "text": [ 39 | "Please enter the name of the fruit you want to delete: Apple\n" 40 | ] 41 | }, 42 | { 43 | "name": "stdout", 44 | "output_type": "stream", 45 | "text": [ 46 | "The updated list is: ['Jackfruit', 'Honeydew', 'Grapes']\n" 47 | ] 48 | } 49 | ], 50 | "source": [ 51 | "#Type of algorithm - inserting new element to pre-existing list\n", 52 | "fruit_name = [\"Jackfruit\", \"Honeydew\", \"Grapes\"]\n", 53 | "user_input1 = input(\"Please enter a fruit name: \")\n", 54 | "fruit_name.append(user_input1)\n", 55 | "print('The updated list is: ' + str(fruit_name))\n", 56 | "\n", 57 | "#Type of algorithm - deleting element from list\n", 58 | "user_input2 = input(\"Please enter the name of the fruit you want to delete: \")\n", 59 | "fruit_name.remove(user_input2)\n", 60 | "print('The updated list is: ' + str(fruit_name))" 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "### Example: Execution Time" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 6, 73 | "metadata": {}, 74 | "outputs": [ 75 | { 76 | "name": "stdin", 77 | "output_type": "stream", 78 | "text": [ 79 | "Please input a number of your choice: 1\n" 80 | ] 81 | }, 82 | { 83 | "name": "stdout", 84 | "output_type": "stream", 85 | "text": [ 86 | "Yes No No No No No No No \n", 87 | "The time elapsed for this computation is: 0.3815207999999757seconds\n" 88 | ] 89 | } 90 | ], 91 | "source": [ 92 | "# a is a list containing some numbers\n", 93 | "# We will compare the number input by user with the numbers in this list\n", 94 | "import timeit\n", 95 | "tic=timeit.default_timer()\n", 96 | "\n", 97 | "a=[1,2,3,4,5,6,7,8]\n", 98 | "\n", 99 | "INPUT = input(\"Please input a number of your choice: \")\n", 100 | "number = int(INPUT)\n", 101 | "\n", 102 | "for i in range(len(a)):\n", 103 | " if a[i]== number:\n", 104 | " print(\"Yes\", end=' ')\n", 105 | " else:\n", 106 | " print(\"No\", end=' ')\n", 107 | " \n", 108 | "print()\n", 109 | "\n", 110 | "toc=timeit.default_timer()\n", 111 | "time_elapsed = toc - tic\n", 112 | "\n", 113 | "print(\"The time elapsed for this computation is: \" + str(time_elapsed) + \"seconds\")" 114 | ] 115 | }, 116 | { 117 | "cell_type": "markdown", 118 | "metadata": {}, 119 | "source": [ 120 | "## Understanding Big-O Notation\n", 121 | "\n", 122 | "### Constant complexity O(constant)" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 9, 128 | "metadata": {}, 129 | "outputs": [ 130 | { 131 | "name": "stdout", 132 | "output_type": "stream", 133 | "text": [ 134 | "The end result after running the algorithm is:8\n" 135 | ] 136 | } 137 | ], 138 | "source": [ 139 | "#Constant complexity function\n", 140 | "def constant_complexity(list):\n", 141 | " output = list[1] * list[1] * list[1]\n", 142 | " print(\"The end result after running the algorithm is:\" + str(output))\n", 143 | " \n", 144 | "constant_complexity([1,2,3,4,5,6,7])" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": {}, 150 | "source": [ 151 | "### Linear complexity $O(n)$" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": 10, 157 | "metadata": {}, 158 | "outputs": [ 159 | { 160 | "name": "stdout", 161 | "output_type": "stream", 162 | "text": [ 163 | "Iteration number 1\n", 164 | "Iteration number 2\n", 165 | "Iteration number 3\n", 166 | "Iteration number 4\n", 167 | "Iteration number 5\n", 168 | "Iteration number 6\n", 169 | "Iteration number 7\n" 170 | ] 171 | } 172 | ], 173 | "source": [ 174 | "# Linear complexity\n", 175 | "def linear_complexity(list):\n", 176 | " for i in list:\n", 177 | " print(\"Iteration number \" + str(i))\n", 178 | "\n", 179 | "linear_complexity([1,2,3,4,5,6,7])" 180 | ] 181 | }, 182 | { 183 | "cell_type": "markdown", 184 | "metadata": {}, 185 | "source": [ 186 | "### Quadratic complexity $O(n^2)$" 187 | ] 188 | }, 189 | { 190 | "cell_type": "code", 191 | "execution_count": 11, 192 | "metadata": {}, 193 | "outputs": [ 194 | { 195 | "name": "stdout", 196 | "output_type": "stream", 197 | "text": [ 198 | "1\t|First for loop iteration: 1 \t| Second for loop iteration:1\n", 199 | "2\t|First for loop iteration: 1 \t| Second for loop iteration:2\n", 200 | "3\t|First for loop iteration: 1 \t| Second for loop iteration:3\n", 201 | "4\t|First for loop iteration: 1 \t| Second for loop iteration:4\n", 202 | "5\t|First for loop iteration: 2 \t| Second for loop iteration:1\n", 203 | "6\t|First for loop iteration: 2 \t| Second for loop iteration:2\n", 204 | "7\t|First for loop iteration: 2 \t| Second for loop iteration:3\n", 205 | "8\t|First for loop iteration: 2 \t| Second for loop iteration:4\n", 206 | "9\t|First for loop iteration: 3 \t| Second for loop iteration:1\n", 207 | "10\t|First for loop iteration: 3 \t| Second for loop iteration:2\n", 208 | "11\t|First for loop iteration: 3 \t| Second for loop iteration:3\n", 209 | "12\t|First for loop iteration: 3 \t| Second for loop iteration:4\n", 210 | "13\t|First for loop iteration: 4 \t| Second for loop iteration:1\n", 211 | "14\t|First for loop iteration: 4 \t| Second for loop iteration:2\n", 212 | "15\t|First for loop iteration: 4 \t| Second for loop iteration:3\n", 213 | "16\t|First for loop iteration: 4 \t| Second for loop iteration:4\n" 214 | ] 215 | } 216 | ], 217 | "source": [ 218 | "#Quadratic complexity\n", 219 | "def quadratic_complexity(list):\n", 220 | " count = 0\n", 221 | " for i in list:\n", 222 | " for j in list:\n", 223 | " count += 1\n", 224 | " print(str(count) + \"\\t|First for loop iteration: \" + str(i), '\\t|', \"Second for loop iteration:\" + str(j))\n", 225 | " \n", 226 | "quadratic_complexity([1,2,3,4])" 227 | ] 228 | }, 229 | { 230 | "cell_type": "markdown", 231 | "metadata": {}, 232 | "source": [ 233 | "### Complexity of complex functions" 234 | ] 235 | }, 236 | { 237 | "cell_type": "code", 238 | "execution_count": 13, 239 | "metadata": {}, 240 | "outputs": [ 241 | { 242 | "name": "stdout", 243 | "output_type": "stream", 244 | "text": [ 245 | "Step: 1 \t Hello World!\n", 246 | "Step: 2 \t Hello World!\n", 247 | "Step: 3 \t Hello World!\n", 248 | "Step: 4 \t Hello World!\n", 249 | "Step: 5 \t Hello World!\n", 250 | "Step: 6 \t Hello World!\n", 251 | "Step: 7 \t 1\n", 252 | "Step: 8 \t 2\n", 253 | "Step: 9 \t 3\n", 254 | "Step: 10 \t 4\n", 255 | "Step: 11 \t 1\n", 256 | "Step: 12 \t 2\n", 257 | "Step: 13 \t 3\n", 258 | "Step: 14 \t 4\n" 259 | ] 260 | } 261 | ], 262 | "source": [ 263 | "#Complex function complexity\n", 264 | "def complex_func (list):\n", 265 | " count = 0\n", 266 | " for i in range(6):\n", 267 | " count += 1\n", 268 | " print(\"Step: \" + str(count) + \" \\t Hello World!\")\n", 269 | " \n", 270 | " for j in list:\n", 271 | " count += 1\n", 272 | " print(\"Step: \" + str(count) + \" \\t \" + str(j))\n", 273 | " \n", 274 | " for k in list:\n", 275 | " count += 1\n", 276 | " print(\"Step: \" + str(count) + \" \\t \" + str(k))\n", 277 | "\n", 278 | "complex_func([1,2,3,4])" 279 | ] 280 | }, 281 | { 282 | "cell_type": "markdown", 283 | "metadata": {}, 284 | "source": [ 285 | "## Complexity of algorithms with fundamental control structures\n", 286 | "\n", 287 | "### `if`-`elif`-`else`" 288 | ] 289 | }, 290 | { 291 | "cell_type": "code", 292 | "execution_count": 14, 293 | "metadata": {}, 294 | "outputs": [ 295 | { 296 | "name": "stdout", 297 | "output_type": "stream", 298 | "text": [ 299 | "b is less than a\n" 300 | ] 301 | } 302 | ], 303 | "source": [ 304 | "#Complexity of if-elif-else statements\n", 305 | "a = 10\n", 306 | "b = 5\n", 307 | "if b > a:\n", 308 | " print(\"b is greater than a\")\n", 309 | " \n", 310 | "elif b < a:\n", 311 | " print(\"b is less than a\")\n", 312 | " \n", 313 | "else:\n", 314 | " print(\"a and b are equal\")" 315 | ] 316 | }, 317 | { 318 | "cell_type": "markdown", 319 | "metadata": {}, 320 | "source": [ 321 | "### `for` Loops" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 18, 327 | "metadata": {}, 328 | "outputs": [ 329 | { 330 | "name": "stdout", 331 | "output_type": "stream", 332 | "text": [ 333 | "apple\n", 334 | "mango\n", 335 | "orange\n", 336 | "banana\n", 337 | "pomegranate\n" 338 | ] 339 | } 340 | ], 341 | "source": [ 342 | "#For loop\n", 343 | "fruits = [\"apple\", \"mango\", \"orange\", \"banana\", \"pomegranate\"]\n", 344 | "\n", 345 | "for x in fruits:\n", 346 | " print(x)" 347 | ] 348 | }, 349 | { 350 | "cell_type": "markdown", 351 | "metadata": {}, 352 | "source": [ 353 | "### Nested `for` Loops" 354 | ] 355 | }, 356 | { 357 | "cell_type": "code", 358 | "execution_count": 19, 359 | "metadata": {}, 360 | "outputs": [ 361 | { 362 | "name": "stdout", 363 | "output_type": "stream", 364 | "text": [ 365 | "tasty apple\n", 366 | "tasty mango\n", 367 | "tasty orange\n", 368 | "tasty banana\n", 369 | "tasty pomegranate\n", 370 | "juicy apple\n", 371 | "juicy mango\n", 372 | "juicy orange\n", 373 | "juicy banana\n", 374 | "juicy pomegranate\n", 375 | "fresh apple\n", 376 | "fresh mango\n", 377 | "fresh orange\n", 378 | "fresh banana\n", 379 | "fresh pomegranate\n" 380 | ] 381 | } 382 | ], 383 | "source": [ 384 | "#Nested for loop\n", 385 | "fruits = [\"apple\", \"mango\", \"orange\", \"banana\", \"pomegranate\"]\n", 386 | "adjectives = [\"tasty\", \"juicy\", \"fresh\"]\n", 387 | "\n", 388 | "for y in adjectives:\n", 389 | " for x in fruits:\n", 390 | " print(y, x)" 391 | ] 392 | }, 393 | { 394 | "cell_type": "markdown", 395 | "metadata": {}, 396 | "source": [ 397 | "### `while` Loops" 398 | ] 399 | }, 400 | { 401 | "cell_type": "code", 402 | "execution_count": 21, 403 | "metadata": {}, 404 | "outputs": [ 405 | { 406 | "name": "stdout", 407 | "output_type": "stream", 408 | "text": [ 409 | "Step: 1 The condition is satisfied\n", 410 | "Step: 2 The condition is satisfied\n", 411 | "Step: 3 The condition is satisfied\n", 412 | "Step: 4 The condition is satisfied\n", 413 | "Step: 5 The condition is satisfied\n", 414 | "Step: 6 The condition is satisfied\n", 415 | "Step: 7 The condition is satisfied\n", 416 | "Step: 8 The condition is satisfied\n", 417 | "Step: 9 The condition is satisfied\n" 418 | ] 419 | } 420 | ], 421 | "source": [ 422 | "#While loop\n", 423 | "i = 1\n", 424 | "while i < 10:\n", 425 | " print(\"Step: \" + str(i) + \" The condition is satisfied\")\n", 426 | " i += 1" 427 | ] 428 | }, 429 | { 430 | "cell_type": "markdown", 431 | "metadata": {}, 432 | "source": [ 433 | "## Complexity of common search algorithms\n", 434 | "\n", 435 | "### Linear search algorithm " 436 | ] 437 | }, 438 | { 439 | "cell_type": "code", 440 | "execution_count": 22, 441 | "metadata": {}, 442 | "outputs": [ 443 | { 444 | "name": "stdin", 445 | "output_type": "stream", 446 | "text": [ 447 | "Please input a number of your choice: 5\n" 448 | ] 449 | }, 450 | { 451 | "name": "stdout", 452 | "output_type": "stream", 453 | "text": [ 454 | "False \n", 455 | "False \n", 456 | "False \n", 457 | "False \n", 458 | "True \n", 459 | "False \n", 460 | "False \n", 461 | "False \n" 462 | ] 463 | } 464 | ], 465 | "source": [ 466 | "def linear_search(input):\n", 467 | " lists = [1, 2, 3, 4, 5, 6, 7, 8]\n", 468 | " number = int(input)\n", 469 | " \n", 470 | " for i in range(len(lists)):\n", 471 | " if lists[i] == number:\n", 472 | " print(\"True\", end=' ')\n", 473 | " \n", 474 | " else:\n", 475 | " print(\"False\", end=' ')\n", 476 | " \n", 477 | " print()\n", 478 | " \n", 479 | "INPUT = input(\"Please input a number of your choice: \")\n", 480 | "linear_search(INPUT)" 481 | ] 482 | }, 483 | { 484 | "cell_type": "markdown", 485 | "metadata": {}, 486 | "source": [ 487 | "### Binary search algorithm" 488 | ] 489 | }, 490 | { 491 | "cell_type": "code", 492 | "execution_count": 23, 493 | "metadata": {}, 494 | "outputs": [ 495 | { 496 | "name": "stdout", 497 | "output_type": "stream", 498 | "text": [ 499 | "Target element is present at index 9 of the list\n" 500 | ] 501 | } 502 | ], 503 | "source": [ 504 | "# Returns index of target (x) if present in the list\n", 505 | "def binary_search(list, l, r, target_value):\n", 506 | " # Check base case\n", 507 | " if r >= l:\n", 508 | " mid_index = l + (r - l) // 2\n", 509 | " \n", 510 | " # If target element matches with the mid-element of the list\n", 511 | " if list[mid_index] == target_value:\n", 512 | " return mid_index\n", 513 | "\n", 514 | " # If element is smaller than mid-element, then it can only be present in the left sublist\n", 515 | " elif list[mid_index] > target_value:\n", 516 | " return binary_search(list, l, mid_index - 1, target_value)\n", 517 | "\n", 518 | " # Else the element can only be present in the right sub-list\n", 519 | " else:\n", 520 | " return binary_search(list, mid_index + 1, r, target_value)\n", 521 | " \n", 522 | " else:\n", 523 | " # Element is not present in the array\n", 524 | " return -1\n", 525 | "\n", 526 | "# Test list\n", 527 | "list = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]\n", 528 | "target_value = 100\n", 529 | "\n", 530 | "# Function call\n", 531 | "result = binary_search(list, 0, len(list) - 1, target_value)\n", 532 | "\n", 533 | "if result != -1:\n", 534 | " print(\"Target element is present at index \" + str(result) + \" of the list\")\n", 535 | "\n", 536 | "else:\n", 537 | " print(\"Target element is not present in list\")" 538 | ] 539 | } 540 | ], 541 | "metadata": { 542 | "kernelspec": { 543 | "display_name": "Python 3.7 (DL)", 544 | "language": "python", 545 | "name": "dl" 546 | }, 547 | "language_info": { 548 | "codemirror_mode": { 549 | "name": "ipython", 550 | "version": 3 551 | }, 552 | "file_extension": ".py", 553 | "mimetype": "text/x-python", 554 | "name": "python", 555 | "nbconvert_exporter": "python", 556 | "pygments_lexer": "ipython3", 557 | "version": "3.7.7" 558 | } 559 | }, 560 | "nbformat": 4, 561 | "nbformat_minor": 4 562 | } 563 | -------------------------------------------------------------------------------- /Chapter 05 - Elements of Discrete Probability/Chapter5.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Chapter 5 - Elements of Discrete Mathematics\n", 8 | "\n", 9 | "This notebook contains code accompanying Chapter 5 Elements of Discrete Mathematics in *Practical Discrete Mathematics* by Ryan T. White and Archana Tikayat Ray.\n", 10 | "\n", 11 | "## The Basics of Discrete Probability\n", 12 | "\n", 13 | "### Example: Tossing Many Coins\n", 14 | "\n", 15 | "The code below computes the probability of getting $k=0$, $k=1$, ..., $k=50$ heads in 50 coin tosses of fair coins. These are binomial probabilities." 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 2, 21 | "metadata": {}, 22 | "outputs": [ 23 | { 24 | "name": "stdout", 25 | "output_type": "stream", 26 | "text": [ 27 | "Probability of 0 heads: 0.000000\n", 28 | "Probability of 1 heads: 0.000000\n", 29 | "Probability of 2 heads: 0.000000\n", 30 | "Probability of 3 heads: 0.000000\n", 31 | "Probability of 4 heads: 0.000000\n", 32 | "Probability of 5 heads: 0.000000\n", 33 | "Probability of 6 heads: 0.000000\n", 34 | "Probability of 7 heads: 0.000000\n", 35 | "Probability of 8 heads: 0.000000\n", 36 | "Probability of 9 heads: 0.000002\n", 37 | "Probability of 10 heads: 0.000009\n", 38 | "Probability of 11 heads: 0.000033\n", 39 | "Probability of 12 heads: 0.000108\n", 40 | "Probability of 13 heads: 0.000315\n", 41 | "Probability of 14 heads: 0.000833\n", 42 | "Probability of 15 heads: 0.001999\n", 43 | "Probability of 16 heads: 0.004373\n", 44 | "Probability of 17 heads: 0.008746\n", 45 | "Probability of 18 heads: 0.016035\n", 46 | "Probability of 19 heads: 0.027006\n", 47 | "Probability of 20 heads: 0.041859\n", 48 | "Probability of 21 heads: 0.059799\n", 49 | "Probability of 22 heads: 0.078826\n", 50 | "Probability of 23 heads: 0.095962\n", 51 | "Probability of 24 heads: 0.107957\n", 52 | "Probability of 25 heads: 0.112275\n", 53 | "Probability of 26 heads: 0.107957\n", 54 | "Probability of 27 heads: 0.095962\n", 55 | "Probability of 28 heads: 0.078826\n", 56 | "Probability of 29 heads: 0.059799\n", 57 | "Probability of 30 heads: 0.041859\n", 58 | "Probability of 31 heads: 0.027006\n", 59 | "Probability of 32 heads: 0.016035\n", 60 | "Probability of 33 heads: 0.008746\n", 61 | "Probability of 34 heads: 0.004373\n", 62 | "Probability of 35 heads: 0.001999\n", 63 | "Probability of 36 heads: 0.000833\n", 64 | "Probability of 37 heads: 0.000315\n", 65 | "Probability of 38 heads: 0.000108\n", 66 | "Probability of 39 heads: 0.000033\n", 67 | "Probability of 40 heads: 0.000009\n", 68 | "Probability of 41 heads: 0.000002\n", 69 | "Probability of 42 heads: 0.000000\n", 70 | "Probability of 43 heads: 0.000000\n", 71 | "Probability of 44 heads: 0.000000\n", 72 | "Probability of 45 heads: 0.000000\n", 73 | "Probability of 46 heads: 0.000000\n", 74 | "Probability of 47 heads: 0.000000\n", 75 | "Probability of 48 heads: 0.000000\n", 76 | "Probability of 49 heads: 0.000000\n", 77 | "Probability of 50 heads: 0.000000\n" 78 | ] 79 | }, 80 | { 81 | "data": { 82 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYAAAAD4CAYAAADlwTGnAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3dfXRc1Xnv8e+j0YtlG1uWJRtbMrYxjkHEgEHxCyZNSgLGJI0dbkjhlpKbdVsuq6GB3sS5dtrV5vZl4dZdaZJVGuomtNByS2hwHDfQCIJDAjGxLSPAGCOQ3yUZS36RX/U+z/1jRkaWR9ZIHunMzPl91vKy5px9zjyzNTrPzN777G3ujoiIhE9O0AGIiEgwlABEREJKCUBEJKSUAEREQkoJQEQkpHKDDiCRkpISnzFjRtBhiIhkjG3bth1299LBHJOWCWDGjBlUV1cHHYaISMYws32DPUZNQCIiIaUEICISUkoAIiIhpQQgIhJSSgAiIiGlBCAiElJKACIiIaUEICISUkoAIiIhpQQgIhJSSSUAM7vNzGrNrM7MVibYf6WZvWpm7Wb21QT7I2ZWY2Y/SUXQIiJy8QZMAGYWAR4BlgIVwN1mVtGn2FHgy8Df9nOaB4GdFxGniIikWDLfAOYDde6+2907gKeAZb0LuHuTu28FOvsebGblwKeA76UgXhERSZFkEkAZcKDX4/r4tmR9C/gaEL1QITO7z8yqzay6ubl5EKcXEZGhSCYBWIJtnszJzezTQJO7bxuorLuvdfdKd68sLR3UlNYiIjIEySSAemBar8flQGOS518MfMbM9hJrOrrZzP5tUBGKiMiwSCYBbAVmm9lMM8sH7gI2JHNyd1/l7uXuPiN+3EZ3v2fI0YqISMoMuCKYu3eZ2QNAFRABHnP3HWZ2f3z/o2Z2KVANjAOiZvYQUOHuJ4YxdhERuQjmnlRz/oiqrKx0LQkpIpI8M9vm7pWDOUZ3AouIhJQSgIhISCkBiIiElBKAiEhIKQGIiISUEoCISEgpAYiIhJQSgIhISCkBiIiElBKAiEhIKQGIiISUEoCISEgpAYiIhJQSgIhISCkBiIiElBKAiEhIKQGIiISUEoCISEgpAYiIhJQSgIhISCWVAMzsNjOrNbM6M1uZYP+VZvaqmbWb2Vd7bZ9mZj83s51mtsPMHkxl8CIiMnS5AxUwswjwCHALUA9sNbMN7v52r2JHgS8Dy/sc3gV8xd1fM7NLgG1m9kKfY0VEJADJfAOYD9S5+2537wCeApb1LuDuTe6+Fejss/2gu78W//kksBMoS0nkIiJyUZJJAGXAgV6P6xnCRdzMZgDzgM397L/PzKrNrLq5uXmwpxcRkUFKJgFYgm0+mCcxs7HAM8BD7n4iURl3X+vule5eWVpaOpjTi4jIECSTAOqBab0elwONyT6BmeURu/g/6e7rBheeiIgMl2QSwFZgtpnNNLN84C5gQzInNzMDvg/sdPdvDj1MERFJtQFHAbl7l5k9AFQBEeAxd99hZvfH9z9qZpcC1cA4IGpmDwEVwDXA7wLbzez1+Cm/7u7PDcNrERGRQRgwAQDEL9jP9dn2aK+f3yfWNNTXKyTuQxARkYDpTmARkZBSAhARCamkmoBEwm59TQNrqmppbGllalEhK5bMYfk83dMomU0JQGQA62saWLVuO62d3QA0tLSyat12ACUByWhqAhIZwJqq2rMX/x6tnd2sqaoNKCKR1FACEBlAY0vroLaLZAolAJEL6OiKMiov8Z/JlKJRIxyNSGopAYj040xHF7/3RDWtnVFyc86/naVkTD7tXd0JjhTJDOoEFonrPdLn0vGjGJWbw96jZ1h9x1xG5UXOGQU0f8YEfvR6I7/3eDW/dc0Uvv1inUYIScZRAhDh/JE+B4+3AfCFRdO5a/5lwPkjfm68ooQVP3yTV+oO4/H5cTVCSDKJmoBESDzSB+BnO5v6PebOymkUj8k7e/HvoRFCkimUAEQY+kifY6c7E27XCCHJBEoAIsDUosJBbb/Y40TSgRKACLBiyRzyIueO9CnMi7BiyZwBjyvMiwz6OJF0oAQgQqzDdtqE0URyDAPKigp5+I65A3bkLp9XxsN3zGVq/J6AgtycpI4TSQcaBSQC7G4+xe7Dp/nabXP4g49fMahjl88rY/m8Mv7mp+/w6C92sfDyicMUpUhq6RuACPAf2+qJ5Bifuz7RukbJ+XzlNKIOz7xWn8LIRIaPEoCEXld3lGe21fObc0qZNG7o0zvMKBnDgpnF/Ef1Abzv2FCRNKQEIKH3Um0zTSfbubNy2kWf6/OV09h75Ayb9xxNQWQiw0sJQELv6eoDlIzN5+YrJ130uW6fO4WxBbk8XX0gBZGJDK+kEoCZ3WZmtWZWZ2YrE+y/0sxeNbN2M/vqYI4VCVLzyXY2vtPEHdeXkxe5+M9DhfkRfuvaqTy3/SAn2hLfJCaSLgZ8x5tZBHgEWApUAHebWUWfYkeBLwN/O4RjRQLzo5p6uqLO51PQ/NPjtz8yjbbOKD9542DKzikyHJL5yDMfqHP33e7eATwFLOtdwN2b3H0r0Pcjz4DHigTF3fnB1gPcMH0CV0wam7LzXls+njmTL+EHagaSNJdMAigDer+T6+PbkpH0sWZ2n5lVm1l1c3NzkqcXGbrX9rewq/k0n68c+tDPRMyMOyvLeeNAC7Xvn0zpuUVSKZkEcP5KGJDsGLekj3X3te5e6e6VpaWlSZ5eZOie3nqA0fkRPnXN1JSf+7PzysiLmDqDJa0lkwDqgd4NpOVAY5Lnv5hjRYbN6fYufvJmI5+Kj9pJtYljC/jkVZP5UU0DHV3RlJ9fJBWSSQBbgdlmNtPM8oG7gA1Jnv9ijhUZFutrGlj81xs53dHNz2ubWF/TMCzPM624kKOnO/jQn/wXi1dvHLbnERmqAT/6uHuXmT0AVAER4DF332Fm98f3P2pmlwLVwDggamYPARXufiLRscP1YkQG0nflr8OnOoZlBa/1NQ3866v7zj7WSmGSjiwdb1mvrKz06urqoMOQLLR49UYaEizWUlZUyK9W3pxxzyPSw8y2uXvlYI7RncASKkNd+Stdn0fkYigBSKiM1ApeWilMMoESgITKV26Zfd624VjBK/FKYTlaKUzSihaEkVCZXhK743fC6DxaznQytaiQFUvmpLxjtud8a6pqz/YFfPkTs9UBLGlFCUBC5ZX3DmMGG7/ycSaMyR/W5+pZKayhpZXFqzeSnxsZ+CCREaQmIAmVV+qamVs2ftgv/r2VFRVyeckYXnlPU5xIelECkNA41d5Fzf4WbrqiZMSf+6bZJWzec1R3BUtaUQKQ0Pj1riN0RZ2bZgeQAK4o4UxHN6/tPzbizy3SHyUACY1X6g5TmBfhhukTRvy5F86aSCTHeOW9wyP+3CL9UQKQ0Hj5vWbmzyymIIDO2HGj8rhuWhEv1ykBSPpQApBQOHi8lV3Np/loAM0/PW66ooTt9S0cP6OlIiU9KAFIKLwcb3oJov2/x0dnlxB12LRL3wIkPSgBSCi88t5hSi8pYM7kSwKL4dppRYwtyFUzkKQNJQDJetGo86u6w9x0RQlmiRapGxl5kRwWXj5RHcGSNpQAJOvtfP8ER053BDL+v6+Pzi5h/9Ez7D9yJuhQRJQAJPu9kgbt/z16Yni5TncFS/CUACTrvVJ3mA9NHsvkcaOCDoXLS8YwdfwoNQNJWlACkKzW1tnNlj1HuemK0qBDAcDMuGl2CZt2HaE7mn6r8Um4KAFIVqvee4z2rmig4//7uml2KcdbO9necDzoUCTklAAkq71c10xexFhweXHQoZy1eNZEAM0OKoFLKgGY2W1mVmtmdWa2MsF+M7PvxPe/aWbX99r3R2a2w8zeMrN/N7PgG2IlNF557zDXXzaB0fnps/TFxLEFXD113Nmb00SCMmACMLMI8AiwFKgA7jazij7FlgKz4//uA74bP7YM+DJQ6e4fBiLAXSmLXuQCjpxqZ0fjibRq/ulx0+wSXtt/jNPtXUGHIiGWzDeA+UCdu+929w7gKWBZnzLLgCc85tdAkZlNie/LBQrNLBcYDTSmKHaRfq2vaeCT3/wFAI9v2sf6moaAIzpXDkZnt3P1n1WxePXGtItPwiGZBFAGHOj1uD6+bcAy7t4A/C2wHzgIHHf35xM9iZndZ2bVZlbd3Ky2URm69TUNrFq3nWPxSdeaT7Wzat32tLnIrq9p4J837Tn7uKGlNa3ik/BIJgEkune+7/i1hGXMbAKxbwczganAGDO7J9GTuPtad69098rS0vQYsieZaU1VLa2d3edsa+3sZk1VbUARnWtNVS1tneeuDJZO8Ul4JJMA6oFpvR6Xc34zTn9lPgnscfdmd+8E1gE3Dj1ckYE1trQOavtIS/f4JDySSQBbgdlmNtPM8ol14m7oU2YDcG98NNBCYk09B4k1/Sw0s9EWm4XrE8DOFMYvcp6pRYWD2j7S0j0+CY8BE4C7dwEPAFXELt5Pu/sOM7vfzO6PF3sO2A3UAf8E/EH82M3AD4HXgO3x51ub6hch0tuKJXOI5JzbKlmYF2HFkjkBRXSuFUvmUJh37qpk6RSfhIe5p9/t6JWVlV5dXR10GJLBKv/yBU61ddHeFWVqUSErlsxh+by+YxeCs76mgTVVtTS0tJIXMdZ87tq0ik8yj5ltc/fKwRyTPnfHiKRI04k2Dp/q4I9vv4rf/43Lgw4noeXzylg+r4xvvvAuf7/xPT5x1aSgQ5IQ0lQQknW27D0KwPyZ6TP9Q38WzCwm6rBt37GgQ5EQUgKQrLNlz1FG50e4euq4oEMZ0LzLisjNMbbsORp0KBJCSgCSdbbsOcoN0yeQG0n/t/fo/Fzmlo9XApBApP9fiMggtJzp4J33T7IgA5p/esyfWcwb9S20dnQPXFgkhZQAJKts3RtrS58/c2LAkSRvwcxiOrudmgPqB5CRpQQgWWXLniPk5+ZwTfn4oENJ2g3TizFDzUAy4pQAJKts3nOUedOKGNXnRqt0Nr4wj4op45QAZMQpAUjWONXexVsNxzOq/b/H/JnFvLb/GB1d0YELi6SIEoBkjW37jhH1zGr/77FgZjFtnVGtEywjSglAssaWPUfIzTGun14UdCiD9pEZsW8tm/ccCTgSCRMlAMkaW/Yc5cNl49Nq/d9kTRxbwBWTxqofQEaUEoBkhbbObt44kJnt/z3mzyymeu8xuqPpN0GjZCclAMkKrx9ooaM7yoLLMzcBLJhZzKn2LnYePBF0KBISSgCSFTbvPopZbEx9puqZvG6zmoFkhCgBSFbYsvcIV106jvGFeUGHMmRTxhdyWfFotqgjWEaIEoBkvI6uKNv2HcuI6Z8HMn9mMVv2HCWqfgAZAUoAkvHeajxOW2c0ozuAe8yfWcyxM53UNZ8KOhQJASUAyXg9Qyc/kgUJYIH6AWQEKQFIxtuy5yizSsdQMrYg6FAu2mXFo5k8rkD3A8iISCoBmNltZlZrZnVmtjLBfjOz78T3v2lm1/faV2RmPzSzd8xsp5ktSuULkPBaX9PAjatfZOM7TRw83sb6moagQ7poZkbZ+EKefbORmSufZfHqjVnxuiQ9DXjLpJlFgEeAW4B6YKuZbXD3t3sVWwrMjv9bAHw3/j/At4GfuvvnzCwfGJ3C+CWk1tc0sGrddlo7Y4uonOnoZtW67UBswfVMtb6mge2Nx+npA25oac2K1yXpKZlvAPOBOnff7e4dwFPAsj5llgFPeMyvgSIzm2Jm44DfAL4P4O4d7t6SwvglpNZU1Z69+Pdo7exmTVVtQBGlxpqqWjq7zx0BlA2vS9JTMgmgDDjQ63F9fFsyZS4HmoF/NrMaM/uemY1J9CRmdp+ZVZtZdXNzc9IvQMKpsaV1UNszRba+LklPySQAS7Ct7yDl/srkAtcD33X3ecBp4Lw+BAB3X+vule5eWVpamkRYEmZTiwoHtT1TZOvrkvSUTAKoB6b1elwONCZZph6od/fN8e0/JJYQRC7KiiVzKMg99+1bmBdhxZI5AUWUGiuWzKGwz2pm2fC6JD0lkwC2ArPNbGa8E/cuYEOfMhuAe+OjgRYCx939oLu/Dxwws5537yeAtxG5SMvnlbGkYjIQ+/pZVlTIw3fMzfiO0uXzynj4jrlMHhcb0jq+MC8rXpekpwFHAbl7l5k9AFQBEeAxd99hZvfH9z8KPAfcDtQBZ4Av9jrFHwJPxpPH7j77RIbseFsXsyeN5YX//bGgQ0mp5fPKWHbdVG5cvZHrp0/QxV+GTVIrZ7j7c8Qu8r23PdrrZwe+1M+xrwOVFxGjyHk6u6Ns3XuUO28oDzqUYWFmLJo1kV/UNhONOjk5ibrZRC6O7gSWjPRmfQtnOrpZNCvz1v9N1qLLJ3LkdAfvNp0MOhTJUkoAkpE21R3BDBZk4ALwyepJbpvqND20DA8lAMlIm3YdoWLKOCaMyQ86lGFTPmE00yeOZtMuJQAZHkoAknHaOrvZtv8YN2Zx80+PG2dNZPPuI3R1R4MORbKQEoBknNf2HaOjK8qNs0qCDmXYLZpVwsn2LnY0ap1gST0lAMk4m3YdIZJjWTH//0AWXR7vB1AzkAwDJQDJOJt2Heba8vGMLUhqFHNGK72kgA9NHsumXYeDDkWykBKAZJRT7V28UX88FM0/PW6cVUL13lizl0gqKQFIRtm65yjdUQ9FB3CPRbMm0trZzRv1mkldUksJQDLKpl2Hyc/N4frpE4IOZcQsnDkRM90PIKmnBCAZZdOuI9xw2QRG9ZkxM5uNH53Hh6eOVz+ApJwSgGSMY6c7ePvgiVA1//S4cdZEava30NrRPXBhkSQpAUjG2LznCO5w4xXhSwCLZk2kozvKtn3Hgg5FsogSgGSMTbuOMDo/wjXlRUGHMuI+MqOY3BxTM5CklBKAZIxNu47wkRnF5EXC97YdU5DLtdOKdEOYpFT4/pIkIzWdbKOu6VQo2/973DhrIm/Wt3CirTPoUCRLKAFIRng1/sk3TDeA9bVo1kSiHrsXQiQVsv9eeslo62saWFNVS0NLKwa8d+gkc8vHBx1WIBqOtQLwPx+vpqyokBVL5mi5SLkoSgCSttbXNLBq3XZaO2NDHx344/VvkZNjobvwra9p4E9/vOPs44aWVlat2w4QurqQ1FETkKStNVW1Zy/+PVo7u1lTVRtQRMFRXchwSCoBmNltZlZrZnVmtjLBfjOz78T3v2lm1/fZHzGzGjP7SaoCl+zX2NI6qO3ZTHUhw2HABGBmEeARYClQAdxtZhV9ii0FZsf/3Qd8t8/+B4GdFx2thMrUosJBbc9mqgsZDsl8A5gP1Ln7bnfvAJ4ClvUpswx4wmN+DRSZ2RQAMysHPgV8L4VxSwisWDKHUXnnvkUL8yKsWDInoIiCs2LJHAr7zH80Ki8nlHUhqZNMAigDDvR6XB/flmyZbwFfAy44mbmZ3Wdm1WZW3dzcnERYku2WzyvjzsppABhQVlTIw3fMDWWn5/J5ZTx8x1zKen3iv3fh9FDWhaROMqOALME2T6aMmX0aaHL3bWb28Qs9ibuvBdYCVFZW9j2/hNSx0x2UjC1g89c/QSQn0dssPJbPK2P5vDLau7q54S9+xsn2rqBDkgyXzDeAemBar8flQGOSZRYDnzGzvcSajm42s38bcrQSKu1d3bxU28wnr5oU+ot/bwW5ET42p5QX3m4iGtVnJRm6ZBLAVmC2mc00s3zgLmBDnzIbgHvjo4EWAsfd/aC7r3L3cnefET9uo7vfk8oXINnr17uPcqq9i1uvnhx0KGnn1orJHD7VTs0BrRImQzdgAnD3LuABoIrYSJ6n3X2Hmd1vZvfHiz0H7AbqgH8C/mCY4pUQeX7H+4zOj4R6+of+fHzOJHJzjOfffj/oUCSDJXUnsLs/R+wi33vbo71+duBLA5zjJeClQUcooRSNOj/beYiPfag0VKt/JWt8YR6LZk3khbcPsWrpVUGHIxlKdwJLWnqz4TiHTrRzS4Waf/pzS8Vkdjefpq7pVNChSIZSApC09MLb7xPJMW6+clLQoaStT14VS44vvH0o4EgkUykBSFp6fschFswspmh0ftChpK2pRYVcUz5e/QAyZEoAknb2HD7Ne02n1PyThFuumkzN/haaTrQFHYpkICUASTsvxD/RKgEM7NarLwXgZzubAo5EMpESgKSd53ccomLKOMonjA46lLT3ocljuax4tJqBZEiUACStHD7Vzrb9x3TzV5LMjFsrJrOp7ginNDWEDJISgKSVF3cewh1urbg06FAyxq1XX0pHd5Rf1GoSRRkcJQBJK8/vOERZUSFXTbkk6FAyxg3TJ1A8Jl/NQDJoSgCSNk63d/Fy3WFuvXoyZpr8LVmRHOMTV05i4ztNdHZfcNZ1kXMoAUhaWF/TwEf/ZiMdXVH+841G1tc0BB1SRhk3KpeTbV3M/uP/YvHqjao/SUpScwGJDKf1NQ2sWrf97KLnh091sGrddgAteJKE9TUNPLll/9nHDS2tqj9Jir4BSODWVNWevfj3aO3sZk1VbUARZZY1VbW0dZ7b9KP6k2QoAUjgGltaB7VdzqX6k6FSApDATS0a1c/2woTb5Vz91ZPqTwaiBCCB61n4vbfCvAgrlswJIJrMs2LJHAr7rJlQkJuj+pMBqRNYArfvyBkKIkbx2ALeP97G1KJCViyZow7MJPXU05qqWhpbWnGgcvoE1Z8MSAlAAtV8sp1n3zzIf18wnW985uqgw8lYy+eVnb3gf/U/3uC57Qc50dbJuFF5AUcm6UxNQBKoH2zdT0d3lN9dND3oULLGvYumc6ajm3Xb6oMORdKcEoAEpqs7ypOb9/PR2SXMKh0bdDhZ45ryIq6bVsQTr+4jGvWgw5E0llQCMLPbzKzWzOrMbGWC/WZm34nvf9PMro9vn2ZmPzeznWa2w8weTPULkMz1s52HOHi8jXsXzQg6lKzzhRuns/vwaX6163DQoUgaGzABmFkEeARYClQAd5tZRZ9iS4HZ8X/3Ad+Nb+8CvuLuVwELgS8lOFZC6vFN+ygrKtS6v8Pg9rlTmDgmnyde3Rd0KJLGkvkGMB+oc/fd7t4BPAUs61NmGfCEx/waKDKzKe5+0N1fA3D3k8BOQEMThHcPneTV3Ue4Z+F0Ijma+C3VCnIj3DV/Gi/uPMSBo2eCDkfSVDIJoAw40OtxPedfxAcsY2YzgHnA5kRPYmb3mVm1mVU3N2te82z3r6/uIz83h9/+yPn3AEhq/M6CWMf6k5v3D1BSwiqZBJDo41nfnqULljGzscAzwEPufiLRk7j7WnevdPfK0tLSJMKSTHWirZNnXqvnM9dOpXhMftDhZK2pRYXcWnEpP9i6n7Y+cy2JQHIJoB7o/TGtHGhMtoyZ5RG7+D/p7uuGHqpki3Xb6jnT0c0X1Pk77O69cTrHznTyn2/0/ZMVSS4BbAVmm9lMM8sH7gI29CmzAbg3PhpoIXDc3Q9abFWP7wM73f2bKY1cMs76mgYWr36Rb/zn2+RFjF3Np4IOKestunwiky8p4Os/2s7Mlc9qrQA5x4B3Art7l5k9AFQBEeAxd99hZvfH9z8KPAfcDtQBZ4Avxg9fDPwusN3MXo9v+7q7P5falyHpru+c/53drjnrR8CPX2/k6JkOOrtjLbJaK0B6M/f0u1GksrLSq6urgw5DUmjx6o00JJieuKyokF+tvDmAiMJB9R4eZrbN3SsHc4zuBJYRoTnrg6F6lwtRApARMXmc5vwPgtYKkAtRApARMWX8+QlAc/4Pv0RrBURyTPUugBKAjICfv9NEzYEWbrv6UsqKCjFibdAP3zFXHZHDbPm8Mh6+Y+7Zeh9bkEt31BMmZAkfdQLLsDrd3sWtf/dLRudHePbLHyU/V585gnSmI/b7yM/N4b8e/CgFuZGBD5KMoE5gSTvffOFdGlpaefiOubr4p4HR+bn81Wfnsrv5NP/w811BhyMB01+kDJs361v451/t4XcWXEbljOKgw5G4j32olOXXTeUfXqqjrulk0OFIgLQkpKTU+pqGs2vTRnKMMfkR/s/SK4MOS/r4k09X8NK7zfz+E9W0d0U52KK1mMNI3wAkZXru9m2IL0zeFXXau6Js3NkUdGjSR8nYApZ++FL2HD5DY0sbzgd3CWuqiPBQApCUWVNVe3aqhx4d3c6aqtqAIpIL+eW750+73trZrd9XiCgBSMrortPM0tjS1s92/b7CQglAUqZkbEHC7brrND3pLmFRApCUeHXXEY63dpy3MpDu9k1fie4SBrizsjyAaCQIGgUkQ9J7tE/xmHxaznRweelY7ll4GWt/uYfGllaNKklzPb+Xnt/jpHEFdHVHWfvL3XR0R/lxTaN+j1lOdwLLoPWd2x/ADP5i2Ye5Z+H0ACOTi9V0oo3P/P0rvH+i/ZzthXkRTd2R5nQnsIyIRKN93OG7L+nO0kw3adwoYgv5nUujg7KTEoAMWqIFRkCjR7LF+8c1Oigs1Acg/erdzj+1qJDP3VBO9b6j/ZbX6JHsMLWoMGGSz8/NYXv9cXY1nzrnfaH+gcylPgBJKFE7P8CY/Ai3VEzmpzvep60zena72oizR6LffW6OkRcxWjuj5BhEe1029LtPD0PpA9A3gJDo+2m+51Nbou1L517KXz779nkXf4BxhXl86655/Z5PMl/f0UE9v9+br5rE4tUbOdnWdU751s5u/uan7/T7frrQdglWUt8AzOw24NtABPieu6/us9/i+28HzgD/w91fS+bYRAqmzPbKB/8xqTfPUPal+/lS/VyJPtEV5kX4bzeU8cy2elp7fZLPsdi/rg82nfteAPas/tRAv0LJUjNXPkt/V4w5k8eyq/k0Xb2+HnzwPms47/3X860hG//mgjhf9bf/F+0H3zu/B/8CBkwAZhYB3gVuAeqBrcDd7v52rzK3A39ILAEsAL7t7guSOTaRgimzfcoXvjXgmwdIeGG70L50P99gn2tUXg7f+K0Kog5//pO3z2mWKcjN4YuLZ/B0dT1HT3f0W999jSmIUJAbSXhMWVEhv1p5c9LnkuyyePXGhP0DY/IjtHdFz7n4D2TimHzuWTidR3+xi/Zenzh63tM5lsOfbnjrvKbGoP/m0vV8Bx9/aFgSwCLgG+6+JP54FYC7P9yrzD8CLz9hEiYAAARUSURBVLn7v8cf1wIfB2YMdGwiPQnggnHF/08U/YX2Zer5RpIBf/fb1/X7ZtRX9/Dq79vkw3fM5Y9+8Hpav6chff++U3G+oSSAZPoAyoADvR7XE/uUP1CZsiSPBcDM7gPuA8gpHMfBxx9KIjRJhnd3dVgkN//8HXDe3A3x8p/9673bcwrHFUfGFpdZJDffu7s6uk8dbfjsX57ofxjQ8CoBDgf03Okm0Lro732RVzpj7mDfZwnLy5B0HR/8tOvJJIBEGaVvMuqvTDLHxja6rwXWAphZdfuZ44Pqzc5WZlY92J79bKR6+IDq4gOqiw+Y2aCHTiaTAOqBab0elwONSZbJT+JYEREJQDJ3Am8FZpvZTDPLB+4CNvQpswG412IWAsfd/WCSx4qISAAG/Abg7l1m9gBQRWwo52PuvsPM7o/vfxR4jtgIoDpiw0C/eKFjk4hr7VBeTJZSXcSoHj6guviA6uIDg66LtLwTWEREhp8mgxMRCSklABGRkEqrBGBmt5lZrZnVmdnKoOMZSWb2mJk1mdlbvbYVm9kLZvZe/P8JQcY4Usxsmpn93Mx2mtkOM3swvj109WFmo8xsi5m9Ea+L/xvfHrq6gNjMBGZWY2Y/iT8OZT0AmNleM9tuZq/3DAEdbH2kTQKITxvxCLAUqADuNrOKYKMaUf8C3NZn20rgRXefDbwYfxwGXcBX3P0qYCHwpfh7IYz10Q7c7O7XAtcBt8VH2oWxLgAeBHb2ehzWeujxm+5+Xa97IQZVH2mTAID5QJ2773b3DuApYFnAMY0Yd/8l0Pcu22XA4/GfHweWj2hQAXH3gz2TCbr7SWJ/8GWEsD485lT8YV78nxPCujCzcuBTwPd6bQ5dPQxgUPWRTgmgv+kkwmxy/H4K4v9PCjieEWdmM4B5wGZCWh/xZo/XgSbgBXcPa118C/ga0Huu2jDWQw8HnjezbfGpdGCQ9ZFO6wEkPW2EhIOZjQWeAR5y9xOJ1qoNA3fvBq4zsyLgR2b24aBjGmlm9mmgyd23mdnHg44nTSx290YzmwS8YGbvDPYE6fQNIJkpJ8LmkJlNAYj/P/jZnjKUmeURu/g/6e7r4ptDWx8A7t4CvESsryhsdbEY+IyZ7SXWPHyzmf0b4auHs9y9Mf5/E/AjYs3og6qPdEoAmjbifBuAL8R//gLw4wBjGTHxBYa+D+x092/22hW6+jCz0vgnf8ysEPgk8A4hqwt3X+Xu5e4+g9i1YaO730PI6qGHmY0xs0t6fgZuBd5ikPWRVncCxxeW+RYfTBvxVwGHNGLM7N+JraFQAhwC/gxYDzwNXAbsB+5096CmYx4xZnYT8DKwnQ/ae79OrB8gVPVhZtcQ68yLEPvA9rS7/7mZTSRkddEj3gT0VXf/dFjrwcwuJ/apH2JN+f/P3f9qsPWRVglARERGTjo1AYmIyAhSAhARCSklABGRkFICEBEJKSUAEZGQUgIQEQkpJQARkZD6/7yFuDrmpYduAAAAAElFTkSuQmCC\n", 83 | "text/plain": [ 84 | "
" 85 | ] 86 | }, 87 | "metadata": { 88 | "needs_background": "light" 89 | }, 90 | "output_type": "display_data" 91 | } 92 | ], 93 | "source": [ 94 | "# import packages with the functions we need\n", 95 | "import scipy.special\n", 96 | "import matplotlib.pyplot as plt\n", 97 | "\n", 98 | "probabilities = []\n", 99 | "\n", 100 | "for n in range(51):\n", 101 | " # calculate probability of n heads\n", 102 | " probability = scipy.special.binom(50, n) / (2 ** 50)\n", 103 | "\n", 104 | " # convert to a string with 6 decimal places\n", 105 | " probString = \"{:.6f}\".format(probability)\n", 106 | "\n", 107 | " # print probability\n", 108 | " print('Probability of ' + str(n) + ' heads: ' + probString)\n", 109 | "\n", 110 | " # add probability to list\n", 111 | " probabilities.append(probability)\n", 112 | "\n", 113 | "# plot the probabilites\n", 114 | "plt.plot(range(51), probabilities, '-o')\n", 115 | "plt.axis([0, 50, 0, 0.15])\n", 116 | "plt.show()" 117 | ] 118 | } 119 | ], 120 | "metadata": { 121 | "kernelspec": { 122 | "display_name": "Python 3.7 (DL)", 123 | "language": "python", 124 | "name": "dl" 125 | }, 126 | "language_info": { 127 | "codemirror_mode": { 128 | "name": "ipython", 129 | "version": 3 130 | }, 131 | "file_extension": ".py", 132 | "mimetype": "text/x-python", 133 | "name": "python", 134 | "nbconvert_exporter": "python", 135 | "pygments_lexer": "ipython3", 136 | "version": "3.7.7" 137 | } 138 | }, 139 | "nbformat": 4, 140 | "nbformat_minor": 4 141 | } 142 | -------------------------------------------------------------------------------- /Chapter 05 - Elements of Discrete Probability/.ipynb_checkpoints/Chapter5-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Chapter 5 - Elements of Discrete Mathematics\n", 8 | "\n", 9 | "This notebook contains code accompanying Chapter 5 Elements of Discrete Mathematics in *Practical Discrete Mathematics* by Ryan T. White and Archana Tikayat Ray.\n", 10 | "\n", 11 | "## The Basics of Discrete Probability\n", 12 | "\n", 13 | "### Example: Tossing Many Coins\n", 14 | "\n", 15 | "The code below computes the probability of getting $k=0$, $k=1$, ..., $k=50$ heads in 50 coin tosses of fair coins. These are binomial probabilities." 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 2, 21 | "metadata": {}, 22 | "outputs": [ 23 | { 24 | "name": "stdout", 25 | "output_type": "stream", 26 | "text": [ 27 | "Probability of 0 heads: 0.000000\n", 28 | "Probability of 1 heads: 0.000000\n", 29 | "Probability of 2 heads: 0.000000\n", 30 | "Probability of 3 heads: 0.000000\n", 31 | "Probability of 4 heads: 0.000000\n", 32 | "Probability of 5 heads: 0.000000\n", 33 | "Probability of 6 heads: 0.000000\n", 34 | "Probability of 7 heads: 0.000000\n", 35 | "Probability of 8 heads: 0.000000\n", 36 | "Probability of 9 heads: 0.000002\n", 37 | "Probability of 10 heads: 0.000009\n", 38 | "Probability of 11 heads: 0.000033\n", 39 | "Probability of 12 heads: 0.000108\n", 40 | "Probability of 13 heads: 0.000315\n", 41 | "Probability of 14 heads: 0.000833\n", 42 | "Probability of 15 heads: 0.001999\n", 43 | "Probability of 16 heads: 0.004373\n", 44 | "Probability of 17 heads: 0.008746\n", 45 | "Probability of 18 heads: 0.016035\n", 46 | "Probability of 19 heads: 0.027006\n", 47 | "Probability of 20 heads: 0.041859\n", 48 | "Probability of 21 heads: 0.059799\n", 49 | "Probability of 22 heads: 0.078826\n", 50 | "Probability of 23 heads: 0.095962\n", 51 | "Probability of 24 heads: 0.107957\n", 52 | "Probability of 25 heads: 0.112275\n", 53 | "Probability of 26 heads: 0.107957\n", 54 | "Probability of 27 heads: 0.095962\n", 55 | "Probability of 28 heads: 0.078826\n", 56 | "Probability of 29 heads: 0.059799\n", 57 | "Probability of 30 heads: 0.041859\n", 58 | "Probability of 31 heads: 0.027006\n", 59 | "Probability of 32 heads: 0.016035\n", 60 | "Probability of 33 heads: 0.008746\n", 61 | "Probability of 34 heads: 0.004373\n", 62 | "Probability of 35 heads: 0.001999\n", 63 | "Probability of 36 heads: 0.000833\n", 64 | "Probability of 37 heads: 0.000315\n", 65 | "Probability of 38 heads: 0.000108\n", 66 | "Probability of 39 heads: 0.000033\n", 67 | "Probability of 40 heads: 0.000009\n", 68 | "Probability of 41 heads: 0.000002\n", 69 | "Probability of 42 heads: 0.000000\n", 70 | "Probability of 43 heads: 0.000000\n", 71 | "Probability of 44 heads: 0.000000\n", 72 | "Probability of 45 heads: 0.000000\n", 73 | "Probability of 46 heads: 0.000000\n", 74 | "Probability of 47 heads: 0.000000\n", 75 | "Probability of 48 heads: 0.000000\n", 76 | "Probability of 49 heads: 0.000000\n", 77 | "Probability of 50 heads: 0.000000\n" 78 | ] 79 | }, 80 | { 81 | "data": { 82 | "image/png": "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\n", 83 | "text/plain": [ 84 | "
" 85 | ] 86 | }, 87 | "metadata": { 88 | "needs_background": "light" 89 | }, 90 | "output_type": "display_data" 91 | } 92 | ], 93 | "source": [ 94 | "# import packages with the functions we need\n", 95 | "import scipy.special\n", 96 | "import matplotlib.pyplot as plt\n", 97 | "\n", 98 | "probabilities = []\n", 99 | "\n", 100 | "for n in range(51):\n", 101 | " # calculate probability of n heads\n", 102 | " probability = scipy.special.binom(50, n) / (2 ** 50)\n", 103 | "\n", 104 | " # convert to a string with 6 decimal places\n", 105 | " probString = \"{:.6f}\".format(probability)\n", 106 | "\n", 107 | " # print probability\n", 108 | " print('Probability of ' + str(n) + ' heads: ' + probString)\n", 109 | "\n", 110 | " # add probability to list\n", 111 | " probabilities.append(probability)\n", 112 | "\n", 113 | "# plot the probabilites\n", 114 | "plt.plot(range(51), probabilities, '-o')\n", 115 | "plt.axis([0, 50, 0, 0.15])\n", 116 | "plt.show()" 117 | ] 118 | } 119 | ], 120 | "metadata": { 121 | "kernelspec": { 122 | "display_name": "Python 3.7 (DL)", 123 | "language": "python", 124 | "name": "dl" 125 | }, 126 | "language_info": { 127 | "codemirror_mode": { 128 | "name": "ipython", 129 | "version": 3 130 | }, 131 | "file_extension": ".py", 132 | "mimetype": "text/x-python", 133 | "name": "python", 134 | "nbconvert_exporter": "python", 135 | "pygments_lexer": "ipython3", 136 | "version": "3.7.7" 137 | } 138 | }, 139 | "nbformat": 4, 140 | "nbformat_minor": 4 141 | } 142 | -------------------------------------------------------------------------------- /Chapter 09 - Searching Data Structures and Finding Shortest Paths/Chapter9.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Chapter 9 - Searching Data Structures and Finding Shortest Paths\n", 8 | "\n", 9 | "This notebook contains code accompanying Chapter 9 Searching Data Structures and Finding Shortest Paths in *Practical Discrete Mathematics* by Ryan T. White and Archana Tikayat Ray\n", 10 | "\n", 11 | "For most of the code in the chapter, we need to import the `NumPy` library." 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 1, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "import numpy" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "## A Python Implementation of DFS" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 2, 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "# Depth First Search\n", 37 | "# \n", 38 | "# INPUTS\n", 39 | "# A - an adjacency matrix. It should be square, symmetric, and binary\n", 40 | "# source - the number of the source vertex\n", 41 | "#\n", 42 | "# OUTPUTS\n", 43 | "# vertexList - an ordered list of vertices found in the search\n", 44 | "\n", 45 | "def DFS(A, source):\n", 46 | " # reduce the source by 1 to avoid off-by-1 errors\n", 47 | " source -= 1\n", 48 | " \n", 49 | " # find the number of vertices\n", 50 | " n = A.shape[0]\n", 51 | " \n", 52 | " # initialize the unvisited vertex set to be full\n", 53 | " unvisited = [1] * n\n", 54 | " \n", 55 | " # initialize a queue with the source vertex\n", 56 | " stack = [source]\n", 57 | " \n", 58 | " # initialize the vertex list\n", 59 | " vertexList = []\n", 60 | " \n", 61 | " # while the stack is not empty\n", 62 | " while stack:\n", 63 | " # remove the just-visited vertex from the stack and store it\n", 64 | " v = stack.pop()\n", 65 | " \n", 66 | " # if v is unvisited, add it to our list and mark it as visited\n", 67 | " if unvisited[v]:\n", 68 | " # save and print the number of the newly visited vertex\n", 69 | " vertexList.append(v)\n", 70 | " \n", 71 | " # mark the vertex as visited\n", 72 | " unvisited[v] = 0\n", 73 | "\n", 74 | " # iterate through the vertices\n", 75 | " for u in range(n - 1, 0, -1):\n", 76 | " # add each unvisited neighbor to the stack\n", 77 | " if A[v,u] == 1 and unvisited[u] == 1:\n", 78 | " stack.append(u)\n", 79 | " \n", 80 | " # return the vertex list found by DFS\n", 81 | " return vertexList" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "Let's save the adjacency matrix for the graph in Figure 9.1." 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 3, 94 | "metadata": {}, 95 | "outputs": [], 96 | "source": [ 97 | "# Save the adjacency matrix for the graph in Figure 9.1\n", 98 | "A = numpy.array([[0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0],\n", 99 | " [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n", 100 | " [0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0],\n", 101 | " [0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0],\n", 102 | " [1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0],\n", 103 | " [0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0],\n", 104 | " [0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0],\n", 105 | " [0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0],\n", 106 | " [0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0],\n", 107 | " [0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],\n", 108 | " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])" 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": {}, 114 | "source": [ 115 | "Next, let's run DFS on the graph starting with source vertex 1." 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 4, 121 | "metadata": {}, 122 | "outputs": [ 123 | { 124 | "data": { 125 | "text/plain": [ 126 | "[1, 2, 5, 4, 3, 6, 7, 8, 9, 10]" 127 | ] 128 | }, 129 | "execution_count": 4, 130 | "metadata": {}, 131 | "output_type": "execute_result" 132 | } 133 | ], 134 | "source": [ 135 | "# Run DFS on the graph with adjacency matrix A and source 1\n", 136 | "vertexList = DFS(A,1)\n", 137 | "\n", 138 | "# Add 1 to the vertex numbers\n", 139 | "[x + 1 for x in vertexList]" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "## Shortest Paths on Networks\n", 147 | "\n", 148 | "The following function checks if a path exists between vertex i and vertex j." 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": 5, 154 | "metadata": {}, 155 | "outputs": [], 156 | "source": [ 157 | "# create a function that returns True if vertex i and vertex j are\n", 158 | "# connected in the graph represented by the input adjacency matrix A\n", 159 | "def isConnected(A, i, j):\n", 160 | " # initialize the paths matrix to adjacency matrix A\n", 161 | " paths = A\n", 162 | " \n", 163 | " # find the number of vertices in the graph\n", 164 | " numberOfVertices = A.shape[0]\n", 165 | " \n", 166 | " # find the number of edges in the graph\n", 167 | " numberOfEdges = numpy.sum(A)/2\n", 168 | "\n", 169 | " # if vi and vj are adjacent, return True\n", 170 | " if paths[i-1][j-1] > 0:\n", 171 | " print('Vertex', i, 'and vertex', j, 'are adjacent')\n", 172 | " return True\n", 173 | "\n", 174 | " else:\n", 175 | " # run the loop until we find a path\n", 176 | " for pathLength in range(2, numberOfVertices):\n", 177 | " # exponentiate the adjacency matrix\n", 178 | " paths = numpy.dot(paths, A)\n", 179 | " \n", 180 | " # if the element in row i, column j is more than 0, we\n", 181 | " # found a path\n", 182 | " if paths[i-1][j-1] > 0:\n", 183 | " print('There is a path with', pathLength,\n", 184 | " 'edges from vertex', i, 'to vertex', j)\n", 185 | " return True\n", 186 | "\n", 187 | " # found no paths, the vertices are not connected\n", 188 | " if pathLength == numberOfEdges:\n", 189 | " print('There are no paths from vertex', i, 'to vertex', j)\n", 190 | " return False" 191 | ] 192 | }, 193 | { 194 | "cell_type": "markdown", 195 | "metadata": {}, 196 | "source": [ 197 | "Let's create adjacency matrices for the graphs in Figure 9.6 and test our function." 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": 6, 203 | "metadata": {}, 204 | "outputs": [ 205 | { 206 | "name": "stdout", 207 | "output_type": "stream", 208 | "text": [ 209 | "There is a path with 2 edges from vertex 1 to vertex 4\n", 210 | "True\n", 211 | "Vertex 2 and vertex 3 are adjacent\n", 212 | "True\n", 213 | "There is a path with 3 edges from vertex 5 to vertex 6\n", 214 | "True\n", 215 | "There is a path with 2 edges from vertex 1 to vertex 6\n", 216 | "True\n", 217 | "There are no paths from vertex 2 to vertex 5\n", 218 | "False\n", 219 | "There are no paths from vertex 1 to vertex 4\n", 220 | "False\n" 221 | ] 222 | } 223 | ], 224 | "source": [ 225 | "# create an adjacency matrix for the graph G1\n", 226 | "A1 = numpy.array([[0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1],\n", 227 | " [1, 1, 0, 1, 1, 0], [0, 1, 1, 0, 1, 0],\n", 228 | " [1, 0, 1, 1, 0, 0], [0, 1, 0, 0, 0, 0]])\n", 229 | "\n", 230 | "# check if various vertices are connected\n", 231 | "print(isConnected(A1, 1, 4))\n", 232 | "print(isConnected(A1, 2, 3))\n", 233 | "print(isConnected(A1, 5, 6))\n", 234 | "\n", 235 | "# create an adjacency matrix for graph G2\n", 236 | "A2 = numpy.array([[0, 1, 0, 0, 0, 0], [1, 0, 0, 0, 0, 1],\n", 237 | " [0, 0, 0, 1, 1, 0], [0, 0, 1, 0, 1, 0],\n", 238 | " [0, 0, 1, 1, 0, 0], [0, 1, 0, 0, 0, 0]])\n", 239 | "\n", 240 | "print(isConnected(A2, 1, 6))\n", 241 | "print(isConnected(A2, 2, 5))\n", 242 | "print(isConnected(A2, 1, 4))" 243 | ] 244 | }, 245 | { 246 | "cell_type": "markdown", 247 | "metadata": {}, 248 | "source": [ 249 | "## Python Implementation of Dijkstra’s Algorithm\n", 250 | "\n" 251 | ] 252 | }, 253 | { 254 | "cell_type": "code", 255 | "execution_count": 7, 256 | "metadata": {}, 257 | "outputs": [], 258 | "source": [ 259 | "import numpy\n", 260 | "\n", 261 | "# Dijkstra's algorithm for finding shortest paths from the source\n", 262 | "# vertex to all other vertices in the graph\n", 263 | "# \n", 264 | "# INPUTS\n", 265 | "# W - a weight matrix. It should be a square matrix\n", 266 | "# i - the number of the source node\n", 267 | "#\n", 268 | "# OUTPUTS\n", 269 | "# shortestDistances - the shortest distances from the source to each\n", 270 | "# vertex\n", 271 | "# previousVertices - the previous vertex to the destination in a \n", 272 | "# shortest path from the source to a destination\n", 273 | "def Dijkstra(W, i):\n", 274 | " # find the number of vertices\n", 275 | " n = W.shape[0]\n", 276 | " \n", 277 | " # initialize the shortest distances to infinity\n", 278 | " shortestDistances = numpy.array([numpy.inf] * n)\n", 279 | " \n", 280 | " # initialize the previous vertices\n", 281 | " previousVertices = numpy.array([numpy.inf] * n)\n", 282 | " \n", 283 | " # initialize the unvisited vertex set to be full\n", 284 | " unvisited = numpy.array([1] * n)\n", 285 | " \n", 286 | " # mark the source as visited\n", 287 | " unvisited[i - 1] = 0\n", 288 | " \n", 289 | " # initialize distance from the source to the source as 0\n", 290 | " shortestDistances[i - 1] = 0\n", 291 | " \n", 292 | " # loop for iteration per vertex until the unvisited set is empty\n", 293 | " for _ in range(n):\n", 294 | " # find the distances to all unvisited adjacent vertices and\n", 295 | " # set others to 0\n", 296 | " distances = shortestDistances * unvisited\n", 297 | " \n", 298 | " # find the index of the nearest unvisited vertex (where\n", 299 | " # distances > 0)\n", 300 | " x = numpy.argmin(numpy.ma.masked_where(\n", 301 | " distances == 0, distances))\n", 302 | " \n", 303 | " # mark vertex x as visited\n", 304 | " unvisited[x] = 0\n", 305 | "\n", 306 | " # iterate through the vertices\n", 307 | " for v in range(n):\n", 308 | " \n", 309 | " oldDistance = shortestDistances[v]\n", 310 | " newDistance = shortestDistances[x] + W[v,x]\n", 311 | " adjacent = W[v,x] > 0\n", 312 | " unvis = unvisited[v]\n", 313 | " \n", 314 | " # if v and x are connected, v has not been visited, and we\n", 315 | " # find a shorter distance to node v...\n", 316 | " if adjacent and unvis and oldDistance > newDistance:\n", 317 | " # save the shortest distance found so far\n", 318 | " shortestDistances[v] = shortestDistances[x] + W[v,x]\n", 319 | " \n", 320 | " # save the previous vertex\n", 321 | " previousVertices[v] = x \n", 322 | "\n", 323 | " # print the table similar to the book\n", 324 | " print(numpy.array([numpy.arange(n) + 1, shortestDistances, \n", 325 | " previousVertices + 1]).T) \n", 326 | " # return the outputs\n", 327 | " return shortestDistances, previousVertices\n" 328 | ] 329 | }, 330 | { 331 | "cell_type": "markdown", 332 | "metadata": {}, 333 | "source": [ 334 | "Let's create the weight matrix for the network in Figure 9.15 and run Dijkstra's algorithms to find the shortest paths from $v_1$ to all other vertices." 335 | ] 336 | }, 337 | { 338 | "cell_type": "code", 339 | "execution_count": 8, 340 | "metadata": {}, 341 | "outputs": [ 342 | { 343 | "name": "stdout", 344 | "output_type": "stream", 345 | "text": [ 346 | "[[ 1. 0. inf]\n", 347 | " [ 2. 3. 3.]\n", 348 | " [ 3. 1. 1.]\n", 349 | " [ 4. 2. 3.]\n", 350 | " [ 5. 2. 1.]\n", 351 | " [ 6. 4. 2.]]\n" 352 | ] 353 | } 354 | ], 355 | "source": [ 356 | "# Create a weight matrix for the network in Figure 9.15\n", 357 | "W1 = numpy.array([[0, 4, 1, 0, 2, 0],\n", 358 | " [4, 0, 2, 1, 0, 1],\n", 359 | " [1, 2, 0, 1, 1, 0],\n", 360 | " [0, 1, 1, 0, 2, 0],\n", 361 | " [2, 0, 1, 2, 0, 0],\n", 362 | " [0, 1, 0, 0, 0, 0]])\n", 363 | "\n", 364 | "# Run Dijkstra's algorithm with a source at vertex v1\n", 365 | "shortestDistances, previousVertices = Dijkstra(W1, 1)" 366 | ] 367 | }, 368 | { 369 | "cell_type": "markdown", 370 | "metadata": {}, 371 | "source": [ 372 | "Next, we write a function to clean up the outputs and display the paths" 373 | ] 374 | }, 375 | { 376 | "cell_type": "code", 377 | "execution_count": 9, 378 | "metadata": {}, 379 | "outputs": [], 380 | "source": [ 381 | "# Use the previousVertices chart to construct the shortest path from\n", 382 | "# input source to input destination and print a string showing\n", 383 | "# showing the path\n", 384 | "\n", 385 | "def printShortestPath(shortestDistances, previousVertices, source,\n", 386 | " destination):\n", 387 | " # avoid off-by-one error\n", 388 | " source -= 1\n", 389 | " destination -= 1\n", 390 | " \n", 391 | " # convert previousVertices to integers\n", 392 | " previousVertices = previousVertices.astype(int)\n", 393 | " \n", 394 | " # initialize the path with the destination\n", 395 | " path = [destination]\n", 396 | " \n", 397 | " # add the previous vertex from previousVertices until we reach\n", 398 | " # the source\n", 399 | " for _ in range(previousVertices.shape[0] - 1):\n", 400 | " # if the source is in the path, stop\n", 401 | " if path[-1] == source:\n", 402 | " break\n", 403 | " # if the source is not in the path, add the previous vertex\n", 404 | " else:\n", 405 | " path.append(previousVertices[path[-1]])\n", 406 | "\n", 407 | " # initialize an output string\n", 408 | " output = []\n", 409 | " \n", 410 | " # iterate through the path backwards (source to destination)\n", 411 | " for i in numpy.flip(path):\n", 412 | " # construct a list of strings to output\n", 413 | " if i > 0:\n", 414 | " output.append('->')\n", 415 | " \n", 416 | " output.append('v' + str(i + 1))\n", 417 | " \n", 418 | " # print the strings with no spaces\n", 419 | " print('Path =', *output, '\\t\\t Distance =',\n", 420 | " shortestDistances[destination])" 421 | ] 422 | }, 423 | { 424 | "cell_type": "markdown", 425 | "metadata": {}, 426 | "source": [ 427 | "And, we run it to find:" 428 | ] 429 | }, 430 | { 431 | "cell_type": "code", 432 | "execution_count": 10, 433 | "metadata": {}, 434 | "outputs": [ 435 | { 436 | "name": "stdout", 437 | "output_type": "stream", 438 | "text": [ 439 | "Path = v1 -> v3 -> v2 \t\t Distance = 3.0\n", 440 | "Path = v1 -> v3 \t\t Distance = 1.0\n", 441 | "Path = v1 -> v3 -> v4 \t\t Distance = 2.0\n", 442 | "Path = v1 -> v5 \t\t Distance = 2.0\n", 443 | "Path = v1 -> v3 -> v2 -> v6 \t\t Distance = 4.0\n" 444 | ] 445 | } 446 | ], 447 | "source": [ 448 | "for i in range(2,7):\n", 449 | " printShortestPath(shortestDistances, previousVertices, 1, i)" 450 | ] 451 | }, 452 | { 453 | "cell_type": "markdown", 454 | "metadata": {}, 455 | "source": [ 456 | "Next, we try a network that we know is not connected. First, we will check if the vertices in question are connected." 457 | ] 458 | }, 459 | { 460 | "cell_type": "code", 461 | "execution_count": 11, 462 | "metadata": {}, 463 | "outputs": [], 464 | "source": [ 465 | "# find the shortest paths to connected vertices\n", 466 | "def distancesWithinComponent(source):\n", 467 | " # initialize the connected component\n", 468 | " component = [source]\n", 469 | "\n", 470 | " # construct the connected component\n", 471 | " for i in range(1, W2.shape[0] + 1):\n", 472 | " if i != source and isConnected(W2, source, i):\n", 473 | " component.append(i)\n", 474 | "\n", 475 | " # find the weight matrix correponding to the connected component\n", 476 | " subnetwork = W2[numpy.array(component) - 1,:][:,numpy.array(component) - 1]\n", 477 | "\n", 478 | " # run Dijkstra's algorithm\n", 479 | " return Dijkstra(subnetwork, 1)\n", 480 | "\n" 481 | ] 482 | }, 483 | { 484 | "cell_type": "markdown", 485 | "metadata": {}, 486 | "source": [ 487 | "Let's find the paths from $v_1$." 488 | ] 489 | }, 490 | { 491 | "cell_type": "code", 492 | "execution_count": 12, 493 | "metadata": {}, 494 | "outputs": [ 495 | { 496 | "name": "stdout", 497 | "output_type": "stream", 498 | "text": [ 499 | "Vertex 1 and vertex 2 are adjacent\n", 500 | "There is a path with 2 edges from vertex 1 to vertex 6\n", 501 | "[[ 1. 0. inf]\n", 502 | " [ 2. 4. 1.]\n", 503 | " [ 3. 5. 2.]]\n" 504 | ] 505 | }, 506 | { 507 | "data": { 508 | "text/plain": [ 509 | "(array([0., 4., 5.]), array([inf, 0., 1.]))" 510 | ] 511 | }, 512 | "execution_count": 12, 513 | "metadata": {}, 514 | "output_type": "execute_result" 515 | } 516 | ], 517 | "source": [ 518 | "# Create a weight matrix for the network in Figure 9.16\n", 519 | "W2 = numpy.array([[0, 4, 0, 0, 0, 0],\n", 520 | " [4, 0, 0, 0, 0, 1],\n", 521 | " [0, 0, 0, 1, 4, 0],\n", 522 | " [0, 0, 1, 0, 2, 0],\n", 523 | " [0, 0, 4, 2, 0, 0],\n", 524 | " [0, 1, 0, 0, 0, 0]])\n", 525 | "\n", 526 | "distancesWithinComponent(1)" 527 | ] 528 | }, 529 | { 530 | "cell_type": "markdown", 531 | "metadata": {}, 532 | "source": [ 533 | "Let's find the paths from $v_3$." 534 | ] 535 | }, 536 | { 537 | "cell_type": "code", 538 | "execution_count": 13, 539 | "metadata": {}, 540 | "outputs": [ 541 | { 542 | "name": "stdout", 543 | "output_type": "stream", 544 | "text": [ 545 | "Vertex 3 and vertex 4 are adjacent\n", 546 | "Vertex 3 and vertex 5 are adjacent\n", 547 | "[[ 1. 0. inf]\n", 548 | " [ 2. 1. 1.]\n", 549 | " [ 3. 3. 2.]]\n" 550 | ] 551 | }, 552 | { 553 | "data": { 554 | "text/plain": [ 555 | "(array([0., 1., 3.]), array([inf, 0., 1.]))" 556 | ] 557 | }, 558 | "execution_count": 13, 559 | "metadata": {}, 560 | "output_type": "execute_result" 561 | } 562 | ], 563 | "source": [ 564 | "distancesWithinComponent(3)" 565 | ] 566 | } 567 | ], 568 | "metadata": { 569 | "kernelspec": { 570 | "display_name": "Python 3.7 (DL)", 571 | "language": "python", 572 | "name": "dl" 573 | }, 574 | "language_info": { 575 | "codemirror_mode": { 576 | "name": "ipython", 577 | "version": 3 578 | }, 579 | "file_extension": ".py", 580 | "mimetype": "text/x-python", 581 | "name": "python", 582 | "nbconvert_exporter": "python", 583 | "pygments_lexer": "ipython3", 584 | "version": "3.7.7" 585 | } 586 | }, 587 | "nbformat": 4, 588 | "nbformat_minor": 4 589 | } 590 | --------------------------------------------------------------------------------