Convert Overnight some submissions have arrived in Canvas. Let's open some and take a look. You can download them in .zip or .tar format.
Looking at the submissions, we could see that there were some inefficiencies. One item of interests: you need to know how to use list comprehensions. We show an example here.
List Comprehensions Some of you don't know about this. Corey Shafer's Video will fill you in. Watch it. Here is an example.
>>> x = [2,5,7,2,9,5]
>>> y = [k*k for k in x]
>>> y
[4, 25, 49, 4, 81, 25]
>>> z = [k*k for k in x if k*k*k < 200]
>>> z
[4, 25, 4, 25]
Don't do this.
>>> out = []
>>> for k in x:
... if k*k*k < 200:
... out.append(k*k)
...
>>>
The Weierstraß Intermediate Value Theorem
Theorem Suppose that f is a continuous function defined on the interval [a,b]. If y is any value between a and b, then there is some x ∈ [a,b] so that f(x) = y.
This is an existence theorem, but it can be used to develop an algorithm for approximating a root of a function.
The graph of f must cross the horizontal line at y.
Suppose we want to compute \(\sqrt{2}\). It is very easy to see that the function \(f(x) = x^2 - 2\) has \(\sqrt{2}\) as a root. Since \(f(1) = -1\) and \(f(2) = 2\), the intermediate value theorem tells us that \(f\) must have a root in the interval \([1, 2]\). We can approximate this root with \(1.5\) with a greatest possible error of $\(\pm .5\)$.
Next, compute \(f(1.5) = .25\). Since \(f(1) \lt 0\), the function \(f\) changes sign on \([1, 1.5]\). We have are close to a root at 1.25 with error \(\pm .25\).
You can continue in this fashion until the error is as small as you wish, since the error halves with each iteration.
You will implement this algorithm in zero_finder.py
.
A Little Number Theory
Divisibility Much of number theory revolves around the divisibility and factorization of integers. This apparatus has far-reaching applications in cryptography.
Definition We write d | a, and say "d divides a" if some integer q, a = d*q. We can test for this in in Python, Java, C, or JS using a%d == 0.
Here is an interesting question. If d | a and d | b, what else is divisible by d?
This is true for certain, per zhang22b
: d*d | ab.
We also have this: d | a + b.
Let's prove it.
We can write Write a = d*q for some integer q, and we can write b = d*r for some integer r. Then a + b = d*(q + r);since q + r is an integer, d | a + b.
Next we ask: What divides zero evenly? Every integer divides 0!
Here's something even more useful.
Suppose that x and y are integers. Then, using what we wrote above we have
a*x + b*y = d*q*x + d*r*y = d*(q*x + r*y).
We can conclude that
d | a*x + b*y
The gcd
Function
For integers a and b that are not both 0, we define gcd(a,b) to be the greatest common divisor of a and b. Note that 1 is a common divisor of any two integers, and that no divisor of a and b is larger than max(a,b), so this thing exists.
Note that gcd(0,0) is not defined, because 0 is divisible by every integer.
If you are writing this function, you need to do this.
- java:
throw new IllegalArgumentException();
- python:
raise ValueError
Reminder: Exceptions in Java
Here is the Throwable
subtree.
---------------- | Throwable | ---------------- / \ ------------ ------------- | Error | | Exception | ------------ ------------- | | DEATH -------------------- | RuntimeException | --------------------
Error
: This is when something goes badly wrong. The result is inevitable program death.Exception
: These are runtime errors that are recoverable errors. To prevent program death, you must use a try-catch progression.RuntimeException
: an exception for which a try-catch progression is optional. Usually, but not always, these are caused by programmer goofs.
Theorem Suppose b, q, a and r are integers and that b = a*q + r. then gcd(a, b) = gcd(a, r).
Proof. Suppose d | a and d|b. Then d | b - a*q. So, d|r. d is common divisor of a and r.
Suppose d | a and d | r. Then d | a*q + r. So d|b. Every common divisor of a and r is a common divisor of a and b.
QED
Here we use the theorem to compute a gcd.
By our theorem, all of the things in the first column are equal.
gcd(528, 341) 528%341 = 187 528 = 341(1) + 187 gcd(187, 341) 341%187 = 154 341 = 187(1) + 154 gcd(187, 154) 187%154 = 33 187 = 154(1) + 33 gcd(154,33) 154%33 = 22 154 = 33(4) + 22 gcd(22,33) 33%22 = 11 33 = 22(1) + 11 gcd(22,11) 22%11 = 0 22 = 11(2) + 0 gcd(11, 0) = 11
Turtle Problem Can you think of a case where this is slow as possible?? Bounty: 10 point bonus for first correct written answer.
Bezout's Theorem If a and b are integers not both zero, then there are integers x and y so that
ax + by = gcd(a,b).
There is a proof in numbers.pdf
that uses the
well-ordering principle on the positive integers.
To actually compute these coefficients, you must back-substitute
in the chain shown above. You are going to write a program
bezout.py
that does this. It's a royal pain in the
keister. Quoth my old friend Judith Anne Raphael, "It's big and it's
yours."
The Division Algorithm
Primality