Assignment 4 - livetoad.org

advertisement
Assignment 4: due 24 September
Problem 1:
Here is Euclid’s algorithm in python:
def gcd(m,n):
"Euclid’s algorithm for computing gcd(m,n)"
# There is no gcd of 0 and 0: since everything divides 0.
if m == n == 0:
raise Exception(’At least one argument must be nonzero’)
# gcd is well-defined for positive and negative arguments,
# because a divides b iff a divides -b iff -a divides b.
# So we may assume that n > 0, and it is convenient to do so.
if n < 0:
n = -n
# The principal idea is that if r = m%n (the remainder
# of m modulo n) then gcd(m,n) = gcd(r,n) = gcd(n,r).
# By definition of remainder, 0 <= r < n, and so
# we proceed recursively, making n smaller at each step
# until it reaches 0, at which point gcd(m,0) = m.
while n > 0:
m, n = n, m%n
return m
In this problem you will investigate the efficiency of Euclid’s algorithm. To do this you will generate random
numbers m and n then compute their gcd, keeping track of how many steps it takes. Compile your data so
that you can determine, on average, how many steps Euclid’s method require for randomly-chosen N -digit
numbers. You will have to generate thousands of numbers for each N in the range up to several hundred.
Plot your data and study the graph. What kind of function best models this data? How precisely can you
model it?
You will need a function to generate random numbers of a specified number of digits. Fortunately python
has a module called random which provides most of what we need. Here is a simple python function that
should work for our purposes:
import random
digits = range(10)
def random_integer(N):
r = random.choice(digits[1:])
i = 1
while i < N:
r = 10*r + random.choice(digits)
i = i + 1
return r
Experiment with this function, then supply a doc string and comments.
Next you will need to modify the gcd code to be able to count the number of steps required for each
computation. The crucial step is the one inside the while loop. Add a line that keeps a running count of
the number of times that step is executed. Since you will not need the gcd itself in this exercise, you could
simply return the count, and rename the function (say) gcd count.
1
Problem 2:
In this problem we will finish the vector algebra module. Here is the code from class:
from math import *
# In the math module there are lots of useful functions,
# including exp (exponential), sqrt (square root),
# cos, sin, and atan (arctangent), and so forth; as well as
# the constants pi and e.
def make_vector(*v):
"Returns a vector (tuple) of the given arguments."
# This deceptively simple function relies on a useful
# convention in python function definition: if you want
# to supply a variable number of arguments to a function
# then you can bundle them together into a tuple with
# the * syntax above. So, the *v in the definition
# simply tells python to gather all arguments into
# a tuple and call the result v. Since that is all we
# want to do to make a vector we simply return this
# value!
return v
def vector_add(v,w):
"Adds vectors v and w (if they are the same size)"
if len(v) <> len(w):
raise Exception(’Cannot add vectors of different sizes’,
v, w)
U = []
i = 0
while i < len(v):
U.append(v[i]+w[i])
i = i + 1
return apply(make_vector,U)
First of all, experiment with this function, to see how it works. When you understand how it works, add
comments to explain it in detail. Finish the vector algebra module by writing the following functions:
• vector sub (to subtract)
• vector neg (to negate a vector)
• vector nonzero (to test whether a vector is nonzero)
• scalar mul (multiplication by a scalar)
• dot prod (dot product)
• cross prod (allow vectors of size 2 or 3)
• length (euclidean norm)
• angle (in radians)
Test these extensively to make sure they all work as expected. (Be careful on the last function.)
2
Download