Loops and Strings, GUESS-and-CHECK, Approximation, Bisection
Loops and Strings, GUESS-and-CHECK, Approximation, Bisection
GUESS-and-CHECK,
APPROXIMATION,
BISECTION
6.00.1X LECTURE 1
- Example of guess and check for the code where you are setting up a variable outside and changing the variable inside
REVIEWING LOOPS
ans = 0
neg_flag = False
x = int(input("Enter an integer: "))
if x < 0:
neg_flag = True
while ans**2 < x:
ans = ans + 1
if ans**2 == x:
print("Square root of", x, "is", ans)
else:
print(x, "is not a perfect square”)
if neg_flag:
print("Just checking... did you mean", -x, "?”)
6.00.1X LECTURE 2
- Strings are a sequence of case sensitive letters (upper or lower case)
- You can also compare strings like you do with numbers.
- ex. you can test if two strings are equal while using the double equal sign, or can use greater than or less than using
lexicographic order to decide if two strings are greater than or less than each other
REVIEWING STRINGS
think of as a sequence of case sensitive characters
can compare strings with ==, >, < etc.
len() is a function used to retrieve the length of the
string in the parentheses
square brackets used to perform indexing into a string
to get the value at a certain index/position
s = "abc"
index: 0 1 2 indexing always starts at 0
len(s) evaluates to 3
s[0] evaluates to "a"
s[1] evaluates to "b"
s[3] trying to index out of bounds, error
6.00.1X LECTURE 3
- Slicing lets you go into string and pull out pieces of the string.
STRINGS
can slice strings using [start:stop:step]
s = "abcdefgh"
- if -1, access
string in s[::-1] evaluates to "hgfedbca"
reverse order
s[3:6] evaluates to "def"
s[-1] evaluates to "h"
strings are “immutable” – cannot be modified
"Immutable" - i.e. it cannot be changed
s = "hello"
s[0] = 'y' gives an error
s = 'y'+s[1:len(s)] is allowed "hello"
Since s[0] is 'h', you cannot use s[0] = 'y' unless you change
the definition of s.
s is a new object
"yello"
You will have to redefine s.
s
6.00.1X LECTURE 4
FOR LOOPS RECAP
for loops have a loop variable that iterates over a set of
values
for var in range(4):
<expressions>
◦ var iterates over values 0,1,2,3
◦ expressions inside loop executed with each value for var
for var in range(4,8): expressions inside the loop are going to be executed for
each value of the variable that you use
<expressions> range is a good way to iterate over numbers.
for char in s: - you can write the loop in this way as well because 's' is a 'iterable'
6.00.1X LECTURE 6
CODE EXAMPLE
an_letters = "aefhilmnorsxAEFHILMNORSX”
6.00.1X LECTURE 7
6.00.1X LECTURE 8
So far, we have been doing everything with integers where there is a finite numbers to check.
APPROXIMATE SOLUTIONS
suppose we now want to find the root of any non-
negative number?
can’t guarantee exact answer, but just look for
something close enough
start with exhaustive enumeration
◦ take small steps to generate guesses in order
◦ check to see if close enough
6.00.1X LECTURE 9
APPROXIMATE SOLUTIONS
good enough solution First, need to define what is a "good enough" solution?
start with a guess and increment by some small value
ex. Start with 1
|guess3|- cube <= epsilon and see if it's
close.
for some small epsilon Then use 1.002,
and check that.
6.00.1X LECTURE 10
APPROXIMATE SOLUTION
– cube root
cube = 27
epsilon = 0.01 how close do we want to be to the actual answer
guess = 0.0 the number what you are going to start with
increment = 0.0001 size which you will increase your guess as you move along
num_guesses = 0
while abs(guess**3 - cube) >= epsilon: and guess <= cube :
guess += increment
num_guesses += 1
print('num_guesses =', num_guesses)
if abs(guess**3 - cube) >= epsilon:
print('Failed on cube root of', cube)
else:
print(guess, 'is close to the cube root of', cube)
6.00.1X LECTURE 11
Some observations
Step could be any small number
◦ If too small, takes a long time to find square root
◦ If too large, might skip over answer without getting close
enough
In general, will take x/step times through code to find
solution
Need a more efficient way to do this
6.00.1X LECTURE 12
6.00.1X LECTURE 13
So far, we have been using epislon to guess and check
- The issue is that with this method, it means we either have to take very small steps and take a
long time, or take larger steps, and possibly miss the solutions.
- Bisection search is a more effective way of doing this.
BISECTION SEARCH
We know that the square root of x lies between 1 and
x, from mathematics
Rather than exhaustively trying things starting at 1,
suppose instead we pick a number in the middle of this
range Ex. we know square root of 25 is somewhere between 1 and x. So rather than starting everything at 1 and taking
small steps, we can pick a number in between 1 and 25. Say, 12.5.
1 x
g
6.00.1X LECTURE 14
BISECTION SEARCH
If not close enough, is guess too big or too small?
If g**2 > x, then know g is too big; but now search
1 throw away x
this section
new g next g g
At each stage, reduce range of values to search by half
6.00.1X LECTURE 15
EXAMPLE OF SQUARE ROOT
x = 25
epsilon = 0.01
numGuesses = 0
low = 1.0
high = x
ans = (high + low)/2.0
BISECTION SEARCH difference is that the root doesn't lie between the
number and x itself.
search space
log2N = that means this doesn't linear time, but
◦ first guess: N/2 logarithmic time (it takes less than linear time to get
there)
◦ second guess: N/4
It is a lot quicker.
◦ gth guess: N/2g
guess converges on the order of log2N steps
bisection search works when value of function varies
monotonically with input
code as shown only works for positive cubes > 1 – why?
challenges modify to work with negative cubes!
modify to work with x < 1!
6.00.1X LECTURE 18
x<1
if x < 1, search space is 0 to x but cube root is greater
than x and less than 1
modify the code to choose the search space
depending on value of x
6.00.1X LECTURE 19
SOME OBSERVATIONS
Bisection search radically reduces computation time –
being smart about generating guesses is important
Should work well on problems with “ordering”
property – value of function being solved varies
monotonically with input value
◦ Here function is g**2; which grows as g grows
Monotonically - i.e. it increases as the input value increases.
For ex. g**2 will grow as g grows. g**3 will grow as g grows.
6.00.1X LECTURE 20
6.00.1X LECTURE 21
Sometimes you may get answers where you're expecting a 3.0, but the actual answer gives you 3.0000000
- To fix this, need to understand how machine actually stores the number
6.00.1X LECTURE 22
CONVERTING DECIMAL
INTEGER TO BINARY
Consider example of Given a decimal integer, how do we convert to Binary?
6.00.1X LECTURE 23
DOING THIS IN PYTHON
if num < 0:
isNeg = True
num = abs(num)
else:
isNeg = False
result = ‘‘
if num == 0:
result = ‘0’
while num > 0:
result = str(num%2) + result
num = num//2
if isNeg:
result = ‘-’ + result
6.00.1X LECTURE 24
WHAT ABOUT FRACTIONS?
3/8 = 0.375 = 3*10-1 + 7*10-2 + 5*10-3 <-- This gives you the digits associated with each
of the placeholders
6.00.1X LECTURE 25
x = float(input('Enter a decimal number between 0 and 1: '))
p = 0
while ((2**p)*x)%1 != 0:
print('Remainder = ' + str((2**p)*x - int((2**p)*x)))
p += 1
num = int(x*(2**p))
result = '' With this code, you can now take any floating point number,
convert into something that can be represented inside of the
if num == 0: machine in binary form, and use it.
result = '0'
while num > 0:
result = str(num%2) + result
num = num//2
6.00.1X LECTURE 27
6.00.1X LECTURE 28
Newton-Raphson - a general approximation algorithm to find roots of a polynomial in one variable
NEWTON-RAPHSON
General approximation algorithm to find roots of a
polynomial in one variable
p(x) = anxn + an-1xn-1 + … + a1x + a0
Want to find r such that p(r) = 0
For example, to find the square root of 24, find the root of
p(x) = x2 – 24
Newton showed that if g is an approximation to the root,
then
g – p(g)/p’(g)
is a better approximation; where p’ is derivative of p
6.00.1X LECTURE 29
NEWTON-RAPHSON
Simple case: cx2 + k
First derivative: 2cx
So if polynomial is x2 + k, then derivative is 2x
Newton-Raphson says given a guess g for root, a better
guess is
g – (g2 –k)/2g
6.00.1X LECTURE 30
NEWTON-RAPHSON
This gives us another way of generating guesses, which we can check; very efficient
This lets you find cube and square root solutions very quickly
epsilon = 0.01
y = 24.0
guess = y/2.0
numGuesses = 0
6.00.1X LECTURE 31
Iterative algorithms
Guess and check methods build on reusing same code
◦ Use a looping construct to generate guesses, then check
and continue
Generating guesses
◦ Exhaustive enumeration
◦ Bisection search
◦ Newton-Raphson (for root finding)
6.00.1X LECTURE 32