I'm trying to create a program utilizing the Bisection Method (there are quite a lot of unused variables and confusing comments, so just ignore those). The value being outputted is fine, except it's getting stuck in an infinite loop and printing an infinite number of floating point digits. Isn't the epsilon supposed to stop this from happening? Here's my code:
total_cost = 1000000
downpayment = 0.25
amount_needed = total_cost * downpayment
annual_salary = int(input("Enter the starting salary: "))
monthly_salary = annual_salary / 12
num_of_months = 36
#needs changing
epsilon = .01
num_of_guesses = 0
low = 0
high = 100
ans = (high + low) / 2.0
ans = round(ans, 2)
#might need changing
while (num_of_months * (monthly_salary * (ans / 100)))**2 - amount_needed >= epsilon:
print("Low:", low, "High:", high, "Answer:", ans)
num_of_guesses = num_of_guesses + 1
if num_of_months * (monthly_salary * (ans / 100)) < amount_needed:
low = ans
elif num_of_months * (monthly_salary * (ans / 100)) > amount_needed:
high = ans
ans = (high + low) / 2.0
ans = round(ans, 2)
print("Number Of Guesses: ", num_of_guesses)
It's probably something really stupid but I honestly don't know what's going on XD
x = -37
epsilon = 0.01
num_guess = 0
low = 0.0
high = abs(x)
ans = ((low + high)/2.0)
while abs(ans**3-abs(x)) >= epsilon:
#print("low = " + str(low) + " high " + str(high) + " ans = " + str(ans))
if ans**3 < abs(x):
low = ans
else :
high = ans
ans = ((low + high)/2.0)
num_guess += 1
if x < 0:
ans = -ans
print("Steps taken during bisecction search: ",num_guess)
print("The cube root of " + str(x) + " is " + str(ans))
this is the code sample. I couldn't find a way to find the cube root of floats. Dont know where to insert the command and somehow the site needs more details , so this is why I am writing so much
You could simply write the root as a power.
For instance, x ** (1/3) gives you the cubic root of x.
So I'm entirely new to coding and I'm taking the MIT Openwarecourse to get started (and I'm using the book Introducing to Computation and Programming using Python)
Also since I'm new here I'm a bit afraid that my question is low quality so please point out if you think I should improve the manner on how I asks questions.
At 3.4 I'm given the code:
x = int(input("Please enter an integer: "))
epsilon = 0.01
numGuesses = 0
low = -100
high = max(1.0, x)
ans = (high + low)/2.0
while abs(ans**2 -x) >= epsilon:
print ("low = ", low, "High=", high, "ans=", ans)
numGuesses += 1
if ans**2 < x:
low = ans
else:
high = ans
ans = (high + low)/2.0
print ("numGuesses =", numGuesses)
print (ans, "Is close to square root of", x)
So what I tried to do first is understand each line of the code and what it exactly does. I've been given the hint: "Think about changing low to ensure that the answer lies within the region being searched.)
I've tried to change low to a negative number and I tried to add if low is less than 0, then low = -low like this:
x = int(input("Please enter an integer: "))
epsilon = 0.01
numGuesses = 0
low = 0.0
if low < 0:
low = -low
high = max(1.0, x)
ans = (high + low)/2.0
while abs(ans**2 -x) >= epsilon:
print ("low = ", low, "High=", high, "ans=", ans)
numGuesses += 1
if ans**2 < x:
low = ans
else:
high = ans
ans = (high + low)/2.0
print ("numGuesses =", numGuesses)
print (ans, "Is close to square root of", x)
However I'm probably taking a wrong approach...
You were very close, to convert the program to find an approximation to the cube root of both negative and positive numbers you have to only change the range in which your algorithm is searching.
To find cube root of positive numbers:
x = 8
epsilon = 0.01
numGuesses = 0
high = max(1.0, x)
low = 0.0
ans = (high + low) / 2.0
while abs((pow(ans,3)- x)) >= epsilon:
print("low ",low," ,high ",high," ans ",ans)
numGuesses += 1
if pow(ans,3) < x:
low = ans
else:
high = ans
ans = (high + low) /2.0
print("numguesses , = "+str(numGuesses))
print(str(ans)+"is close to square root of x "+ str(x))
The algorithm searches between low and high.
Suppose a user enters a number say 8 implies high = 8 and low = 0.0 and then it performs the search and will output 2.0, if user enters a negative number say -8 then high = 1.0 and low = 0.0 which don't appear to be right,the correct limit should be i.e [-8,0) (cube root of a negative number is negative) "ignoring complex roots", in this case high = 0 and low = -8.
You can do it by a simple if else statement.
x = 8
epsilon = 0.01
numGuesses = 0
high = max(1.0, x)
low = 0.0
if x < 0:
low = x
else:
None
ans = (high + low) / 2.0
while abs((pow(ans,3)- x)) >= epsilon:
print("low ",low," ,high ",high," ans ",ans)
numGuesses += 1
if pow(ans,3) < x:
low = ans
else:
high = ans
ans = (high + low) /2.0
print("numguesses , = "+str(numGuesses))
print(str(ans)+"is close to square root of x "+ str(x))
I hope this is a beginner friendly answer.
To solve the problem I used the min function and compared x to 1.0, then extracted the lowest value. I did this because it is the direct inverse of extracting the initial high value.
x = -25
epsilon = 0.01
num_guesses = 0
low = min(x, 1.0)
high = max(1.0, x)
ans = (high + low) / 2.0
while abs(ans**3 - x) >= epsilon:
print('low =', low, 'high =', high, 'ans =', ans)
num_guesses += 1
if ans**3 < x:
low = ans
else:
high = ans
ans = (high + low) / 2.0
print('num guesses =', num_guesses)
print(ans, 'is close to cube root of', x)
I wrote an alternative code that allows negatives of square, cube, etc roots while keeping the core of OP's code unchanged:
number = int(input('Number? '))
x = abs(number)
root = int(input('Root? '))
epsilon = 0.01
numGuesses = 0
low = 0.0
high = max(1.0, x)
ans = (high + low)/2.0
while abs(ans**root - x) >= epsilon:
print('low =', low, 'high =', high, 'ans =', ans)
numGuesses += 1
if ans**root < x:
low = ans
else:
high = ans
ans = (high + low)/2.0
print('numGuesses =', numGuesses)
if number < 0:
if root%2 == 1:
ans = -ans
else:
ans = str(ans)+'i'
print(ans, 'is close to square root of', number)
It takes the input number as absolute and checks its signal after the calculation is performed. It also adds 'i' in case of even roots of negative numbers.
x = int(input("Please enter an integer: "))
epsilon = 0.01
numGuesses = 0
low = -abs(x)
high = max(1.0, x)
ans = (high + low)/2.0
while abs(ans**2 -x) >= epsilon:
print ("low = ", low, "High=", high, "ans=", ans)
numGuesses += 1
if ans**2 < x:
low = ans
else:
high = ans
ans = (high + low)/2.0
print ("numGuesses =", numGuesses)
print (ans, "Is close to square root of", x)
x = int(input('Enter the number you want to find the root of: '))
root = int(input('Enter the power number: '))
epsilon = 0.01
numGuesses = 0
low = 0.0
high = x #note that u removed max()
guess = (high + low)/2.0 #note u changed ans to guess
while abs(abs(guess**root) - abs(x)) >= epsilon:
print('low =', low, 'high =', high, 'ans =', guess)
numGuesses += 1
if abs(guess**root) < abs(x):
low = guess
else:
high = guess
guess = (high + low)/2.0
print('numGuesses =', numGuesses)
print(guess, 'is close to root of', x)
This works well and there are not a lot of changes from the OG code
Your algorithm is a numerical search through dichotomy method applied to X^2-x=0, it converges (quite fast actually) towards the solution X=sqrt(x) as long as low is lower than the solution, and high is higher than the solution.
In your case x is always higher than sqrt(x) and 0 is always lower than sqrt(x).
The answer will always be in the region being searched,you can lower epsilon as much as you want. There is no point in changing the initialisation of low. If you lower it to negative values, it will only require a few more step, roughly log2(abs(low))
change
ans**2
to
ans**3
and your algorithm converges to the cubic root of x.
The cubic root of negative numbers is not well defined, I guess what they mean is the cubic root of the absolute value, multiplied by -1. So (-3)^3 =-9
If x<0, replace x by abs(x), run the algorithm and return the solution multiplied by -1.
This:
low = 0.0
if low < 0:
low = -low
literally does nothing. You set low = 0 and then check if it's less than 0 (which it isn't). Also, 0 is both positive and negative, so changing its sign does nothing.
I'm afraid I don't understand the problem entirely, but it looks like high and low are bounds within which you expect the square/cubed root to be?
If x is negative then you want to make sure your lower bound can encompass it. Maybe setting low = x would help?
I really am not sure how to explain my question in a title; a graphic will be best.
I've been given this problem as something to play around with in class, so far only one person has managed to achieve a solution, and it's a very complex one.
While I've spoken to him (The best we can manage, his english isn't great), I'd like to come up with my own solution, but I need some pointers, or at least new ideas..
The problem is this:
n=5
0 3 5 5 3 0
3 5 5 3
5 5
5 5
3 5 5 3
0 3 5 5 3 0
With 'n' being an input value.
So far I've got this;
#!/usr/bin/env python3
while True:
n = int(input("Enter a size : "))
z = "+"
for i in range(n*2): # ROWS
for j in range(n*2): # COLUMNS
if i == 0 or j == 0 or i == n*2 - 1 or j == n*2 - 1: # OUTLINE
print(z, end=" ")
elif j < n-i: # TOP LEFT
print(z, end=" ")
elif j >= n+i or i >= n+j: # TOP RIGHT + BOTTOM LEFT
print(z, end=" ")
elif j >= n*2-i+n-1 and i >= n*2-j+n-1: # BOTTOM RIGHT
print(z, end=" ")
else:
print(" ", end=" ")
print()
Whitch outputs this;
Enter a size : 5
+ + + + + + + + + +
+ + + + + + + +
+ + + + + +
+ + + +
+ +
+ +
+ + + +
+ + + + + +
+ + + + + + + +
+ + + + + + + + + +
The next step is to replace "z" with an equation for the places in the box I guess. But I've no idea where to start (And my math is a little rusty)
Taking a guess, I suppose this is what you mean:
def square(n):
def row(i, n):
l = [str(x) if x <= n else ' ' for x in range(i, i+n)]
return l + l[::-1]
top = [row(i, n) for i in range(1, n+1)]
return '\n'.join(' '.join(r) for r in (top + top[::-1]))
while True:
n = int(input("> "))
print(square(n))
I solved it, and not in a way I was expecting, tbh. I'd call it a dirty hack.
#!/usr/bin/env python
__author__ = "Luke Jones"
__copyright__ = "Copyleft, do what you want with it"
__license__ = "GPL"
__version__ = "0.0.1"
while True:
startV = int(input("Enter a size : "))
array1=[]
array2=[]
for i in range(1,startV+1,2):
array1.append(i)
array2 = list(array1)
array2.reverse()
n = len(array1)
for i in range(n*2): # ROWS
for j in range(n*2): # COLUMNS
if j < n-i: # TOP LEFT
print(array1[j+i], end=" ")
elif j >= n+i: # TOP RIGHT
print(array2[j-n-i], end=" ")
elif i >= n+j: # BOTTOM LEFT
print(array2[i-n-j], end=" ")
elif i >= n*2-j+n-1 and not i >= n*2-j+n:
#print("X",end=" ")
for q in range(n*2-j):
print(array2[q], end=" ")
else:
print(" ", end=" ")
print()
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Using bisection search to determine
I have posted other thread but it did not receive answers thus i'm trying to provide some of my work to make more clear.
I need to use bisection method to determine monthly payment in order to pay off debt in one year exactly.
Here's some code:
originalBalance = 320000
annualInterestRate = 0.2
monthly_interest = annualInterestRate / 12
low = originalBalance/12
high = (originalBalance*(1 + monthly_interest)**12)/12
epsilon = 0.01
min_payment = (high + low)/2.0
while min_payment*12 - originalBalance >= epsilon:
for month in range(0, 12):
balance = (originalBalance - min_payment) * (1+monthly_interest)
if balance < 0:
low = min_payment
elif balance > 0:
high = min_payment
min_payment = (high + low)/2.0
print "lowest payment: " + str(balance)
However, I receive very way off answer: 298222.173851
My friend told me that correct answer is : 29157.09
Which is a lot lower than my...I guess the problem is in rounding(which I did not do yet) and preserving the balance after every looping and resetting it if balance is over 0. I cannot figure out how to attempt this problem and please, help someone :)
This is the correct one.
originalBalance = 320000
annualInterestRate = 0.2
monthly_interest = annualInterestRate / 12
low = originalBalance/12
high = (originalBalance*(1 + monthly_interest)**12)/12
epsilon = 0.01
min_payment = (high + low)/2.0
while min_payment*12 - originalBalance >= epsilon:
for month in range(0, 12):
balance = (originalBalance - min_payment)/10 * (1+monthly_interest)
if balance < 0:
low = min_payment
elif balance > 0:
high = min_payment
min_payment = (high + low)/2.0
print "lowest payment: " + str(balance)
This is what you need
while abs(x) > epsilon:
x = balance
for month in range(0, 12):
x = (x - ans) * (1+monthly_interest)