Dr J H Klopper
Department of Biostatistics and Bioinformatics Milken Institute School of Public Health George Washington University
This chapter of Algebra for Health Data Science by Dr JH Klopper is licensed under Attribution-NonCommercial-NoDerivatives 4.0 International
While there are many functions in Python, we can extend the language with packages that contains even more functions.
The sympy
package, short for symbolic Python is a Python package that contains functions for symbolic mathematics. This means that we can use Python to do mathematics in the same way that we would do it by hand. The sympy
packages turns Python into a computer algebra system (CAS).
The import keyword is used to import packages into Python. It is typical to use an abbreviation for packages and use the code import sympy as sym
. This means that we can use the abbreviation sym
to refer to the sympy
package and call functions in the package such as sqrt
(the square root) by typing sym.sqrt
. By not using an abbreviation, we will have to type sympy.sqrt
every time we want to use the square root function. The choice is a matter of style.
import sympy
The init_printing
function is used to make the output of the sympy
package look like typeset mathematics. This is because it use LaTeX to print proper mathematical notation. The init_printing
function has several arguments, which we will not use here.
sympy.init_printing()
Python has a built-in package for mathematics called math
. The math
package does not use symbolic mathematics, but rather numerical mathematics. This means that the math
package will give us numerical answers, while the sympy
package will give us symbolic answers.
import math
The matplotlib
package is a large Python packages used for generating plots. Here we use one of the models in the package called pyplot
.
from matplotlib import pyplot
Monitors with high-resolution screen such as those found on Apple computer can print plotrs with more detail. To make use of the detail, we use a magic command as is shown below.
%config InlineBackend.figure_format = 'retina'
While not the focus of this course, we will perform some statistical tests as motivation for the algebra that we want to explore. The stats
module in the scipy
package contains functions for statistical tests. We will use the ttest_ind
function from this module to perform a t-test.
from scipy.stats import ttest_ind
Lastly, we import the numpy
package, short for numerical Python. This package is used for numerical mathematics and is used to create arrays. Arrays are similar to lists, but are more efficient for numerical calculations.
import numpy
We use numbers every day of our lives. We count objects and we consider costs and spending. While counting usually involves the use of whole numbers, we also consider parts of the whole when we cut a pizza into slices. Pizza slices are fractions of the whole and we pay for the pizza using decimal numbers. Numbers are everywhere in the life sciences. We count, add, multiply, calculate means and standard deviations. The list is endless.
Computers and most computer languages can do mathematics. However, they do not do mathematics in the same way that we do mathematics by hand. Computers use numerical mathematics, which means that they use numbers to represent quantities. This is different from symbolic mathematics, which means that we use symbols to represent quantities. For example, we use the symbol $\pi$ to represent the ratio of the circumference of a circle to its diameter and we use the symbols $x$ and $y$ to denote unknowns, and $f$ and $g$ to denote fuctions. With numpy
and sympy
Python can do both and we will explore how Python works with numbers and mathematical symbols.
In this textbook, we explore mathematics, and algebra in particular. While being able to use a pencil and paper is part of the visceral experience and understanding of mathematics, we live in an era of powerful computers in our pockets and software on our computers. The calculations in these notebooks will be laid out in detail. We will, though, also make use of modern technology to gain a level of familiarity. We will use technology to verify our results or to simply do the calculations for us. We will use modern technology as a tool to learn about and understand the mathematics. Technology is a companion to our pencils and paper.
Our technology partner will be the Python programming language. This is not a set of notebooks on Python and the material will not teach you how to become a Python programmer. It will simply serve as our calculator instead of the calculator on our phones. Along the way, though, we will come to realize how Python can help us build our intuition for the mathematics and how it helps us understand the mathematics. Python will be our teaching aid when we need it.
In this chapter, we explore basic number types and arithmetic as a foundation to exploring the use of algebra in public health and biomedical research in later notebooks. A proper foundation in algebra can be an enjoyable and simple task. Being comfortable with algebra will allow everyone who goes on to study statistics, to concentrate on the understanding of data and its analysis instead of being afraid of or sparring with the mathematics.
In Python we can refer to any item as an object. There are many object types in Python. Not all of these types are numbers.
We use the type
function to return the type of a Python object. Strings are not numbers or mathematical symbols. They are letter, words, sentences, and paragraphs of text. Strings are denoted by their enclosure in single or double quotes. Below we pass the string 'This is Python.'
to the type
function.
type('This is Python.')
str
Python returns the value str
to indicate that the object is a string. Next, we pass the number $1$ to the type
function.
type(1)
int
Python returns the value int
to indicate that the object is an integer. Integers are whole numbers. We can also pass the number $1.0$ to the type
function.
type(1.0)
float
We see that $1.0$ is of type float
. This is short for floating point number. Floating point numbers are numbers with a decimal point. We can also pass the number $1j$ to the type
function.
type(1j)
complex
The 1j
symbol is a complex number. Complex numbers are numbers with an imaginary part. The imaginary part is denoted by the symbol $i$ or $j$. In Python, the symbol $j$ is used to denote the imaginary part of a complex number. The symbol $i$ is used to denote the imaginary part of a complex number in mathematics.
Boolean values are either True
or False
. We can pass the boolean values True
and False
to the type
function.
type(True)
bool
Python returns the value bool
to indicate that the object is a Boolean value.
type(False)
bool
False
is also a Boolean value as indicated by the returned bool
type.
True
and False
in Python are stored as $1$ and $0$ respectively. We can add True
and False
values together.
True + True
False + False
True + False
We can also pass the value None
to the type
function.
type(None)
NoneType
None
indicates that the object has no value and has the specific type NoneType
. This is different from False
, which is a Boolean value.
In mathematics we put the elements of a set in curly braces, $\{ 1,2,3,4, \ldots \}$. A set is any collection of objects, such as all the toppings on a pizza. With respect to numbers, the elememts are just that, numbers Each member (number) is separated by a comma. We also see a set of ellipses, $\ldots$. Intuitively, we read this as a continuation along, or, following the pattern of elements, before the ellipses. This indicates a continuation of the numbers. The numbers never stop. The $\ldots$ at the end of the list of elements indicate an infine extension of values. The numbers go to infinity. We refer to the number of elements in a set as the cardinality or size of the set.
In this section, we investigate the commonly used number system in mathematics.
Consider a list of the smoking status of participants in a study. In the table below, we note $10$ participants. Each participant has either never smoked, smoked in the past, or currently smokes.
Participant | Smoking status |
---|---|
1 | Currently smokes |
2 | Never smoked |
3 | Smoked in the past |
4 | Never smoked |
5 | Never smoked |
6 | Smoked in the past |
7 | Smoked in the past |
8 | Smoked in the past |
9 | Currently smokes |
10 | Currently smokes |
We can count the number of occurrences of each smoking status. We can count the number of participants who never smoked by counting the number of times the smoking status is never smoked. We can count the number of participants who smoked in the past by counting the number of times the smoking status is smoked in the past. Lastly, we can count the number of participants who currently smoke by counting the number of times the smoking status is currently smokes. From the data we note that $3$ participants never smoked, $4$ participants smoked in the past, and $3$ participants currently smoke. We cannot have that three-and-half participants never smoked, nor can we have a negative number of people who cuttenrly smoke. Each count is a counting number.
Definition 1.3.2.1 The counting numbers, symbolized by $\mathbb{N}$, are the set of numbers $\{ 1,2,3,4,\ldots \}$.
To accomodate the case where we count a zero number of participants for a specific smoking status, we add the number $0$ to the set of counting numbers. We call this set of numbers the natural numbers.
Definition 1.3.2.2 The natural numbers, symbokized by $\mathbb{N}_{0}$ are the set of numbers $\{ 0,1,2,3,4,\ldots \}$.
In many cases, we want to consider a range of natural numbers. Age is a good example in public health and biomedical research, that is, caputuring peoples’ age in years. In fancy terms, we would say the unit of measurement of age is years.
We consider a baby in its first year of life as being $0$ years old. Most humans do not live beyond $100$ years of age, let alone an infinite number of years. Maybe one day. As an android. Imagine that. Age can be expressed as a natural number in an interval. An interval (of ages) has a minimum and a maximum value. The minimum and maximum values for a set of age values are often quoted in research papers. In the set $\{ 1,2,3, \ldots , 10 \}$ we use ellipses do denote the we follow the pattern up until a maximum number. In this case, $10$.
To sound like mathematicians, we note that there is an order to the symbols that we use to denote numbers. We know that $5$ is larger than $2$. In fact ordering is an imporant and sophisticated topic in math. Even so, we have a natural intuition for order and make use of it all the time.
It is typical to use a lowercase letter as a symbol for an arbitrary number. For natural numbers, we typically use the symbols $i$, $j$, $k$, and $n$. In human research studies, we have a number of participants in a study. This number of people is referred to as the sample size. In many calculations, we would use the symbols $n$ to denote a sample size. The symbol $n$ takes on a specific value depending on how many people are in our study.
Finally, we visualize the natural numbers (at least the first few) as markers on the horizontal axis of the familiar Cartesian plane (mutually perpendicular lines), shown in Figure 1.3.2.1.
x = range(10)
y = numpy.repeat(0, 10)
pyplot.figure(figsize=(8, 2))
pyplot.scatter(
x=x,
y=y,
s=60,
marker='o',
alpha=.8,
lw=1
)
pyplot.grid(color='0.5')
for pos in ['right', 'top', 'bottom', 'left']:
pyplot.gca().spines[pos].set_visible(False)
It may be useful to include what we refer to as additive inverses to the natural numbers. The additive inverse of a number is the number that we add to the number to get $0$. For example, the additive inverse of $3$ is $-3$ because $3+(-3)=0$. The additive inverse of $-3$ is $3$ because $-3+3=0$. We can extend the natural numbers to include the additive inverses of the natural numbers. We call this set of numbers the integers.
Definition 1.3.2.3 The integers, symbolized by $\mathbb{Z}$ are the whole numbers $\{ \ldots , -3,-2,-1,0,1,2,3, \ldots \}$. The integers is the set of all natural numbers and their additive inverses. The additivive inverse of a natural number $n$ is $-n$ such that $n + (-n) = 0$.
Arbitrary integers are usually denoted by lowercase letters such as $a$, $b$, $c$, $p$, and $q$.
As with natural numbers, there are an infinite number of integers, and we can also specify an interval or intervals of integers.
Consider the case where we have $100$ participants in a study and $34$ of them suffer from hypertension. We might want to express the proportion of participants who have a diagnosis of hypertensions. To do this, we introduce rational numbers.
Definition 1.3.2.4 The rational numbers, symbolized by $\mathbb{Q}$, are defined in Equation 1.3.2.1.
The top number $a$ is the numerator and the bottom number, $b$, is the denominator. Rational numbers are fractions and are often used when we express ratios, shown in Equation 1.3.2.2.
In the case of our $100$ participants where $34$ have hypertensions, we could state that the proportion of hypertensive participants is $34 \div 100 =0.34$. We confirm this calculation using code below.
34 / 100
The word fraction is typically reserved for cases in which the numerator is smaller than the denominator. We consider a fraction of the whole. If we have are investigating $100$ people and $53$ of them are ill, we can concern ourlselves with the fraction of the whole (all $100$ people) that are ill. Fractions are very, very usefull. In resaerch, we often use these fractions as proportions.
The Rational
function in the sympy
package creates a rational number. The numerator and the denominator of the rational number are passed to the Rational
function as arguments, separated by a comma.
sympy.Rational(3, 4)
An integer can also be expressed as a rational number, shown in Equation 1.3.2.3.
Rational numbers can be expressed as decimal numbers and the latter can be expressed as a finite decimal number or a repeating decimal number. We see three such rational numbers in Equation 1.3.2.4, which is then expressed in code. They are treated as numerical value by Python when we do not use the Rational
function from sympy
.
A bar is drawn over the repeating sequences of numbers. The bar is called a vinculum. The vinculum is used to indicate that the sequence of numbers repeats indefinitely. A finite numbert of decimal digits or an infinite number of repeating decimal digits are both hallmarks of rational numbers.
# Example of a finite decimal representation of a rational number
3/4
# Example of a repeating decimal number
1/3
# Example of a longer repeating decimal number (142857 142857)
1/7
In the case of the repeating decimal expansion, the repeating part is truncated in the output. As such, the decimal number is an approximation of the exact rational number as shown in Equation 1.3.2.5.
The set of rational numbers also contain the primes numbers.
While we typically do not concern ourselves with prime nunmbers in the day-to-day analysis of data, we have to mention the prime numbers.
Definition 1.3.2.5 A prime number is an integer that is divisible only by itself AND $1$.
Definition 1.3.2.6 A number $a$ is divisible by a number $b \ne 0$ if there exists an integer $c$ such that $a = bc$. In other words, there is no remainder after division, shown in Equation 1.3.2.6.
By definition, $1$ is not a prime number. The isprime
function in the sympy
package returns True
if the input is a prime number and False
otherwise.
# Use sympy to detrmine if 1 is a prime number
sympy.isprime(1)
False
In the code cell below, we use list comprehension to print the prime numbers between $1$ and $100$.
# Use list comprehension and the isprime function to determine the prime numbers less than 100
[p for p in range(100) if sympy.isprime(p)]
This brings us to our first exmaple problem.
Problem 1.3.2.1 Determine if $997$ is prime.
We use the isprime
function in sympy
and pass the number $997$ as an argument.
sympy.isprime(997)
True
We see that $997$ is indeed a prime number.
Homework 1.3.2.1 Determine if $1001$ is prime.
Defintion 1.3.2.7 A composite number is an integer that is not prime number, and is therefor divisible by at least one other number other than itself or $1$.
The number $16$ is a composite number as it is divisible by $2$ and $8$ and $4$, as well as $1$ and $16$.
# Determine if 16 is a prime number
sympy.isprime(16)
False
The factorint
function in the sympy
package returns the prime factors of a number and how many times each prime factor occurs.
# Determine the prime factorization of 16
sympy.factorint(16)
The factorint
function returns a Python dictionary object (key-value pairs). The keys are the prime factors and the values are the number of times they occur in the prime factorization of the given number. This is termed the multiplicities of a prime factor. For $16$ there is only a single prime. The prime factor is $2$ and there are four $2$’s in the prime facotrization of $16$. We write $16=2^{4}$.
Defintition 1.3.2.8 The prime factorization of a number is the product of its prime factors.
Defintion 1.3.2.9 The multiplicity of a prime factor is the number of times the prime factor occurs in the prime factorization of a number.
Homework 1.3.2.2 Determine the prime factors of $23452$ and their multiplicities.
Definition 1.3.2.10 The set of irrational numbers are the set of numbers that canot be expressed as a ratio of two integers.
# Example of an irrational number
sympy.sqrt(2)
The decimal approximation of $\sqrt{2}$ is calculated below using the evalf()
method.
# Decimal approximation of square root of 2
sympy.sqrt(2).evalf()
There is no termination to, and no repeating pattern in, the decimal expansion of $\sqrt{2}$, making it an irrational number. If a decimal expansion of a number does not terminate or repeat, then it is irrational.
The number $\pi$ is also an irrational number. The pi
function from the sympy
package returns the value of $\pi$. The evalf()
method returns the decimal approximation of $\pi$ to the specified number of digits.
# Print the number pi
sympy.pi
# Print the value of pi with 50 digits
sympy.pi.evalf(50)
So much of the data that we collected are real numbers, which we define in Definition 1.3.2.9.
Defintion 1.3.2.11 The real numbers, $\mathbb{R}$, are the union (combination) of the rational and irrational numbers.
While we are often constrained by the accuracy of our measuring instruments, we can consider the real numbers to be continuous. So, if we state that a person is $6$ foot and $6$ inches tall, it is only an approximation. The person (well me, since I am $6' \, 6''$ tall) is not exactly $6$ foot and $6$ inches tall. The person is $6$ foot and $6$ inches tall to the accuracy of our measurement accuracy.
The real numbers can be represented as a point on the number line. There are an infinite number of real numbers. In many cases, most of the statistical analysis that we do in public health and in biomedical research involve real numbers. We generate some pseudo-random numbers below and assign them to the computer variable x
# Seed the pseudorandom number generator with the integer 1
numpy.random.seed(1)
# Create a variable called x that holds an array of 10 real numbers from the standard normal distribution
x = numpy.random.randn(10)
x
array([ 1.62434536, -0.61175641, -0.52817175, -1.07296862, 0.86540763, -2.3015387 , 1.74481176, -0.7612069 , 0.3190391 , -0.24937038])
Figure 1.3.2.1 shows the number line with the real numbers $x$.
# Plot the values in the array x as markers on the x-axis
pyplot.figure(figsize=(10, 2))
pyplot.scatter(
x,
[0,0,0,0,0,0,0,0,0,0],
color='red',
marker='o',
s=100,
alpha=0.5,
label='x'
)
pyplot.grid()
pyplot.xlim(-3, 3)
pyplot.hlines(0, -3, 3, color='black')
pyplot.gca().spines['top'].set_visible(False)
pyplot.gca().spines['right'].set_visible(False)
pyplot.gca().spines['bottom'].set_visible(False)
pyplot.gca().spines['left'].set_visible(False)
pyplot.title('Figure 1.3.2.1');
We often find that the results of statistical calculations contain values with many decimal places and we need to round these. Look at the p value for the equal variance t test below.
# Seed the numpy pseudorandom number generator with the integer 2
numpy.random.seed(2)
# Create a variable named groupA that holds an array of 100 real numbers from a normal distribution with a mean of 100 and a standard deviation of 10
groupA = numpy.random.normal(100, 10, 100)
# Create a variable named groupB that holds an array of 100 real numbers from a normal distribution with a mean of 101 and a standard deviation of 9
groupB = numpy.random.normal(101, 9, 100)
# Conduct an equal variance t test comparing the values in groupA to those in group Band show the p-value
ttest_ind(groupA, groupB, equal_var=True)[1]
We would typically round this p value to two decimal places and write $0.03$.
The round
function rounds a number to a specified number of decimal places. By default, the number fo decimal places is zero, but the function will add a single decimal place with a value of $0$ to the output.
# Round a number to the nearest whole number
round(10.4)
# Round a number to the nearest whole number
round(10.51)
A decimal digit with a value $5$ and up leads to the preceding digit being rounded up and a decimal value with a value of $4$ and down leads to the preceding decimal digit being rounded down.
Below, we round the p value from our equal variance t test to two decimal places.
# Round the number 10.59 to the nearest tenth (a single decimal place)
round(0.0285355177361664, 2)
Homework 1.4.1.1 Round $3.666666666667$ to two decimal places.
In our solution the value $0.0285355177361664$ was printed to the screen. The decimal digits $0$ and $2$ are in the first two places. The next digit is an $8$, which is $5$ or more. As such, we round the $2$ up to a $3$ and the output is $0.03$.
Rounding to the nearest integer is not always desired. In many statistical tests we calculate the degrees of freedom. Below, we calculate the degrees of freedom for an unequal variance t test. (Ignore the code and consider the results.)
# Seed the numpy pseudorandom number generator with the integer 2
numpy.random.seed(2)
# Create a variable named groupC that holds an array of 100 real numbers from a normal distribution with a mean of 101 and a standard deviation of 20
groupC = numpy.random.normal(101, 20, 100)
# Conduct an unequal variance t test comparing the values in groupA to those in group C and show the degrees of freedom
ttest_ind(groupA, groupC, equal_var=False)
TtestResult(statistic=0.01605247831794392, pvalue=0.9872145027924664, df=145.58823529411765)
We note that the degrees of freedom is $145.58823529411765$. In the case of degrees of freedom, we want to round down.
The math
package has a floor
function that rounds a number down to the nearest integer. The ceil
function rounds a number up to the nearest integer.
# Round down the number 145.58823529411765to the nearest whole number
math.floor(145.58823529411765)
We would state that the T statistic has $145$ degrees of freedom.
As example, we also show the ceil
function for the sake of completeness.
# Round up the number 10.1 to the nearest whole number
math.ceil(10.1)
Homework 1.4.1.2 Determine the ceiling an the floor of $\pi$.
Arithmetic is the branch of mathematics that deals with the study of numbers and their operations. The four basic operations are addition, subtraction, multiplication, and division. We will explore each of these operations in turn.
The +
symbol placed between two numbers add the numbers in Python. Below we calculate $3+4$.
# Adding 3 and 4
3 + 4
More than two numbers can be added. We calculate $3+4+5$.
# Adding 3 and 4 and 5
3 + 4 + 5
Problem 1.4.2.1 Calculate $3+4+5+6+7+8+9+10$.
We use the +
symbol to add the numbers.
3 + 4 + 5 + 6 + 7 + 8 + 9 + 10
Homework 1.4.2.1 Calculate $1+2+3+4+5+6+7+8+9+10$.
The -
symbol placed between two numbers subtracts the second number from the first number in Python. We calculate $3-4$.
# Subtracting 4 from 3
3 - 4
More than one number can be subtracted. We calculate $23-6-10$.
# Subtracting 6 and 10 from 23
23 - 6 - 10
Problem 1.4.3.1 Calculate $23-6-10-4-5-6-7-8-9-10$.
We use the -
symbol to subtract the numbers.
23 - 6 - 10 - 4 - 5 - 6 - 7 - 8 - 9 - 10
Homework 1.4.3.1 Calculate $100-1-2-3-4-5-6-7-8-9-10$.
The *
symbol between two numbers multiplies the numbers in Python. We calculate $3 \times 4$.
# Mutiplying 3 and 4
3 * 4
More than two numbers can be multiplied. We calculate $3 \times 4 \times 2$.
# Multiplying 3 and 4 and 2
3 * 4 * 2
Problem 1.4.4.1 Calculate $3 \times 4 \times 2 \times 5 \times 6 \times 7 \times 8 \times 9 \times 10$.
We use the *
symbol to multiply the numbers.
3 * 4 * 2 * 5 * 6 * 7 * 8 * 9 * 10
Homework 1.4.4.1 Calculate $1 \times 2 \times 3 \times 4 \times 5 \times 6 \times 7 \times 8 \times 9 \times 10$.
The forward slash /
symbol between two numbers divides the first number by the second number in Python. We calculate $10$ divided by $2$.
# Dividing 10 by 2
10 / 2
Note that we can write division using the $\div$ symbols as $10 \div 2$. We can also use the notation in Equation 1.4.5.1.
In the notation used in Equation 1.4.5.1, the number above the line is called the numerator and the number below the line is called the denominator.
Problem 1.4.5.1 Calculate $10$ divided by $2$ divided by $5$.
We use the /
symbol to divide the numbers.
10 / 2 / 5
Homework 1.4.5.1 Calculate $100$ divided by $2$ divided by $5$.
We use short-hand notation when we want to multiply a number by itself a number of times. Instead of writing $2 \times 2 \times 2$, which is $2$ multiplied by itself $3$ times, we write $2^{3}$, placing the $3$ as a superscript after the $2$. This short-hand notation shows $2$ raised to the power $3$, which simply means $2$ multiplied by itself $3$ times.
Th double star symbol **
between two numbers raises the first number to the power of the second number in Python. We calculate $2$ raised to the power of $3$ or $2 \times 2 \times 2$.
# 2 to the power of 3
2 ** 3
Problem 1.4.6.1 Calculate $2$ raised to the power of $4$.
Equation 1.4.6.1 shows the general form of the power in this problem.
Homework 1.4.6.1 Calculate $2$ raised to the power of $5$.
Problem 1.4.6.2 Calculate $3$ raised to the power of $2$ raised to the power of $3$.
Equation 1.4.6.2 shows the mathematical notations for this problem.
We use the **
symbol to raise the first number to the power of the second number.
3**2**3
Consider the number resulting form $3 \times 3$. The result is $9$. We state that the square roots of $9$ is $3$.
Definition 1.4.7.1 The square root of a number $a$ is the number $b$ such that $b \times b = a$. We write $b = \sqrt{a}$.
We can also write $\sqrt{a}$ as $a^{\frac{1}{2}}$.
Below, we calculate the square root of $9$ using the calculation in Equation 1.4.7.1.
# Positive square root of 9
9 ** (1/2)
We can also use the sqrt
function in the math
package to calculate the square root of $9$.
# Positive square root of 9 using the sqrt function from numpy
math.sqrt(9)
Only the positive square root value is returned. We do remember that $\left(-3\right)^{2}$ is also equal to $9$.
# Show that -3 squared is 9
(-3) ** 2
The sympy
package has a sqrt
function that calculates the square root of a number analytically. We calculate the square root of $10$ using the sqrt
function.
# Symbolic computation of the square root of 10
sympy.sqrt(10)
Note that the exact solution $\sqrt{10}$ is returned. We can also use the evalf
method to return the decimal approximation of the square root of $10$ in sympy
.
# Symbolic computation of the square root of 10 using numerical approximation
sympy.sqrt(10).evalf()
Problem 1.4.7.1 Calculate the square root of $81$.
We use the sqrt
funtion in the sympy
package to calculate the square root of $81$.
sympy.sqrt(81)
Homework 1.4.7.1 Calculate the square root of $100$.
The sympy
package can manage the square root of negative numbers. We calculate the square root of $-9$.
sympy.sqrt(-9)
We see a complex number returned. The sympy
package uses the symbol $i$ to denote the imaginary part of a complex number.
We can also calculate higher roots. Below we calculate the cube root of $27$, using the calculation in Equation 1.4.8.1.
# Cube root of 27
27 ** (1/3)
Next we calculate the root in Equation 1.4.8.2.
# Fourth root of 16
16 ** (1/4)
Obviously $-2$ is also a solution to $\sqrt[4]{16}$ since $(-2) \times (-2) \times(-2) \times(-2) =16$. We confirm this result using code below.
# Show that (-2) to the power of 4 is 16
(-2) ** 4
Problem 1.4.8.1 Calculate the cube root of $64$.
We use power notation, **
, in Python to calculate the cube root of $64$.
64**(1/3)
The sympy
package contains the root
function that calculates the $n$-th root of a number. We calculate the cube root of $64$ using the root
function.
# Calculate the cube root of 64 using sympy
sympy.root(64, 3)
Homework 1.4.8.1 Calculate the cubic root of $1000$. Use pure Python (the exponentiation operator **
), the math
package, and the sympy
package. Try to explain the difference in the results.
The absolute value of a number is the distance of the number from zero on the number line. The absolute value of a number is always positive. It is written as $\lvert a \rvert$.
The abs()
function from the numpy
package returns the absolute value of a number. We calculate $\lvert -3 \rvert$ below.
# Asbolute value of -3
abs(-3)
Defintion 1.4.9.1 The absolute value of a number $a$ is defined in Equation 1.4.9.1.
Form the defintion we have see why $\lvert -3 \rvert = - (-3) = 3$.
Logarithms are very frequenctly used in health data science. In Figure 1.4.10.1 we show a histogram of the age of participants in a study. (Ignore the code and consider the results.) We see that the distribution of age is skewed to the right. We can transform the data using a logarithm to make the distribution more symmetric, shown in Figure 1.4.10.2.
# Create an array of 100 values for a variable named "age" that is right-skewed
age = numpy.random.gamma(2, 2, 100)
# Create a histogram of the values in the array Age
pyplot.figure(figsize=(10, 2))
pyplot.hist(
age,
color='red',
alpha=0.5,
bins=20
)
pyplot.grid()
pyplot.xlim(0, 20)
pyplot.gca().spines['top'].set_visible(False)
pyplot.gca().spines['right'].set_visible(False)
pyplot.gca().spines['bottom'].set_visible(False)
pyplot.gca().spines['left'].set_visible(False)
pyplot.title('Figure 1.4.10.1');
# Recreate the histogram but use a logarithm transformation of the values in the array age
pyplot.figure(figsize=(10, 2))
pyplot.hist(
numpy.log(age),
color='red',
alpha=0.5,
bins=20
)
pyplot.grid()
pyplot.xlim(0, 3)
pyplot.gca().spines['top'].set_visible(False)
pyplot.gca().spines['right'].set_visible(False)
pyplot.gca().spines['bottom'].set_visible(False)
pyplot.gca().spines['left'].set_visible(False)
pyplot.title('Figure 1.4.10.2');
The logarithm of a number is defined by a base. As an example, we consider a base $10$. We can raise $10$ to any power. As an example we have that $10^{2}=100$. For the number $100$ and the base $10$, we would state that the logarithm base $10$ of $100$ is $2$, since it is $10$ raised to the power $2$ that is $100$. For the values $a,b,c$, we state the logarithm in Equation 1.4.10.1.
From the defintion we note that $c>0$, since a positive value raised to any real-valued power is positive.
The log()
function from the numpy
package calculates the logarithm of a number. The default base is $e$, Euler's number.
# Natural log of 1000
numpy.log(1000)
The sympy
package can also calculate logarithms. The log()
function from the sympy
package calculates the logarithm of a number. The default base is $e$. Note that sympy
returns an exact value.
sympy.log(1000)
To return a number approximation in sympy
, we use the evalf
method.
sympy.log(1000).evalf()
Euler's number, $e$, is approximated below using the numpy
function exp
. We pass the argument value $1$, since any number raised to the power $1$ is itself and so $e^{1}=e$.
# Express Euler's number e as a decimal number
numpy.exp(1)
Once again, sympy
returns an exact value.
sympy.exp(1)
Problem 1.4.10.1 Calculate the logarithm base $e$ of $43545$.
The log
function from the numpy
package is used to calculate this natural logarithm.
numpy.log(43545)
The log10
function from the numpy
package calculates the logarithm of a number with a base of $10$.
# Log base 10 of 1000
numpy.log10(1000)
Homework 1.4.10.1 Calculate the logarithm base $10$ of $43545$.
Homework 1.4.10.2 Calculate the natural logarithm of $43545$.
Euler's number is useful when modeling growth or decay. For a simple model, we may have exponential growth at every time step $t$. The number of cases may then be as shown in Equation 1.4.11.1 with the number of cases at $t=0$ of $1$.
At time $t=5$, we have $e^{5}$ organisms, which is $e \times e \times e \times e \times e$, calculated below using the exp
function in numpy
.
numpy.exp(5)
We can use the floor
function to round the result down.
# Round exp(5) to 3 digits
math.floor(numpy.exp(5))
Starting with $e^{0}=1$ organism at $t=0$, we have that there will be $148$ organisms as $t=5$. Figure 1.4.11.1 demonstrates the growth.
fig, ax = pyplot.subplots()
ax.plot([0, 1, 2, 3, 4, 5],
[numpy.exp(t) for t in [0, 1, 2, 3, 4, 5]],
"b--")
ax.grid()
ax.set_title("Figure 1.4.11.1")
ax.set_xlabel("Time")
ax.set_ylabel("Number of cases")
pyplot.hlines(0, 0, 5, color='black')
pyplot.vlines(0, 0, 150, color='black')
pyplot.gca().spines['top'].set_visible(False)
pyplot.gca().spines['right'].set_visible(False)
pyplot.gca().spines['bottom'].set_visible(False)
pyplot.gca().spines['left'].set_visible(False);
We will learn more about exponents in later chapters.
We will commonly use the following order of arithmetic operations, expressed using the acronymn PEMDAS.
We start by calculating $3+2 \times 4$, which is $3 + (2 \times 4) = 3 + 8 = 11$.
# Expression with addition and multiplication
3 + 2 * 4
We can use parenthesis to first add $3+2$ and then multiply by $4$. This is $(3+2) \times 4 = 5 \times 4 = 20$.
# Using parenthesis to change the order of operations (addition before multiplication)
(3 + 2) * 4
In the examples below, we simplificy the indicated expressions, where the symbol $\cdot$ indicates multiplication.
Problem 1.4.12.1 Calculate the expression in Equation 1.4.12.1.
(3 * 2)**2 - 4 * (6 + 2)
Problem 1.4.12.2 Calculate the expression in Equation 1.4.12.2.
((5**2 - 4) / 7) - numpy.sqrt(11 - 2)
Problem 1.4.12.3 Calculate the expression in Equation 1.4.12.3.
6 - abs(5 - 8) + 3 * (4 - 1)
Homework 1.4.12.1 Calculate the expression in Equation 1.4.12.4.
There are many useful properties of real numbers. We will explore some of these properties in this section.
Defintion 1.5.1 The commutative property of addition states that the order of the numbers does not matter. We have that $a+b=b+a$ for two real numbers $a$ and $b$
We use the comparison operator ==
to test if two numbers are equal. The output is a boolean value, either True
or False
.
Problem 1.5.1 Determine if $3+4=4+3$.
# Show that 3 + 4 = 4 + 3
3 + 4 == 4 + 3
True
The result is the boolean value True
, which indicates that indeed $3+4=4+3$.
Defintion 1.5.2 The commutative property of multiplication states that the order of the numbers does not matter. We have that $a \cdot b = b \cdot a$ for two real numbers $a$ and $b$.
Problem 1.5.2 Determine if $3 \times 4 = 4 \times 3$.
# Show that 3 x 4 = 4 x 3
3 * 4 == 4 * 3
True
Neither subtraction nor division is commutative. The !=
comparison operator tests if two numbers are not equal.
Problem 1.5.3 Determine if $3-4=4-3$.
# Show that 3 - 4 is not equal to 4 - 3
3 - 4 != 4 - 3
True
By using the is equal to ==
comparison operator, we see that $3-4 \neq 4-3$, by considering that the result is False
. The $\neq$ symbol means that the tow sides are not equal to each other.
# Alternative way to show that 3 - 4 is not equal to 4 - 3
3 - 4 == 4 - 3
False
Problem 1.5.4 Determine if $10 \div 5 = 5 \div 10$.
We use the /
symbol for division and consider the cases using !=
and ==
.
# Show that 10 divided by 5 is not equal to 5 divided by 10
10 / 5 != 5 / 10
True
# Alternative way to show that 10 divided by 5 is not equal to 5 divided by 10
10 / 5 == 5 / 10
False
Defintion 1.5.3 The associative property of addition holds such that $a + (b + c) = (a + b) + c$, for three real numbers $a,b,c$.
Problem 1.5.5 Determine if $3 + (4 + 5) = (3 + 4) + 5$.
# Show that (3 + 4) + 5 is equal to 3 + (4 + 5)
(3 + 4) + 5 == 3 + (4 + 5)
True
Definition 1.5.4 The associative property of multiplication holds such that $a \cdot (b \cdot c) = (a \cdot b) \cdot c$, for three real numbers $a,b,c$.
Problem 1.5.6 Determine if $\left( 3 \times 4 \right) \times 5 = 3 \times \left( 4 \times 5 \right)$.
# Show that (3 x 4) x 5 is equal to 3 x (4 x 6)
(3 * 4) * 5 == 3 * (4 * 5)
True
Associativity does not hold for subtraction or division. We see an example of subtraction below, where the ==
logical operator tests if two numbers are equal and returns a value of False
when comparing $(10-3)-2$ and $10 - (3 - 2)$.
# Show that (10 - 3) - 2 is not equal to 10 - (3 - 2)
(10 - 3) - 2 == 10 - (3 - 2)
False
Defintion 1.5.5 The distributive property holds such that $a(b + c) = ab + ac$, for three real numbers $a,b,c$. That is to say that multiplication distributes over addition. The distributive property also holds for subtraction. It does, however, not hold for division, nor for addition or subtraction over multiplication.
Problem 1.5.7 Determine if $3 \left( 2 + 7 \right) = \left( 3 \times 2 \right) + \left() 3 \times 7 \right)$.
# Show that 3(2 + 7) is equal to 3 x 2 + 3 x 7
3 * (2 + 7) == 3 * 2 + 3 * 7
True
There is a special case of distributivity that holds for subtraction. We have that $a - (b + c) = a - b - c$, for three real numbers $a,b$ and $c$.
Problem 1.5.8 Determine if $3 - \left( 2 + 1 \right) = 3 - 2 - 1$.
# Show that 3 - (2 + 1) is equal to 3 - 2 - 1
3 - (2 + 1) == 3 - 2 - 1
True
Definition 1.5.6 The number $0$ is the additive identity of real numbers. We have that $a + 0 = a$ for any real number $a$.
Problem 1.5.9 Determine if $5 + 0 = 5$.
# Show to 5 + 0 = 5
5 + 0 == 5
True
Definition 1.5.7 The number $1$ is the multiplicative identity of real numbers. We have that $a \cdot 1 = a$ for any real number $a$.
Problem 1.5.10 Determine if $5 \times 1 = 5$.
# Show that 5 x 1 i s equal to 5
5 * 1 == 5
True
Defintion 1.5.8 The additive inverse of a real number $a$ is the number $-a$ such that $a + (-a) = 0$.
Problem 1.5.11 Determine if $5 + \left( -5 \right) = 0$.
# Show that 5 + (-5) is equal to 0
5 + (-5) == 0
True
Problem 1.5.12 Show that $3$ is the additive inverse of $-3$.
If $3$ is the additiive inverse of $-3$ then $3 + \left( -3 \right)$ should be equal to $0$.
# Show that 3 is the additive inverse of -3
(-3) + 3 == 0
True
Since the additive inverse of any number $a$ is $-a$ we have that the additive inverse of $-3$ is $- \left( -3 \right)$, which is $3$.
Definition 1.5.9 The multiplicative inverse of a real number $a$ is the number $\frac{1}{a}$ such that $a \cdot \frac{1}{a} = 1$ and $a \ne 0$.
Problem 1.5.13 Show that $\frac{1}{5}$ is the multiplicative inverse of $5$.
# Show that 5 x (1/5) is equal to 1
5 * (1/5) == 1
True
In health data science we often have to consider values that are fractions. Fractions involve division, which we also commonly use in ratios.
A fraction is a part of a whole and is calculated using division. A ratio similarly involves division.
We see both, and the fact that we accomplish both calculations by division, in Equation 1.6.1.1. In either case, $a$ and $b$ are integers and we always have that $b \ne 0$. We also omit the case where $a=b$, which is simply $1$. We also remeber that if $a=0$, we have that our fraction or ratio is $0$.
$$ \begin{align*} &\text{Fraction: } \frac{a}{b}, \text{ where } b \ne 0 \\ \\ &\text{Ratio: } a:b , \text{ where we calculate } \frac{a}{a+b} \text{ and } \frac{b}{a+b} \\ \\ &\;\;\;\text{ and } a+b \text{ is never equal to } 0 \end{align*} \tag{Equation 1.6.1.1}
It is important to understand the basics of fractions and ratios. The basics include the mechanics of the parts of a fraction or a ratio and the comparison of different fractions and ratios.
We have seen that a fraction or a ratio has a numerator and a denominator. Note that in the case of ratios we also use the terms divided or antecedent for the numerator and the term consequent for the denominator. A fraction describes a count of parts of a whole. By parts of the whole, we are referring to the denominator. The numerator describes how many of those parts we count.
Consider any shape, such as a square or a circle. We can divide a shape into equal parts. That would be $b$ equal parts. If $b=2$ then we have divided the shape into halves. If $b=4$, then we have divided the shape into $4$ equally sized parts called quarters. This is the value of the denominator.
The numerator, $a$, counts the number of $b$-parts of the whole. In Figure 1.6.1.1, we have divided the whole (of a circle) into $b=4$ equal parts (the denominator) and we consider $a=3$ of those $b=4$ parts (the numerator).
pyplot.pie(
[1, 1, 1, 1],
colors=['red', 'red', 'red', 'lightgray'],
wedgeprops={"edgecolor":"k",'linewidth': 1}
)
pyplot.title('Figure 1.6.1.1')
pyplot.show()
In Figure 1.6.1.2, we visualize the difference between three eights and seven eights, seen in Equation 1.6.1.2. We keep $b=8$ fixed and compare $a=3$ to $a=7$.
fig, ax = pyplot.subplots(1, 2)
ax[0].pie(
[1, 1, 1, 1, 1, 1, 1, 1],
colors=['red', 'red', 'red', 'lightgray', 'lightgray', 'lightgray', 'lightgray', 'lightgray'],
wedgeprops={"edgecolor":"k",'linewidth': 1}
)
ax[1].pie(
[1, 1, 1, 1, 1, 1, 1, 1],
colors=['red', 'red', 'red', 'red', 'red', 'red', 'red', 'lightgray'],
wedgeprops={"edgecolor":"k",'linewidth': 1}
)
ax[0].set_title('Figure 1.6.1.2')
pyplot.show()
With a good understanding of the parts of a fraction or a ratio, we consider the mechanics. By the mechanics we mean, changes in the values of $a$ or $b$, where we consider a change in one, while keeping the other constant.
If we keep $b$ constant and we increase $a$, we are counting more of the parts. The actual overall value that the fraction or ratio describes gets bigger. If we decrease $a$, then we have fewer parts, and the overall value gets smaller.
In Figure 1.6.1.3, we visualize the difference between three eighths (on the left) and three fifths (on the right), seen in Equation 1.6.1.3.
fig, ax = pyplot.subplots(1, 2)
ax[0].pie(
[1, 1, 1, 1, 1, 1, 1, 1],
colors=['red', 'red', 'red', 'lightgray', 'lightgray', 'lightgray', 'lightgray', 'lightgray'],
wedgeprops={"edgecolor":"k",'linewidth': 1}
)
ax[0].set_title('Figure 1.6.1.3')
ax[1].pie(
[1, 1, 1, 1, 1],
colors=['red', 'red', 'red', 'lightgray', 'lightgray'],
wedgeprops={"edgecolor":"k",'linewidth': 1}
)
pyplot.show()
It is clear that $3$ parts of $8$ must be smaller than $3$ parts of $5$. In essence, keeping the numerator constant, the final values increases when the denominator get smaller and decreases when the demominator gets bigger.
Understanding the mechanics, leads us to comparing fractions and ratios. When is one smaller or larger than the other?
To answer this question, we must have equal $b$ parts (equal denominators). In Equation 1.6.1.3 we made such a comparison. We can make a direct comparison by equalling $b=8$ and $b=5$. The easiest way to do this is to start by considering multiplying both by $1$. The number $1$ can be written as a fraction, in many ways, as we see in Equation 1.6.1.4, as long as $b \ne 0$.
Multiplying by $1$ does not change a number. All we have to do is write $1$ as a fraction. We do so my choosing the opposite value of $b$, shown in Equation 1.6.1.5, remembering that we multiply numerator by numerator and denominator by denominator, we now have equal parts $b=40$.
Clearly $15 < 21$ and three eighths is smaller than three fifths.
The sympy
package makes such a comparison easy. We use the Rational
function to create the fractions and the >
and <
symbols (which are comparison operators) to compare the fractions. We print the two fractions to the screen to see the use of the Rational
function.
# Print the rational three-eighths
sympy.Rational(3, 8)
# Print the rational three-eighths
sympy.Rational(3, 8)
In the code cell below, we ask the question: Is three eighths smaller than three fifths? Note the use of the less than <
comparison operation.
sympy.Rational(3, 8) < sympy.Rational(3, 5)
The sympy
package returns True
to indicate that three eighths is smaller than three fifths.
Depending on the propblem, we can multiply both sides by $1$ expressed in smaller values for the numerator and denominator. The next problem shows the intuition.
Problem 1.6.1.1 Compare the two fractions in Equation 1.6.1.6 and determine which is larger.
The results is shown in Equation 1.6.1.7.
Clearly, three eights is larger than two eights and therefor three-eights is larger than a quarter.
We use sympy
again to verify the result. Note that in this case we use the larger than >
comparison operator.
sympy.Rational(3, 8) > sympy.Rational(1, 4)
If we use the less than <
comparison operator (keeping the order of the fractions the same), we get False
.
sympy.Rational(3, 8) < sympy.Rational(1, 4)
Problem 1.6.1.1 Is $\frac{21}{43}$ larger than $\frac{51}{100}$?
We multiply both sides with $1$ as represented in Equation 1.6.1.8.
We note that $\frac{21}{43}$ is not larger than $\frac{51}{100}$. In fact, it is smaller. We confirm this with code below.
sympy.Rational(21, 43) > sympy.Rational(51, 100)
We do not require the Rational
function to create the fractions. We can simply use the /
symbol to create the fractions and the great than >
or less than <
comparison operators as required.
(21 / 43) > (51 / 100)
False
Homework 1.6.1.1 Is $\frac{3}{13}$ smaller than $\frac{7}{30}$?
The multiplication of fractions is quite simple. In Equation 1.6.2.1, we see two fractions, where each of $a,b,c$, and $d$ are integers, and neither $b$ nor $d$ are equal to $0$.
Equation 1.6.2.2 shows an example of multiplying two fractions.
We use sympy
to solve the problem.
sympy.Rational(3, 11) * sympy.Rational(7, 20)
Below, we calculate the same product using simple Python mathematical notation.
(3 / 11) * (7 / 20)
The result is a numerical approximation.
Note that sympy
will automatically simplify any fraction. In Equation 1.6.2.3 we see such a simplification where five tenths is eqal to a half.
Below, we see that sympy
simplifies the fraction.
sympy.Rational(5, 10)
We have seen that comparisons of fractions are easier when the denominator is the same. Arithmetic with fraction is in general easier when the denominators are the same. In fact, in the case of addition and subtraction the denominators have to be the same. To do this, we need to find the least common multiple.
In Equation 1.6.3.1, we see the addition of two fractions. We rewrite each fraction by multiplying it by $1$, written as a fraction where the numerator and denominator are the denominator of the other fraction.
In Equation 1.6.3.2, we see an alternative way to solve Equation 1.6.3.1.
We have recognized that $12$ is the least common multiple between $4$ and $6$. Both $4$ and $6$ divide $12$. We can use the lcm
function from the sympy
package to find the least common denominator.
sympy.lcm(4, 6)
We still have to determine if the solutions in Equation 1.6.3.1 and in Equation 1.6.3.2 are the same. To do this, we see the rule of addition of fractions in Equation 1.6.3.3. Fractions can only be added (or subtracted) if they have the same denominator. The addition of two fractions with the same denominator is shown in Equation 1.6.3.3 where $c \ne 0$ and $a,b,$ and $c$ are integers.
Our two solutions are shown in Equation 1.6.3.4.
These two fractions are indeed the same. In Equation 1.6.3.5 we simplify thirty-eight twenty-fourths by multiplying it by $1$ in the form of a half over a half.
We can use sympy
to verify this.
sympy.Rational(38, 24)
This brings us to an important topic for the least common multiple. We can break down or rewrite any integer into the multiplication of other interegers. In more advanced algebra, we learn that these other integers (if the break down is complete) are all prime numbers (numbers that are only divisible by $1$ and themselves). We see an example in Equation 1.6.3.6, where we consider the integers that multiply to get $18$ and $9$, with $18 = 2 \times 3 \times 3$ and $9 = 3 \times 3$.
We have taken care to write similar numbers in the same columns. In Equation 1.6.3.7, we add a new line by bringing down or representing all the numbers.
If we multiply the numbers in the new row in Equation 1.6.3.7, we find the least common multiple of $18$ and $9$, which is $2 \times 3 \times 3 = 18$. So, instead of Equation 1.6.3.8, we can do Equation 1.6.3.9.
We recognized that we do not have to perform the multiplication by rewriting $1$ as a fraction using the other fraction's denominator. Since $18$ was the least common multiple, we only have to consider how to change the $9$ into an $18$ and that was mutiplying by $2$.
Problem 1.6.3.1 Find the least common multiple of $12$ and $15$.
The process of breaking down or factoring an integer can be tedious. For the relatively small integers that we deal with in the life sciences, we can start by dividing repeatedly by $2$, then $3$, then $5$, and so on, using the primes in an iterative process. Remember, that primes are only divisible by $1$ and themselves. We do so for $12$ and $15$ in Equation 1.6.3.10
We have that $2 \times 2 \times 3 \times 5 = 60$. This is smaller than $12 \times 15 = 180$. We can use the lcm
function from the sympy
package to verify our result.
sympy.lcm(12, 15)
Homework 1.6.3.1 Find the least common multiple of $13$ and $17$.
Problem 1.6.3.2 Add the fractions in Eqiation 1.6.3.11.
We have to turn $12$ into $60$ and $15$ into $60$. This is simple and is shown in Equation 1.6.3.12.
We have found the way to rewrite $1$ as fractions for this problem. The solution is shown in Equation 1.6.3.13.
We use sympy
to confirm the result.
sympy.Rational(5, 12) + sympy.Rational(7, 15)
Homework 1.6.3.2 Add the fractions in Equation 1.6.3.14.
A fraction does not change in value if we divide the numerator and the denominator by the same value. This is shown in Equation 1.6.4.1.
In Equation 1.6.4.2, we note the equality between six-eights and a three-quarters.
In the case of six-eigths, we can divide the numberator and the denominator by the same number (and hence not change the value of the fraction). In this case, we can divide both by $2$ to get theee quarters. To do the simplification, we made use of the fact that $2$ divides both $6$ and $8$.
We could not divide $3$ and $4$ by another integer that divides both $3$ and $4$. By divides in this case, we mean, division without a remainder, or then, a remainder of $0$.
Consider, though, dividing $11$ by $4$. We know that $4$ does not divide $10$. If we divide $11$ by $4$ and still require this division to produce a whole number, we can at best get $2$ with a remainder of $3$. We see this in Equation 1.6.4.3.
We have that $4$ divides into $11$ twice, with a remainder of $3$ since $2 \times 4 = 8$ and $8 + 3 = 12$. We can write this in more egneral terms as shown in Equation 1.6.4.4.
If $r=0$, we say that $a$ divides $b$ and $b=ca$, or then, $b$ is a constant multiple of $a$.
Problem 1.6.4.1 Caclulate the remainder when $13$ is divided by $2$.
We note that $2$ goes into $13$ a total of $6$ times. Since $6 \times 2 = 12$, we have a remainder of $1$. In Equation 1.6.4.5 we see the calculation. In the last line we also see a common notation for the remainder, where we state that $13$ divided by $2$ is $6$ and a half.
The Mod
function in sympy
returns the remainder and we use it below to verify the result.
sympy.Mod(13, 2)
Homework 1.6.4.1 What is the remainder when we divide $125$ by $7$.
In this section, we take a brief look at basic trigonometry. The trigonomtery that we explore here concenrs the right triangled triangle. A right triangle is a triangle with one angle of $90^{\circ}$.
Figure 1.7.1 shows a right triangle with the angle $\theta$. The sides are named in relation to the angle $\theta$.
# Use matplotlib to plot a triangle
fig, ax = pyplot.subplots()
ax.plot([0, 1, 0, 0], [0, 0, 1, 0], 'k')
ax.set_title('Figure 1.7.1')
pyplot.xlim(-1, 1.5)
pyplot.ylim(-0.5, 1.5)
pyplot.vlines(0, 0, 1, color='black')
pyplot.gca().spines['top'].set_visible(False)
pyplot.gca().spines['right'].set_visible(False)
pyplot.gca().spines['bottom'].set_visible(False)
pyplot.gca().spines['left'].set_visible(False)
pyplot.text(0.25, -0.125, 'adjacent', fontsize=12, color='black')
pyplot.text(-0.5, 0.5, 'opposite', fontsize=12, color='black')
pyplot.text(0.55, 0.5, 'hypoteneuse', fontsize=12, color='black')
pyplot.text(0.75, 0.047, r'$\theta$', fontsize=12, color='black')
pyplot.xticks([])
pyplot.yticks([])
pyplot.show()
The trigonometric functions sine, cosine, tangent, cosine, secant, and cotangent are defined in Equation 1.7.1.
It is common to use $\pi$ when dealing with trigonometric functions. We can express $pi$ as a numerical approximation using the numpy
package and as an exact value using the sympy
package.
numpy.pi
sympy.pi
There are two common measures of any angle $\theta$. We can use degrees or radians. Degrees span a circle from $0^{\circ}$ to $360^{\circ}$. Radians span a circle from $0$ to $2\pi$. We can convert between degrees and radians using Equation 1.7.2.
We can also use code to convert between degrees and radians. We use the radians
function from the numpy
package to convert degrees to radians. We use the degrees
function from the numpy
package to convert radians to degrees.
numpy.radians(180)
numpy.degrees(numpy.pi)
Problem 1.7.1 Calculate the sine of $\pi$ radians.
The sympy
package contains functions for all the trigonometric functions. These functions use angles is radians. We use the sin
function to calculate the sine of $\pi$.
# Calculate the sime of pi radians
sympy.sin(sympy.pi)
Problem 1.7.2 Calculate the cosine of $\frac{\pi}{2}$ radians.
We use the cos
function from the sympy
package to calculate the cosine.
# calculate the cosine of a half pi radians
sympy.cos(sympy.pi / 2)
Problem 1.7.3 Calculate the tangent of $\frac{\pi}{6}$.
We use the tan
function from the sympy
package to calculate the tangent.
# calculate the tangent of pi over 6
sympy.tan(sympy.pi / 6)