0% found this document useful (0 votes)
2 views

Python and Mathematics (1)

The document introduces programming concepts using Python, specifically tailored for mathematicians, covering basic terms, variables, statements, operators, and expressions. It also discusses debugging common errors like syntax, type, name, and indentation errors, along with examples. Additionally, it explains sequential programming and provides examples of calculating areas using user input.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Python and Mathematics (1)

The document introduces programming concepts using Python, specifically tailored for mathematicians, covering basic terms, variables, statements, operators, and expressions. It also discusses debugging common errors like syntax, type, name, and indentation errors, along with examples. Additionally, it explains sequential programming and provides examples of calculating areas using user input.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 48

Python and Mathematics

Donnie Munyao Kasyoki

April 13, 2025

1 INTRODUCTION TO PROGRAMMING

1.1 Basic concepts of Programming


A program is a set of instructions that tell a computer how to perform a task. Programming
is the process of writing instructions for a computer to follow, (or the process of writing code
to perform a computation). A computation doesn't have to be arithmetic. But since this
course is designed for mathematicians only, let's just stop at that.
Now that we know what programming is, let us take a look at some terms that are going to
be useful to the reader of this work.
Python is a high-level language, just like C, C++, java, etc. The computer needs an inter-
preter to convert it to a lowlevel language that a computer can execute.

1.1.1 Basic terms


Value A value is the most basic piece of data that can be stored and manipulated by a
program. There are several types of value that we are going to come across so we may as
well take a look as the most basic types.
int  numbers with no fractional parts, e.g., 1, 0, 10, 1327, etc.
oat  numbers with fractional part, e.g., 1.0, 0.91, 1034.2, etc.
str  a sequence of characters, e.g., `Hello', World, `2.3', `7'.
bool  True or False.
Other types that we will come across include: list, dictionary, tuple, set, range, etc.
[1]: type(10) #is an inbuilt function to check the type of a given value

[1]: int

[2]: type('90')

[2]: str

1
Python and Mathematics by Donnie M. Kasyoki

Variable A variable is a name that stores a value. In order to be able to store values and
reuse them in our program, we need to give these values names that can be memorised by
the programmer. There are some basic rules that govern the naming of these variables. A
variable name should not:-
Start with a digit. A variable name should always start with a letter or underscore for
some reason. May include digits if the user chooses to do so. For instance 1name, name,
namedate, etc are not valid variables while name, name1, _name are all valid.
Include special characters like @, #, $, %, , &, *, (, etc. The only character permitted is
the underscore.
Include spaces  Use an underscore of capitalization of rst letter of the subsequent names
if you want to a variable with multiple names. For instance rst name is not valid, instead
you can write rstName, rst_name, etc.
Although some naming may not give rise to errors, it doesn't mean it is a good practice.
In python we have several key words that are well preserved for the language and have a
meaning in the language. For example the word `print' is preserved for giving output. We
will come across most of these keywords but we may list a few. They include: print, for, if,
in, from, import, list, set, try, except, dict, etc. If a variable is named after these keywords
then it overwrites its functions and you wont be able to use the functionality of the keyword
in that particular program.

Example If we rename print and give is a value, say 10, then printing will result into an
error as swown below.

[3]: print = 10
print('Hello World!')

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[34], line 2
1 print = 10
----> 2 print('Hello World!')

TypeError: 'int' object is not callable

[4]: firstName = 'Donnie'#firstName if the variable that stores the str value
,→'Donnie'

Statement A statement refers to a single line of code that instructs the computer how to
perform a specic task. Some examples of statements that we will encounter include: print
statement, assignment statement, if statements, etc.

2
Python and Mathematics by Donnie M. Kasyoki

[5]: print('Hello World!') # A print statement - will give an output


h = 10 #An assignment statement - will not give an output just assigning

Hello World!

Operator An operator is a special symbol that is used to perform operations on variables


and values. There are many types of operators used in programming and they include:
Arithmetic operators - used with numeric values to perform common mathematical oper-
ations, e.g., + for addition, - for subtraction, * for multiplication, / for division, ** for
exponentiation, % for division modulo, // for oor division, etc. Some of these operators
can be used with strings but the operations they perform is not arithmetic. For instance,
addition of strings implies concatenation. `Hello' + ' ' + `World!' = `Hello World'. However
additing strings to numerals is not a valid operation. The asteric can also be used on str
values but with an int value and not any other type of value. It replicates a str value a
certain number (the int) of copies. For instance, `10.0'*3 = `10.310.310.3'.

Assignment operators are used to assign values to variables. They include: =, +=, -=, /=,
*=, **=, etc. An equal sign preceeded by an arithmetic operator is used for reassignment
which means the variable must have existed before reassigning it. These reassignment op-
erators are used just to avoid repeting the specic variable name. We will consider some
examples below.
Comparison operators are used to compare two values. E.g. == for comparing equality, !=
for checking non-equality, > for greater than, < for less than, <= for less than or equal to,
>= for greater than or equal to.

Logical operators are used to combine conditional statements. E.g. and, or, not.
There other types of operators that you may want to research on.

[6]: #Arithmetic
print(25 % 7) #Gives the remainder when 25 is divided by 7. Used to test
,→for divisibility.

print(25 // 7) #Gives the largest whole number that can be multiplied to


,→7 to give or be less than 25.

4
3
[7]: #Assinment
n = 10; h = 'Hello' #assigns values to variables
n += 5 #Equivalent to n = n + 5
print(n)

15

3
Python and Mathematics by Donnie M. Kasyoki

[8]: #Comparison
print(10 == 10) #this is True
print(10 < 10) #this is False
print(10 <= 10) #this is True

True
False
True
[9]: #Logical
print(10 == 10 or 10 < 10) #Since one of them is True, the whole
,→statement is True

print(10 > 10 or 10 < 10) #is False. None of the statements is True
print(10 == 10 and 10 < 10) #is False. and requires both to be True.

True
False
False

1.1.2 Expressions
An expression is a combination of operarators and operands. Operands could be values or
variables.

Order of operation Arithmetic operators in python just like in mathematics have dier-
ent order of precedence. PEMDAS is a mathematical accronym that is used to summarize
these precedences. PEMDAS stands for Parenthesis, Exponentiation, Multiplication, Divi-
sion, Addition and Subtraction. Multiplication and division have the same precedence and
addition and subtraction as well. So the one that comes rst precedes in the operation.

[10]: print(3-4+5 == (3-4)+5) ## If subtractions comes first then it is done


,→first.

print(3+4-5 == (3+4)-5)

print(4/5*7 == (4/5)*7)

print(4*5/6 == (4*5)/6)

print(5-8/2**3-(1-3)) #=5-8/2**3-(-2)=5-8/(2**3)+2=5-8/8+2=5-(8/
,→8)+2=5-1+2 = 4+2 = 6

True
True
True

4
Python and Mathematics by Donnie M. Kasyoki

True
6.0

Comments When writing codes, it is wise to write short comments as a guide to the user
or even yourself as you work on the code. The comments may be explaining variables or
functionalities of sections of codes. Comments in python start with a # symbol. We can
also write a descriprion of what the program does by writing a much longer comment. Then
comments begin and end with tripple quotation marks when using other python editors. For
jupyter you may want to set the cell to `markdown' rather than `code'. Comments do not
aect the code and are not part of the output.

[11]: #This is a comment and won't appear


print('Hello World!') #This is another comment.

Hello World!

2 Debugging

For some reason errors in a computer program are called bugs. Therefore, the process in
which the programmer identies and corrects these errors is referred to as debugging.
It is therefore very useful to understand the error messages that python shows when it
encounters them. We start by looking at some of these common errors that may arise in a
program.

2.1 Common errors


Syntax error Syntax refers to the rules of the programming language. Therefore, one
obtains this error when they break the rules of the language. For instance we looked at some
of the don'ts of naming variables in python. When one breaks these rules then they end up
getting a syntax error.

Example Using a space when naming a variable.

[12]: first name = 'Donnie'

Cell In[33], line 1


first name = 'Donnie'

SyntaxError: invalid syntax

Type error As the name suggests, this error occurs when the user does an operation
that is not permitted by a certain type of value. We have already gotten this error when

5
Python and Mathematics by Donnie M. Kasyoki

discussing variables. The message was that the type int is not callable. The reason for that
is because int is not a function therefore cannot be called with the parenthesis. Also using
* on a oat and a str will result in the same error. There are many ways in which one can
get these errors.

Example Operation * on a oat and a str.

[13]: .8 * '.7'

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[36], line 1
----> 1 .8 * '.7'

TypeError: can't multiply sequence by non-int of type 'float'

2.1.1 Name error


This error occurs when one calls a variable that is not dened. In most cases one misspells
a variable name, uses dierent cases (lowercase instead of uppercase and vice-versa), when
one is writing a string but forgets to use quotation marks, etc.

Example Using a single uppercase instead of lowercase.

[14]: name = "Donnie Munyao"


print(Name) #This will give a name error

---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[36], line 2
1 name = "Donnie Munyao"
----> 2 print(Name)

NameError: name 'Name' is not defined

Indentation error This error will occur mostly because of inconsistency spacing behind a
statements or expressions. When writing functions (def statements), if, else, elif statements,
class denitions require that the second line be indented and thus missing indent will result
in this type of error.

Example Inconsistent spacing

6
Python and Mathematics by Donnie M. Kasyoki

[15]: n = 10
m = 11
print(n*m)

Cell In[5], line 2


m = 11

IndentationError: unexpected indent

Index error This error occurs when dealing with lists. The items in a list can be called
using an index. The rst item is assigned index 0, the second is index 1, etc. If a list has 5
items, then that means index 5 does not exist and therefore accessing it will result to this
error.

Example Let L be the list L = [1,2,5,0,6]. To access the rst element we call L[0], so
calling L[5] will result in index error.

[16]: L = L = [1,2,5,0,6]
print(L[5])

---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
Cell In[7], line 2
1 L = L = [1,2,5,0,6]
----> 2 print(L[5])

IndexError: list index out of range

Key error This occurs when dealing with dictionaries. In dictionaries, we use keys rather
than indices to refer to items. For example, the dictionary d dened as d = {`name': `Ken',
`gender':`M', `age': 20} has keys `name', `gender', and `age'. Calling any other value or
misspelling a key will result into key error.

Example Using uppercase instead of lowercase for a key.

[17]: d = {'name': 'Ken', 'gender':'M', 'age': 20}


print(d['Name'])

---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
Cell In[9], line 2

7
Python and Mathematics by Donnie M. Kasyoki

1 d = {'name': 'Ken', 'gender':'M', 'age': 20}


----> 2 print(d['Name'])

KeyError: 'Name'

Exercise Research on more errors in python.

3 SEQUENTIAL, CONDITIONAL AND ITERATIVE

FLOWS

3.1 Sequential ow,


Writing a program is more or less the same as preparing a meal. You must prepare the in-
gredients before you begin cooking. In programming you need to set up all the requirements,
then write the code in a way that some variables will not be dened after usage. It is good
practice to dene all the variables before writing expressions.

3.1.1 Basic program


We start with some simple program that does not get any extra input from outside the
program.

All variables given

Example Write a program to calculate the area of a triangle with base 10 units. and
height 20 units.

[18]: '''
Calculating the area of a triangle
'''
base = 10
height = 20
area = 1/2*base*height
print(f"Area: {area} sq. units")

Area: 100.0 sq. units

Variables from the user We can obtain values from the user of the program, we will
therefore use the input function to obtain these data. It is useful to give some direction to
the user.

Example Write a program to calculate the area of a square whose side is provided by the
user.

8
Python and Mathematics by Donnie M. Kasyoki

[19]: side = eval(input('Enter the length of the side: '))


area = side**2
print(f'Area: {area} sq. units')

Enter the length of the side: 10


Area: 100 sq. units

Importing modules or from modules We can borrow some functions or values that
are already dened in installed modules. The most common modules that we will look at
include: math, numpy, sympy, scipy, etc. There are ways that are used to import these
modules into our programs.
The major ways include:
Importing the module
Importing all the elements of the module
Importing specic function(s) and value(s) from the modules

Example Write a program to calculate the area of a circle whose radius is provided by the
user.

[20]: import math # Way 1


radius = eval(input('Enter the radius of the circle: '))
area = math.pi*radius**2
print(f'Area: {area} sq. units')

Enter the radius of the circle: 10


Area: 314.1592653589793 sq. units

Example Write a program to calculate the volume of a cylinder whose dimensions are
provided by the user.

[21]: from math import * # Way 2


radius = eval(input('Enter the radius of the base: '))
height = eval(input('Enter the height: '))
area = pi*radius**2*height
print(f'Area: {area} sq. units')

Enter the radius of the base: 10


Enter the height: 20
Area: 6283.185307179587 sq. units

Exercise

9
Python and Mathematics by Donnie M. Kasyoki

4 CONDITIONAL FLOW

We solve problems that involve some conditions. We are going to incorporate if, elif and else
statements in this section. The if and elif are followed by a boolean expression.

4.1 if statements
Example Write a program that prints the absolute value of a number x input by the user
given that (
x, if x ≥ 0
|x| =
−x, if x < 0

[21]: x = eval(input('Enter a number: '))


if x >= 0:
absx = x
if x < 0:
absx = -x
print(f'|{x}| = {absx}')

Enter a number: -3
|-3| = 3

4.2 Multiple if statements


If one has multiple if statements then python goes through each of the statements and
executes it accordingly. Unlike the cases when one uses elif statements. We now see the
dierence between the two cases but rst we look at an example that entails several true
statements.

Example
[22]: m = 10
if m >= 10: #True
m += 15 # m is now 25
if m > 20: #True
m += 30 #m is now 55
if m > 50: #True
print('Over 50') # Printed
m -= 40 #m is updated to 15
print(m) #prints the value of m = 15

Over 50
15

10
Python and Mathematics by Donnie M. Kasyoki

4.3 elif statements


Unlike if's, when working with elif (else if) once a true condition is encountered, python does
not consider the subsequent elif or else statements.

Example We repeat the above program using if and subsequent elif statements.

[23]: m = 10
if m >= 10: #True
m += 15 # m is now 25
elif m > 20: #Not checked
m += 30 #m not updated
elif m > 50: #Not checked
print('Over 50') # Not printed
m -= 40 #m is not updated
print(m) #prints the value of m = 25

25

Example Write a program to grade a mark entered by the user (between 0-100) following
the grading system given below:
A = 80 ≤ mark ≤ 100
B = 65 ≤ mark < 80
C = 50 ≤ mark < 65
D = 40 ≤ mark < 50
E = 0 ≤ mark < 40

[24]: mark = eval(input('Enter a mark: '))


grade = 'Invalid mark'
if mark < 40:
grade = 'E'
elif mark < 50:
grade = 'D'
elif mark < 65:
grade = 'C'
elif mark < 80:
grade = 'B'
elif mark < 100:
grade = 'A'
print(grade)

Enter a mark: 68
B

11
Python and Mathematics by Donnie M. Kasyoki

4.4 else statements


If no other possibilities that may lead to confusion, then `else' can be used instead of `if' or
`elif'. For instance in the case of absolute value, if a number is not equal or greater than
zero, then that number is denitely less than zero. So instead of writing another if statement
for less than zero, we can just use else.

Example Rewrite a program that prints the absolute value of a number x input by the
user.

[25]: x = eval(input('Enter a number: '))


if x >= 0:
absx = x
else:
absx = -x
print(f'|{x}| = {absx}')

Enter a number: -3
|-3| = 3

Example Write a program to calculate the real roots of a quadratic polynomial ax2 +bx+c,
where a, b, c are input by the user.

[26]: from math import sqrt # way 3


a, b, c = eval(input('Enter the values of a, b, c separated by commas: '))
disc = b**2-4*a*c #discriminant which determines the type and number of
,→roots

if disc < 0: #Complex roots


print('No real roots')
elif disc >= 0: #Two real roots
r1 = (-b + sqrt(disc))/(2*a)
r2 = (-b - sqrt(disc))/(2*a)
print(f'The roots are {r1} and {r2}.')
else: #Repeated root
r = -b/(2*a)
print(f'The root is {r}.')

Enter the values of a, b, c separated by commas: 1, -5, 6


The roots are 3.0 and 2.0.

4.4.1 Nested if's


Nested if's are if statements used inside other if statements.

Example Write a program that checks whether a number n provided bu the user is divisible
by 2, 3, 5 or none. If it is visible by only one, two, or all of them, inform that user.

12
Python and Mathematics by Donnie M. Kasyoki

[27]: n = eval(input('Enter an integer n: '))


if n % 2 == 0:
#at this point n is divisible by 2
if n % 3 == 0:
#at this point n is divisible by 2 and 3
if n % 5 == 0:
#at this point n is divisible by 2, 3 and 5
print(f'{n} is divisible by 2, 3 and 5.')
else:
#at this point n is divisible by 2 and 3 only
print(f'{n} is divisible by 2 and 3 only.')
elif n % 5 == 0:
#at this point n is divisible by 2 and 5 only
print(f'{n} is divisible by 2 and 5 only.')
else:
#at this point n is divisible by 2 only
print(f'{n} is divisible by 2.')
elif n % 3 == 0:
if n % 5 == 0:
#at this point n is divisible by 3 and 5 only
print(f'{n} is divisible by 3 and 5 only.')
else:
print(f'{n} is divisible by 3 only.')
elif n % 5 == 0:
print(f'{n} is divisible by 5 only.')
else:
print(f'{n} is not divisible by 2, 3 nor 5 only.')

Enter an integer n: 90
90 is divisible by 2, 3 and 5.

5 ITERATIVE FLOW/ REPETITIVE FLOW

Sometimes in mathematics we need to perform an operation in repetitive manner. To en-


able us to do so python provides several ways. We have two ways of performing repetitive
operations each with its own advantages and limitations as well.

5.1 for loops


In most cases we will use a range function that will provide us with range of numbers that
we can work with writing `for' statements.
range(n) gives a range of integers starting with 0 and ending at n-1.
range(k, n) gives a range of integers starting with k and ending at n-1

13
Python and Mathematics by Donnie M. Kasyoki

range(k, n, r) gives a range of integers starting with k, then k+r, k+2r and ending at k+mr
< n.

Example Write a program that prints the following sequence of numbers in that order: 0,
2, 4, 6, 8, 10, 12, 14, 16, 18, 20

[28]: for j in range(0, 21, 2):


if j == 20:
print(j)
else:
print(j, end = ', ')

0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20

Example Write a program to evaluate obtain the sum of the rst 100 natural number.
That is
100
X
s= n
n=1

[29]: s = 0 #initialize summation


for n in range(1,101):
s += n
print(s)

5050

Example Write a program that uses a `for' loop to calculate the factorial of a positive
integer n provided by the user.

[30]: number = int(input('Enter an integer n: '))


factorial = 1 #initiate a product
for j in range(2, number+1):
factorial *= j

print(factorial)

Enter an integer n: 6
720

Exercise

5.2 while loop


While is a little bit technical. It requires a condition to stop or use a `break' keyword to break
out of the loop, otherwise the loop will continue forever. Most people prefer a condition to
break. We will consider both cases for writing `while' loop.

14
Python and Mathematics by Donnie M. Kasyoki

A condition to break I this case the we will need to use a count variable that will
determine when to break. The count variable must be incremented after every iteration so
be sure not to forget that. Anything that can be done with a `for' loop can be done using a
`while' loop.

Example Write a program that prints the following sequence of numbers in that order: 0,
2, 4, 6, 8, 10, 12, 14, 16, 18, 20

[31]: count = 0
while not count > 20:
if count == 20:
print(count)
else:
print(count, end = ', ')
count += 2

0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20

Example Write a program to evaluate obtain the sum of the rst 100 natural number.
That is
100
X
s= n
n=1

[32]: count = 1
s = 0
while count < 101:
s += count
count += 1
print(s)

5050

Example Write a program that uses a `while' loop to calculate the factorial of a positive
integer n provided by the user.

[33]: number = int(input('Enter an integer n: '))


factorial = 1 #initiate a product
count = 2
while count < number+1:
factorial *= count
count += 1
print(factorial)

Enter an integer n: 6
720

15
Python and Mathematics by Donnie M. Kasyoki

`while' for validation Validation is the process of ensuring that the data one is using is
useful. In the case above for instance, the user may input a oat instead and that complecates
things resulting to semantic error. These are errors that cannot be detected easily since they
are not really bugs. The program runs normally. However, the output is not correct.
In the above case of calculating the factorial of a number n, we should force the user to input
an integer by using the `isdigit()' function and `while' loop.

[34]: number = input('Enter an integer n: ') #Use the input to get a str value
while not number.isdigit(): #Check if the entry contains all digits
number = input('Invalid entry. Enter a positive integer: ')
number = int(number) #Change from str to int type
factorial = 1 #initiate a product
count = 2
while count < number+1:
factorial *= count
count += 1
print(factorial)

Enter an integer n: -5
Invalid entry. Enter a positive integer: 5.0
Invalid entry. Enter a positive integer: 6
720

The division algorithm to nd gcd of two numbers Let a and b be positive integers.
The gcd(a, b) is the greatest common divisor of the two numbers. This can be obtained
using division algorithm.
If a < b, swap the values so a > b.
Dene r = a%b. If r = 0, stop the process and print b as the gcd.
If r != 0, redine a and b by setting a = b and b = r.
Repeat the same process until you obtain r = 0.

Example Write a program to calculate the gcd of two integers a and b provided by the
user. Ensure that they are both integers.

[35]: a, b = input('Enter integer a, b separated by a comma no space: ').


,→split(',')

while not (a.isdigit() and b.isdigit()): #Check if the entry contains all
,→digits

a, b = input('Invalid entry. Enter integera a, b: ')


c, d = a, b
a, b = int(a), int(b) #Change from str to int type
if a < b:

16
Python and Mathematics by Donnie M. Kasyoki

a, b = b, a #Swapping ##step 1
while True:
r = a%b #defining r
if r == 0:
break#If r =0 we stop
else:
a, b = b, r #Redefining a and b ##Step 3
print(f'gcd({c}, {d}): {b}')

Enter integer a, b separated by a comma no space: 48,56


gcd(48, 56): 8

Exacise

6 LISTS, ARRAYS AND DICTIONARIES

6.1 Lists
List is another type of value. Elements of a list are enclosed in a pair of square brackets.
One may also choose to dene a list using the inbuilt `list' function. A list can take any
type of value as an item including lists themselves. The function `len' gives the number of
elements in a list.

Index of a list We access an item of a list using an index. The rst element of the list is
index 0, the next is 1, etc. We can also use reverse indexing that starts at index -1 which is
the last, -2 is the second last, etc.

Example
[36]: A = [] # L is an empty list
B = [90, 50, 'Hello', [9, 0, 1], 5]
print(f'Number of elements in B: {len(B)}')
print(f'The 1st item in list B: {B[0]}')
print(f'The second last item in list B: {B[-2]}')
print(f'The second item in the second last item of list B: {B[-2][1]}')
print(f"The fifth character of 'Hello' which is index 2 of B: {B[2][4]}")

Number of elements in B: 5
The 1st item in list B: 90
The second last item in list B: [9, 0, 1]
The second item in the second last item of list B: 0
The fifth character of 'Hello' which is index 2 of B: o

Sublists We can form sublists from the main lists. We will obtain these sublists using
index notations. For instance, the sublist ending at a certain position, the sublist begining

17
Python and Mathematics by Donnie M. Kasyoki

at a certain index, or sublist starting at a certain index and ending at a certain position.

Example Form a list L = [5, 3, 5, 6, 7, 10, 34, 56, 32, 12, 3, 4].
Print the rst ve items in the list.
Print the last six items in the list.
Print the items from index 4 to index 8 in the list.

[37]: L = [5, 3, 5, 6, 7, 10, 34, 56, 32, 12, 3, 4]


print(L[:5]) #First 5 ends at position 5
print(L[-6:]) #Last 6 starts at index -6
print(L[4:9]) # Index 8 is position 9

[5, 3, 5, 6, 7]
[34, 56, 32, 12, 3, 4]
[7, 10, 34, 56, 32]

Append, overwrite, remove and delete a sublist Appending an item in a given list
adds a new item at the end of a list. To overwrite an item in the list, we simply assign the
the list index to the new value. The `remove' function is set to remove a specic item in the
list and removes the rst one that appears in the list. For instance, if a list contains more
that one 5's in a certain list, `remove(5)' will remove the one that has the smallest index.
To delete a sublist, all we have to do is assign the sublist to an empty list.

Example Use the list created above to answer the following questions:
Print the list.
Append 9 to the list.
Replace the item in index 10 with 10.
Remove three from the list.
Delete items starting from index 4 to index 8.
Print the new list.

[38]: L = [5, 3, 5, 6, 7, 10, 34, 56, 32, 12, 3, 4]


print(L) #1
L.append(9) #2
L[10] = 10 #3
L.remove(3) #4 #removes the 3 in index 1
L[4: 9] = [] #5
print(L) #6

[5, 3, 5, 6, 7, 10, 34, 56, 32, 12, 3, 4]


[5, 5, 6, 7, 10, 4, 9]

18
Python and Mathematics by Donnie M. Kasyoki

Sort and shue Sorting a list requires a list of all numeral values or all string values.
Sorting an all strings list is done alphabetically or the reverse alphabetically. Numbers' lists
can also be done ascending and descending order.
To shue a list will recquire the shue function from the random module.

Example Sort the list in the above example in both ascending and descending order. Print
both sorted lists. Shue twice printing each time.

[39]: from random import shuffle


L = [5, 3, 5, 6, 7, 10, 34, 56, 32, 12, 3, 4]
L.sort() #Sorting the list in ascending order
print(f'Ascending: {L}')
L.sort(reverse = True) #Sorting the list in descending order
print(f'Descending: {L}')
shuffle(L)
print(f'Shuffled 1: {L}')
shuffle(L)
print(f'Shuffled 2: {L}')

Ascending: [3, 3, 4, 5, 5, 6, 7, 10, 12, 32, 34, 56]


Descending: [56, 34, 32, 12, 10, 7, 6, 5, 5, 4, 3, 3]
Shuffled 1: [5, 10, 32, 3, 6, 12, 34, 3, 7, 5, 56, 4]
Shuffled 2: [10, 4, 56, 3, 5, 3, 7, 5, 6, 34, 12, 32]

Exercise

6.2 Dictionaries
Dictionaries work more or less the same as lists but we use keys instead of indices. Items of
a dictionary are called using specic keys. ints, oats, str, bool, tuple can be used as Keys.
Lists, sets cannot be used as keys in a dictionary.
One can create a key by directly assigning it to a value. Unlike the keys, the value can be
any type of value.

Example Create a list of 1000 random integers between 1 and 100. Create and print a
dictionary that summarizes the grades using the grading system below:
A = 80 ≤ mark ≤ 100
B = 65 ≤ mark < 80
C = 50 ≤ mark < 65
D = 40 ≤ mark < 50
E = 0 ≤ mark < 40

19
Python and Mathematics by Donnie M. Kasyoki

[40]: from random import randint as rint #The function to get random integers
L = [] #initialize a list
for i in range(1000):
L.append(rint(1,100))
grades = []
for l in L:
if l >= 80:
grades.append('A')
elif l >= 65:
grades.append('B')
elif l >= 50:
grades.append('C')
elif l >= 40:
grades.append('D')
else:
grades.append('E')
gradesDic = {} #Initialize an empty dictionary.
for grade in grades:
if grade in gradesDic: #If the key exists,
gradesDic[grade] += 1 #Add one to the value.
else:
gradesDic[grade] = 1 #Create the key and enter the value as 1
print(f'grades = {gradesDic}')
print(f"A = {gradesDic['A']}") # The 'A's only

grades = {'A': 201, 'B': 155, 'E': 399, 'D': 83, 'C': 162}
A = 201

Exercise

6.3 Arrays
We are going to import several functions from numpy including `array' function. `zeros'
function is used to create an zero array of a specied dimension determined by the argument.
The `array' function takes a list and converts to an array. Let's look at a n-dimensional array
of size n × 1.
Example
Write a zero array of dimension 6. Overwrite the array by generating random integers
between 1 and 10 and placing at each index of the array to chnage it to a nonzero array.

[41]: import numpy as np


from random import randint as rint
z = np.zeros(6)
print(f'z as a zero array: {z}')

20
Python and Mathematics by Donnie M. Kasyoki

for i in range(len(z)):
z[i] = rint(1,10)
print(f'z after overwiting: {z}')

z as a zero array: [0. 0. 0. 0. 0. 0.]


z after overwiting: [ 9. 10. 2. 7. 3. 6.]

arange and linspace functions The `arange' and `linspace' functions are used basically
for the same job only that their arguments defer by functionality.
We can use `arange' to create an array of numbers equidistant from the previous number. If
h is the common dierence from one number to the next, then h will take the third argument.
The starting number takes the rst argument and

last number + k, 0 < k ≤ h

takes the second argument.


When dealing with `linspace' function the rst number takes the rst argument, the last
number takes the second argument and the dimension of the array takes the last argument.

Example Create an array of numbers between 0, 2 with a distance of 0.2 from a number
to the next. Use both `arange' and `linspace'.

[42]: import numpy as np


arange_array = np.arange(0, 2.01, .2)
print(f'arange array: {arange_array}')
dim = int((2-0)/.2+1)
linspace_array = np.linspace(0, 2, dim)
print(f'linspace array: {linspace_array}')

arange array: [0. 0.2 0.4 0.6 0.8 1. 1.2 1.4 1.6 1.8 2. ]
linspace array: [0. 0.2 0.4 0.6 0.8 1. 1.2 1.4 1.6 1.8 2. ]

Exercise

7 Functions

We have already handled some inbuilt functions and gotten other functions from modules.
Some of these inbuilt functions include, `list' used to create lists, `len' for checking the size
of a list or dimension of an array, etc. Some of the functions from math module for instance
are `sqrt' for square root, `factorial' for factorial, etc.
In this subsection we will mainly focus on writing our own functions that we can use in our
program(s). We will introduce new keywords like `def' and `return'. We prefer returning
rather than printing when writing functions expecially maths functions because our interest

21
Python and Mathematics by Donnie M. Kasyoki

is sometimes getting the value rather than printing it. We can reuse the returned value to
perform operations but we cannot use it if we just print.
We can write a function that takes zero arguments or one that takes one or more arguments.
We will only focus on the ones that take at least one argument and a denite number of
arguments.
When calling a function, one can use positional arguments or key arguments. For positional
arguments one needs to know the position of the specic parameter as dened in a function.
For instance if the `def' statement is def function(x, y) then one must know what x and y
are and their positions and roles as per the denition. For key arguments one needs to know
the parameters used as arguments if it is x and y like in our case then one needs to have
that information. Order doesn't matter when dealing with key arguments. Let's look at the
following examples.

Example Write a function that returns the area of a circle of radius r. Where r is the
argument. Use the function dened to calculate the area of a circle whose radius is 10 units.

[43]: def area_circle(r):


from math import pi
return pi*r**2

print(f'Area of a circle of radius 10: {area_circle(10)} sq. units.


,→')#positional argument

print(f'Area of a circle of radius 10: {area_circle(r = 10)} sq. units.


,→')#key argument

Area of a circle of radius 10: 314.1592653589793 sq. units.


Area of a circle of radius 10: 314.1592653589793 sq. units.

Example Write a function that returns the volume of a cylinder of radius r and height h.
Use the function to calculate the volume of a cylinder of radius 10 units and height 5 units.

[44]: def volume_cylinder(r, h): ##Parameters used are r and h so one must use
,→r and h for key arguments.

from math import pi


return pi*r**2*h

#positional arguments
print(f'Volume of a cylinder of radius 10 and height 5:
,→{volume_cylinder(10, 5)} cubic units.')

#key arguments
print(f'Volume of a cylinder of radius 10 and height 5:
,→{volume_cylinder(h = 5, r = 10)} cubic units.')

22
Python and Mathematics by Donnie M. Kasyoki

Volume of a cylinder of radius 10 and height 5: 1570.7963267948967 cubic


,→units.

Volume of a cylinder of radius 10 and height 5: 1570.7963267948967 cubic


,→units.

Example Write a function `sqr' to approximate the square root of a number a using
Newtons iteration method shown below:
We start with an approximate number, say y = a/2 (doesn't hav to be that). Find a new
approximate
y2 − a
ynew = yold − old
2yold
and compare with the previous approximate. If they are not the same nd another new
approximate using the same formula and compare. Do the same until you get equality of
the two approximates. The last approximate is the approximate square root of a.

[45]: def sqr(a):


y_old = a/2
while True:
y_new = y_old - (y_old**2-a)/(2*y_old) #create a new approximate
if y_new == y_old: #Compare old approximate with new one
break
y_old = y_new #If they are not equal update y_old to use in
,→calculating new approx

return y_new

print(f'sqrt(64) = {sqr(64)}')

sqrt(64) = 8.0

Exercise Write a function gcd(a,b) that takes two arguments (positive integers) and re-
turns their gcd using division algorithm describes previously.

7.1 Recursive functions


Recursion is a very important term in mathematics. This can also be utilized in program-
ming, not only in python, but in all-I think-programming languages.

Example Dene factorial of a nonnegative integer n as follows:


(
1, if n = 0
n! = .
n(n − 1)!, if n > 0

Write a recursive function to that returns the factorial of a nonnegative integer n.

23
Python and Mathematics by Donnie M. Kasyoki

[46]: def factorial(n):


if n == 0:
return 1
return n*factorial(n-1)# We have used the function in defining the
,→function.

print(f'6! = {factorial(6)}')

6! = 720

Example Dene a sequence {xn }n∈N recurcively as follows:

x1 = −2, xn+1 = 2xn + 5, n > 1.

Write a recurcive function seq(n) that returns the nth term of the sequence. Use the function
to nd the 10th term of the sequence.

[47]: def seq(n):


if n == 1:
return -2
return 2*seq(n-1)+5
print(f'The 10th term of the sequence: {seq(10)}')

The 10th term of the sequence: 1531

Exercise Write a recursive function b(n) that returns the nth term of the Fibonaci se-
quence dened by:
F1 = 1, F2 = 1, Fn = Fn−1 + Fn−2 , n > 2.
Print the 20th term of the sequence
Write another function bRatio(n) that returns the ratio Fn
Fn−1
,n > 1.
Write a function bSum(n) that returns the sum of the rst n terms of the Fibonacci se-
quence.

8 CALCULUS IN PYTHON

In this chapter we will look at some basic elements of calculus and how we can use python
to solve some basic problems. We will look at limits, derivatives, integrals of functions.

8.1 Limits of functions


Using sympy, we are going to write symbolic functions and hence nd their limits. We will
need to dene the symbols rst before writing the function.

24
Python and Mathematics by Donnie M. Kasyoki

Example Use sympy to evaluate


x−1
lim .
x→1 x2 − 1

[48]: from sympy import limit #limit function


from sympy.abc import x # symbol x

f = (x-1)/(x**2-1)
lim = limit(f, x, 1)
print(lim)

1/2

Example Evaluate the following using sympy


2 sin x − sin 2x
lim
x→0 x − sin x

[49]: from sympy import limit, sin


from sympy.abc import x
f = (2*sin(x)-sin(2*x))/(x-sin(x))
lim = limit(f, x, 0)
print(lim)

Example Use sympy to evaluate

x4 + 3x − 4
lim .
x→∞ x3 − x2

[50]: from sympy import limit, oo ##ouble o for infinity


from sympy.abc import x
f = (x**4+3*x-4)/(x**3-x**2)
lim = limit(f, x, oo)
display(lim)

Example Use sympy to evaluate

x2 + 3x − 4
lim−
x→1 |x2 − 1|

25
Python and Mathematics by Donnie M. Kasyoki

[51]: from sympy import limit, oo ##ouble o for infinity


from sympy.abc import x
f = (x**2+3*x-4)/abs(x**2-1)
lim = limit(f, x, 1, dir = '-')
display(lim)
5

2

Exercise Use sympy to evaluate

x2 + 3x − 4
lim
x→∞ x2 − 1
Use sympy to evaluate
x2 + 3x − 4
lim−
x→1 |x2 − 1|
Use sympy to evaluate
x2 + 3x − 4
lim+
x→1 |x2 − 1|

8.2 Derivatives
We are going to look at how we can nd derivatives both ordinary and partial derivatives.
Although the only dierence is the number of symbols we import from `sympy.abc'. In most
cases if the solution does not look simplied, it is recommended to use the `simplify' method
which is an attribute of any function dened symbolically. The `di' function is also an
attribute hence no need of importing it.

Example Use sympy to nd the derivative of the function f (x) = x2 +3x−4
x2 −1
.

[52]: from sympy.abc import x


f = (x**2+3*x-4)/(x**2-1)
display(f.diff(x).simplify())
3

x2 + 2x + 1

Example Use sympy to nd the third derivative of the function f (t) = 3t · e2t dt.

[53]: from sympy import exp


from sympy.abc import t
f = 3*t*exp(2*t)
display(f.diff(t, t, t)) #f.diff(t, t, t) for the third derivative

12 · (2t + 3) e2t

26
Python and Mathematics by Donnie M. Kasyoki

8.3 Partial derivatives


For partial derivative we need to dene a function with more than one independent variables.
Example
∂2f
Given that f (x, t) = 2xe2t − cos tx, nd ∂f
∂t
and ∂x∂t
.

[54]: #w.r.t t
from sympy import cos
from sympy.abc import t, x
f = 2*x*exp(2*t)-cos(t*x)
display(f.diff(t))

4xe2t + x sin (tx)


[55]: #w.r.t t and x
display(f.diff(t).diff(x))

tx cos (tx) + 4e2t + sin (tx)

8.4 Integrals
Just like working with derivatives, we need to dene our functions with the necessary symbols
for integration. We will look at both indenite and denite integrals. We do a list of all the
examples below:

Example Find the indenite integral using sympy √1 dx.


R
x2

[56]: from sympy import sqrt


from sympy.abc import x
f = 1/(sqrt(x**2))
display(f.integrate(x))
 √ 
log 2x + 2 x2

Use sympy to evaluate tan−1 x dx


R

[57]: from sympy import atan


from sympy.abc import x
f = atan(x)
display(f.integrate(x))

log (x2 + 1)
x atan (x) −
2

Example
R2
Use sympy to evaluate the following deinite integral 0
√ 1
4−2x
dx

27
Python and Mathematics by Donnie M. Kasyoki

[58]: from sympy import sqrt


from sympy.abc import x
f = 1/(sqrt(4-2*x))
display(f.integrate([x, 0, 2]))

9 ALGEBRA AND LINEAR ALGEBRA

Here we are going to look at factorization problems, roots of polynomials, solutions of si-
multaneous equations, and some matrix operations. All these will be done using the sympy
module as well.

9.1 Substitution and factorization


Example Write and display the function f (a, b) below. Factorize the function and display.
Substitute b with 4 and factorize the function again then display
y = a3 − a2 b − ab2 + b3 .

[59]: from sympy.abc import a, b


f = a**3-a**2*b-a*b**2+b**3 #defining f
display(f) #Displays f
display(f.factor()) #Factorizing
f = f.subs(b, 4)
display(f)#Substituting b with 4.
display(f.factor())

a3 − a2 b − ab2 + b3
(a − b)2 (a + b)
a3 − 4a2 − 16a + 64
(a − 4)2 (a + 4)

9.2 Roots of polynomials


Example Find the roots of the following polynomial:
6x3 + x2 − x

[60]: from sympy import roots


from sympy.abc import x
f = 6*x**3+x**2-x #defining f
print(roots(f, x)) #Dictionary of roots of f and their multiplicities.

{-1/2: 1, 1/3: 1, 0: 1}

28
Python and Mathematics by Donnie M. Kasyoki

9.3 Simultaneous equations


To solve simultaneous linear equations we need to write a list of the various linear combina-
tions that equal to zero before calling the function `solve' for solutions.

Example Solve the following simultaneous linear equations:

x+y+z =6
3x + 2y + z = 10
x + 2y + z = 8

[61]: from sympy import solve


from sympy.abc import x, y, z
eq = [x+y+z-6, 3*x+2*y+z-10, x+2*y+z-8]
sol = solve(eq)
print(sol)

{x: 1, y: 2, z: 3}

Example Solve the following simultaneous linear equations:

c+d−e=0
2c − d − e = −1

The system does not have a unique solution. Therefore we will nd solution for two of the
variables.

[62]: from sympy.abc import c, d, e


from sympy import solve
eqs = [c+d-e, 2*c-d-e+1]
solve(eqs, c, d)

[62]: {c: 2*e/3 - 1/3, d: e/3 + 1/3}

9.4 Matrices
9.4.1 Determinants and inverses of invertible matrices
Example Write the following matrix, nd the determinant and its inverse.
 
1 0 −2
A = 0 3 1
1 −1 2

29
Python and Mathematics by Donnie M. Kasyoki

[63]: from sympy import Matrix


A = Matrix([[1, 0, -2],[0, 3, 1],[1, -1, 2]])
print(f'det(A) = {A.det()}')
display(A.inv())

det(A) = 13
 7 2 6

13 13 13
 1 4 1 
− 13
13 13
3 1 3
− 13 13 13

9.4.2 Eigenvalues and eigenvectors


Example Find the eigenvalues and eigenvectors of the matrix:
 
0 −2 −2
A = 1 3 1
0 0 2

[64]: from sympy import Matrix


A = Matrix([[0, -2, -2],[1, 3, 1],[0, 0, 2]])
print(f'det(A) = {A.eigenvals()}')
display(A.eigenvects())

det(A) = {2: 2, 1: 1}
[(1,
1,
[Matrix([
[-2],
[ 1],
[ 0]])]),
(2,
2,
[Matrix([
[-1],
[ 1],
[ 0]]),
Matrix([
[-1],
[ 0],
[ 1]])])]
The set of eigenvectors is not always that pretty. Most of the times it looks very messy.

30
Python and Mathematics by Donnie M. Kasyoki

9.4.3 Diagonalization
Diagonalization does not always work on matrices. Especially when a matrix has an eigen
value whose multiplicity is greater than one and the number of independent eigenvectors
corresponding to such eigenvalue does not match the multiplicity.
The `diagonalize' function returns a tuple (P, D) where P is an invertible matrix and D is a
diagonal matrix such that A = P −1 DP , where A is the matrix in question.

Example Diagonalize matrix A and print the diagonal matrix D and nonsingular matrix
P such that A = P −1 DP :  
0 −2 −2
A = 1 3 1
0 0 2

[65]: from sympy import Matrix


A = Matrix([[0, -2, -2],[1, 3, 1],[0, 0, 2]])
P, D = A.diagonalize() #diagonalize the matrix A
display(D)
display(P)
 
−2 −1 −1
1 1 0
0 0 1
 
1 0 0
0 2 0
0 0 2

10 SOLUTIONS OF ORDINARY DIFFERENTIAL

EQUATIONS

10.1 Analytic solutions using sympy's dsolve


We will rst look at general solutions to dierential equations using python. Firstly we will
need to learn how to represent a dierential equation in a way that we can call dsolve from
sympy module.

Example Write and display the following dierential equation:


y ′′ + 2y ′ + y = x2 − sin x

[66]: from sympy import Function, Eq, sin #importing the required functions.
from sympy.abc import x #import symbol x.
y = Function('y') #setting y as a function
de = Eq(y(x).diff(x,x)+2*y(x).diff(x)+y(x), x**2-sin(x))

31
Python and Mathematics by Donnie M. Kasyoki

display(de)

d d2
y(x) + 2 y(x) + 2 y(x) = x2 − sin (x)
dx dx

Example Write and display the following dierential equation:


dy
(ex + sin y) = cos x − ey
dx

[67]: from sympy import Function, Eq, sin, cos, exp #importing the required
,→functions.

from sympy.abc import x #import symbol x.


y = Function('y') #setting y as a function
de = Eq((exp(x)+sin(y(x)))*y(x).diff(x), cos(x)-exp(y(x)))
display(de)

d
(ex + sin (y(x))) y(x) = −ey(x) + cos (x)
dx
Now that we can write the dierential equations, we can now solve them.

Example Solve the dierential equation below using dsolve function:

y ′′ − 5y ′ + 6y = x2 − 3x.

[68]: from sympy import Function, Eq


from sympy.abc import x
y = Function('y')
de = Eq(y(x).diff(x,x)-5*y(x).diff(x)+6*y(x), x**2-3*x)
sol = dsolve(de)
display(sol)

x2 2x 13
y(x) = C1 e2x + C2 e3x + − −
6 9 54

Example Write and display the following dierential equation:


dy cos x − 1
= ey .
dx x

[69]: from sympy import Function, Eq


from sympy.abc import x
y = Function('y')
de = Eq(y(x).diff(x), exp(y(x))*(cos(x)-1)/x)
sol = dsolve(de)

32
Python and Mathematics by Donnie M. Kasyoki

display(sol)
 
1
y(x) = log −
C1 − log (x) + Ci (x)

Initial Value Problem Initial conditions are written as a dictionary as part of the optional
arguments in dsolve function.

Example Solve the IVP below using dsolve:

dy
= −2y, y(0) = 2
dx

[70]: from sympy import Function, Eq


from sympy.abc import x
y = Function('y')
de = Eq(y(x).diff(x), -2*y(x))
sol = dsolve(de, ics = {y(0):2})
display(sol)

y(x) = 2e−2x

10.1.1 Example
Solve the IVP below using dsolve:

y ′′ + 3y ′ + 2y = sin x, y(0) = 0, y ′ (0) = 1

[71]: from sympy import Function, Eq


from sympy.abc import x
y = Function('y')
de = Eq(y(x).diff(x,x)+3*y(x).diff(x)+2*y(x), sin(x))
sol = dsolve(de, ics = {y(0):0, y(x).diff(x).subs(x, 0):1})
display(sol)

sin (x) 3 cos (x) 3e−x 6e−2x


y(x) = − + −
10 10 2 5

11 NUMERICAL SOLUTIONS OF ODEs

11.1 Euler's Method for rst order


The dx
dy
= f (x, y), y(x0 ) = y0 be a rst order initial value problem. Let x0 = 0, y(xn ) = yn .
Let xl be the last value of x that we are interested in. Eulers method tries to approximate
estimate the solution curve between the x0 and xl by taking small step along the tangent

33
Python and Mathematics by Donnie M. Kasyoki

line at each point. The smaller the steps the close we get to the actual solution as will be
demostrated in subsequent examples. We use the following formulars to obtain values of y
at every step. h is the step size.

yn = yn−1 + h ∗ fn (x, y), y0 = y(x0 )


fn (x, y) = f (xn , yn )
xn = xn−1 + h, x0 = initial value of x

Example Given that


dy
= 3x2 , y(0) = 0.
dx
Use Euler's method to obtain the value of y at x = 1 given that h = .01.

[72]: from numpy import zeros, linspace


x0 = 0
y0 = 0
xn = 1
h = .01
n = int((xn-x0)/h+1)
x = linspace(x0, xn, n)
dim = len(x)
y = zeros(dim)
f = zeros(dim)
for j in range(1, dim):
y[j] = y[j-1]+h*f[j-1]
f[j] = 3*x[j]**2
z = x**3

import pylab as pl
pl.plot(x, y, label = 'Euler', color = 'green')
pl.plot(x, z, label = 'Exact', linewidth = 2, linestyle = '--')
pl.xlabel('$x$-axis')
pl.ylabel('$y$-axis')
pl.legend()
pl.show()

34
Python and Mathematics by Donnie M. Kasyoki

Example Use Euler's method to plot the solution of the IVP for 0 ≤ x ≤ 1 using Euler's
method.
dy
= 2y, y(0) = 2
dx
Use h = .01. In the same plot, plot the function y = 2e2x .

[73]: from numpy import linspace, zeros, exp


import pylab as pl
x0 = 0
xn = 1
h = .01
n = int((xn-x0)/h+1)
x = linspace(x0, xn, n)
dim = len(x)
y = zeros(dim)
f = zeros(dim)
y[0] = 2
f[0] = 4
for j in range(1, dim):

35
Python and Mathematics by Donnie M. Kasyoki

y[j] = y[j-1]+h*f[j-1]
f[j] = 2*y[j] #f(x, y) = 2y = dy/dx

z = 2*exp(2*x)
pl.plot(x, y, label = 'Euler', linewidth = 2, linestyle = '--')
pl.plot(x, z, color = 'green', label = '$y = 2e^{2x}$')
pl.xlabel('$x$-axis')
pl.ylabel('$y$-axis')
pl.legend()
pl.savefig('Euler.pdf')

11.2 Runge-Kutta fourth order method


This method is more accurate compared to the Euler method.
Consider a rst order dierential equation dy
dx
= f (x, y). We use h as the step-size and

36
Python and Mathematics by Donnie M. Kasyoki

y(x0 ) = y0 . We obtain the nth value of y by

k1 = hf (xn , yn )
 
h k1
k2 = hf xn + , yn +
2 2
 
h k2
k3 = hf xn + , yn +
2 2
k4 = hf (xn + h, yn + k3 )
1
yn+1 = yn + (k1 + 2k2 + 2k3 + k4 ) .
6

Example Given that


dy
= 3x2 , y(0) = 0.
dx
Use Runge-Kutta method and pylab to plot the solution of the above IVP for 0 ≤ x ≤ 1
using 1001 points. In the same graph plot the graph of y = x3 .

[74]: #dy/dx = 3x^2, y(0) = 0, h = .01


from numpy import linspace, zeros
import pylab as pl
x0 = 0
xn = 1
h = .01
n = int((xn-x0)/h+1)
x = linspace(x0, xn, n)
y = zeros(len(x))
y[0] = 0 #initial condition
f = zeros(len(x))
for j in range(1, len(x)):
#f[j] = 3*x[j]**2
k1 = h*3*x[j-1]**2
k2 = h*3*(x[j-1]+h/2)**2
k3 = h*3*(x[j-1]+h/2)**2
k4 = h*3*(x[j-1]+h)**2
y[j] = y[j-1]+(1/6)*(k1+2*k2+2*k3+k4)

z = x**3 #The solution of the IVP


pl.plot(x, y, label = "Runge-Kutta", linewidth = 3, linestyle = "--",
color = 'orange') #Solution from Runge-Kutta
pl.plot(x, z, label = '"$y = x^3$"', color = 'green') #Plotting the
,→solution

pl.xlabel('$x$')
pl.ylabel('$y(x)$')
pl.title("Solution by 4th order Runge-Kutta")

37
Python and Mathematics by Donnie M. Kasyoki

pl.legend();

Example Consider the IVP


dy
= x(1 + y), y(0) = 0.
dx
Use Runge-Kutta method and pylab to plot the solution of the above IVP for 0 ≤ x ≤ 3
x2
given that h = 0.01. In the same graph plot the graph of of the solution y = e 2 − 1.

[75]: #f(x, y) = x(1+y)


#y(0) = 0
import pylab as pl
from numpy import linspace, zeros, exp
x0 = 0
xn = 3
h = .01
n = int((xn-x0)/h+1)
x = linspace(x0, xn, n)
y = zeros(len(x))

38
Python and Mathematics by Donnie M. Kasyoki

for j in range(1, len(x)):


k1 = h*x[j-1]*(1+y[j-1])
k2 = h*(x[j-1]+h/2)*(1+y[j-1]+k1/2)
k3 = h*(x[j-1]+h/2)*(1+y[j-1]+k2/2)
k4 = h* (x[j-1]+h)*(1+y[j-1]+k3)
y[j] = y[j-1] + (1/6)*(k1+2*k2+2*k3+k4)

z = exp(x**2/2)-1 #The solution


pl.plot(x, y, color = 'green', linewidth = 3, linestyle = '--', label =
,→"Runge-Kutta");

pl.plot(x, z, color = 'red', label = ""$y = e^x^2/2-1$"")


pl.xlabel('$x$')
pl.ylabel('$y(x)$')
pl.title("Solution of $y' = x(1+y)$ by 4th order Runge-Kutta")
pl.legend();

39
Python and Mathematics by Donnie M. Kasyoki

11.3 SCIPY module


Here we solve the above IPV using the scipy module which is the most accurate method,
and do a comparison with the exact solution.

Example Given that


dy
= 3x2 , y(0) = 0.
dx
Use scipy module and pylab to plot the solution of the above IVP for 0 ≤ x ≤ 1 using
h = 0.1. In the same graph plot the graph of y = x3 .
[76]: from scipy.integrate import odeint
from numpy import linspace
def de(y, x):
return 3*x**2 #define the ode dy/dx = f(x,y)
x0 = 0
xn = 1
y0 = 0 #initial condition
x = linspace(x0, xn, 1001)
y = odeint(de, y0, x)
z = x**3
import pylab as pl
pl.plot(x, y, label = 'scipy', color = 'green')
pl.plot(x, z, label = 'Exact', linewidth = 2, linestyle = '--')
pl.xlabel('$x$-axis')
pl.ylabel('$y$-axis')
pl.legend()
pl.savefig('scipy 1st order.pdf')

40
Python and Mathematics by Donnie M. Kasyoki

Example Use scipy module to plot the solution of the IVP for 0 ≤ x ≤ 1 using 1001
points.
dy
= 2y, y(0) = 2.
dx
In the same graph, plot the function y = 2e2x .

[77]: from scipy.integrate import odeint


from numpy import exp
import pylab as pl
def de(y, x):
return 2*y

x0 = 0
xn = 1
x = linspace(x0, xn, 1001)
y0 = 2 #initial condition
y = odeint(de, y0, x)

z = 2*exp(2*x)

41
Python and Mathematics by Donnie M. Kasyoki

pl.plot(x, y, label = 'Scipy', linewidth = 2, linestyle = '--')


pl.plot(x, z, color = 'green', label = '$y = 2e^{2x}$')
pl.xlabel('$x$-axis')
pl.ylabel('$y$-axis')
pl.legend()
pl.savefig('scipy 1st order 2.pdf')

Higher order IVPs For higher order initial value problems we need to reduce them to
a system of rst order IVPs. Then we create an array of this system and a tuple of initial
values before doing the numerical solution. Let's start with a case of second order ODE.
Condider the initial value problem
d2 y
= f (x, y, y ′ ), y(x0 ) = y0 , y ′ (x0 ) = y0′ .
dx2

To solve this we create a new variable say z = y ′ which implies that $ y'_0 = z_0, z' =
y' '$. So now we have a system of two rst order IVPs

z ′ = (f (x, y, z)
y ′ = z, z(x0 ) = z0 , y(x0 ) = y0

42
Python and Mathematics by Donnie M. Kasyoki

Consider the example below:

Example Using scipy and pylab plot the solution for 0 ≤ x ≤ 2 (use 1001 points) of the
IVP
7
y ′′ + 3y ′ + 2y = x2 , y(0) = , y ′ (0) = −1.
4
In the same graph, plot
x2 3x 7 1 −x 1 −2x
y= − + + e − e
2 2 4 2 2

[78]: #Transformation of the ODE to a system of 1st order ODEs.


#Let y' = z, => z' = x^2-3z-2y and y' = z, y(0) = 7/4, z(0) = -1
from scipy.integrate import odeint
from numpy import linspace, array, exp
import matplotlib.pyplot as plt
def de(y, x): #y = (z, y) => y[0] = z and y[1] = y
from numpy import zeros
dydx = zeros(2) # dydx = (z', y')
dydx[0] = x**2-3*y[0]-2*y[1]
dydx[1] = y[0]
return dydx
x = linspace(0,2,1001)
ics = (-1, 1.75)
Y = odeint(de, ics, x)

z = x**2/2 - 3*x/2 + 7/4 + 0.5*exp(-x) - 0.5*exp(-2*x)

plt.plot(x, Y[:,1], color = 'yellow', label = 'Scipy')


plt.plot(x, z, linestyle = '--', linewidth = 2, label = 'Exact')
plt.xlabel('$x$-axis')
plt.ylabel('$y$-axis')
plt.title('The solution of the DE')
plt.legend()
plt.savefig('scipy 2nd order.pdf')

43
Python and Mathematics by Donnie M. Kasyoki

Exercise.
1. Solve the IVP below using dsolve:

y ′′′ + 3y ′′ + 3y ′ + y = 0, y(0) = 1, y ′ (0) = −2, y ′′ (0) = 1.


.

[79]: from sympy import Eq, Function, dsolve


from sympy.abc import x
y = Function('y')
de = Eq(y(x).diff(x,x,x)+3*y(x).diff(x,x)+3*y(x).diff(x)+y(x),0)
sol = dsolve(de, ics = {y(0):1, y(x).diff(x).subs(x,0):-2, y(x).diff(x,x).
,→subs(x,0):1})

display(sol)

y(x) = (x (−x − 1) + 1) e−x


2. Tranform the IVP into a system of rst order ODEs and using scipy's odeint obtain
1001 points of y for 0 ≤ x ≤ π .

44
Python and Mathematics by Donnie M. Kasyoki

[80]: # y' = z #y' = z


# z' = y'' = w #z' = w
# w' = y''' #w' = -3w-3z-y
from numpy import linspace, pi
from scipy.integrate import odeint
def de(y, x): ##y = (w, z, y)
from numpy import zeros
dydx = zeros(3) #dydx = (w', z', y')
dydx[0] = -3*y[0]-3*y[1]-y[2]
dydx[1] = y[0]
dydx[2] = y[1]
return dydx
x = linspace(0, pi, 1001)
ics = (1, -2, 1)
Y = odeint(de, ics, x)

3. Plot the two solutions in one graph showing the dierence of the two plots.

[81]: from numpy import exp


import pylab as pl
z = (-x*(x+1)+1)*exp(-x) #The solution using dsolve

pl.plot(x, Y[:,2], color = 'orange', linestyle = '--', linewidth = 2.2,


,→label = 'dsolve')

pl.plot(x, z, label = 'scipy', color = 'green')


plt.xlabel('$x$-axis')
plt.ylabel('$y$-axis')
plt.title("The solution of $y'''+3y''+3y'+y = 0, y(0) = 1, y'(0) = -2,
,→y''(0) = 1.$")

plt.legend()
plt.savefig('scipy 3rd order.pdf')

45
Python and Mathematics by Donnie M. Kasyoki

11.4 SIR and SEIR models


Compartmental modeling is very commonly used in mathematical modelling of infections
diseases. SIR model has three compartments namely: Susceptible, Infected and Recovered
while SEIR model has four compartments namely: Susceptible, Exposed, Infected and Re-
covered. The model is summarized by using a system of rst order dierential equations.
This makes it easy to use the odeint method from scipy.

Example Write a program to plot the graph showing Susceptible, Infected and Recovered
for a whole year given that

dS
= −βSI
dt
dI
= βSI − γI
dt
dR
= γI
dt
given that at time (days) t = 0, S = 1 − 10−5 , I = 1 − 10−5 , β = 0.8, γ = 0.1

46
Python and Mathematics by Donnie M. Kasyoki

[82]: from scipy.integrate import odeint


import pylab as pl
beta = .8
gamma = .1
def de(Y,t): # Y = (S, I, R)
from numpy import zeros
dydt = zeros(3) #dydt = (S', I', R')
dydt[0] = - beta*Y[0]*Y[1]
dydt[1] = beta*Y[0]*Y[1]-gamma*Y[1]
dydt[2] = gamma*Y[1]
return dydt
ics = (1-1e-5, 1e-5, 0)
from numpy import linspace
t = linspace(0, 365, 1001)
sol = odeint(de, ics, t)
S = sol[:, 0]
I = sol[:, 1]
R = sol[:,2]
pl.plot(t, S, label = 'Susceptible', color = 'blue')
pl.plot(t, I, label = 'Infected', color = 'red')
pl.plot(t, R, label = 'Recoverands', color = 'green')
pl.xlabel('days(t)')
pl.ylabel('population')
pl.title('SIR model')
pl.legend();

47
Python and Mathematics by Donnie M. Kasyoki

Exercise Write a program to plot the graph showing Susceptible, Exposed, Infected and
Recovered for a whole year given that

dS
= −βSI
dt
dI
= βSI − γE
dt
dE
= γE − σI
dt
dR
= σI
dt
given that at time (days) t = 0, S = 1 − 10−5 , I = 1 − 10−5 , β = 0.8, γ = 0.1, σ = 0.2

48

You might also like