Approximating Sine recursively - python

So I am trying to write a file consisting of two recursive functions. One of which calculates the factorials required for approximating sine via taylor series. The second is another recursive function that will output the value of sine as a float value and will go as far as the amount of terms inputted. Here is a mathematical representation of what I am aiming to get
Here is my code so far (it is unfinished as I am having difficulties with the actual sine computation function):
def main():
ang = int(input("Enter the angle to approximate (in radians): "))
trms = int(input("Enter the amount of terms to compute: "))
sinApprox(ang,trms)
def calcFac(x):
if x <= 0:
return 1
else:
return x * calcFac(x-1)
def sinApprox(angle, terms):
if calcFac(terms) <= 0:
return (sinApprox(angle,terms)/calcFac(terms))
elif terms % 2 == 0:
return sinApprox(angle**)
Note that both functions must be pure and recursive as well.

Here is a way that this can be done.
def calcFac(x):
if x == 1 or x == 0: return 1
val = 1
for i in range(2, x+1):
val = val * i
return val
def sinApprox(angle, terms):
mult = 1
if terms % 2 == 0: mult = -1
power = 2*terms - 1
val = angle ** power
val = mult * val/calcFac(power)
if terms == 1: return val
else: return val + sinApprox(angle, terms - 1)
angle = int(input("Enter the angle to approximate (in radians): "))
terms = int(input("Enter the amount of terms to compute: "))
sinApprox(angle, terms)

Related

Is there a way to make approximation outputs in to a list?

I am trying to write a code (python) that uses the Babylonian square root equation by usimg a while loop to approximate square root until error is less than an epsilon value and I am trying to print the approximations in the form [x1,x2,x3...] but have only managed to get the approximations to be listed vertically downwards each on a separate line
e.g.
x1
x2
x3
This is my code so far. I am new to coding so any help and advice would be much appreciated :)
a= float(input('enter the positive value that you wish to find the babylonian square root of '))
e= float(input('enter a positive value for maxium error '))
x= float(input('enter an arbitrary starting value '))
if a<0 or a==0:
print(' a must be a positive number')
elif e<0 or e==0:
print('e must be a positive number')
elif x==0:
print('starting value cannot be 0 as cant divide by 0!')
else:
while abs(x**2-a)>e or abs(x**2-a)==e :
x=0.5*(x-(a/x))
xn=0.5*(x-(a/x))
x=xn
print(x)
Create a list and then output the list:
a = float(input('enter the positive value that you wish to find the babylonian square root of '))
e = float(input('enter a positive value for maxium error '))
x = float(input('enter an arbitrary starting value '))
if a < 0 or a == 0:
print(' a must be a positive number')
elif e < 0 or e == 0:
print('e must be a positive number')
elif x == 0:
print('starting value cannot be 0 as cant divide by 0!')
else:
result_list = []
while abs(x ** 2 - a) > e or abs(x ** 2 - a) == e:
x = 0.5 * (x - (a / x))
xn = 0.5 * (x - (a / x))
x = xn
result_list.append(x)
print(result_list)

Return statement not forcing to jump out of function

I am writting a recursive function to print number of square root of first occurring number between a given range of numbers.For example, between a range of 80 - 90, 81 is the first number which has a perfect square root which is 9. Also 9 has a perfect squreroot which is 3. but 3 does not have a perfect equre root. So the count should be 2: 81 : 9 -> 3. count = 2
import math
def sqrtCount(num, countVal):
count = countVal
root = math.sqrt(num)
if int(root + 0.5) ** 2 != num:
return count
else:
count += 1
sqrtCount(root, count)
return count
min = int(input("Enter Minimum number: "))
max = int(input("Enter Maximum number: "))
for i in range(min, max + 1):
val = sqrtCount
if val(i, 0) > 0:
print(val(i, 0))
break
First of all, your code is quite hard to read.
val = sqrtCount
does not serve a good purpose here. It looks to me that you wanted
for i in range(min, max + 1):
val = sqrtCount(i, 0)
if val > 0:
print(val)
break
Also,
count = countVal
seems not helpful. Removing it will simplify the method and help yourself understanding it. Finally it will be as simple as
def sqrtCount(num, countVal):
root = math.sqrt(num)
if int(root + 0.5) ** 2 != num:
return countVal
else:
return sqrtCount(root, countVal +1)

Loop Function to find a Square root of a number

The question is
To find the square root of number ā€˜Nā€™.using this procedure, we must implement the
following process:
Guess a value for the square root of N
Divide N by that guess
Average the result with your original guess to get your new guess
Go to step 2 and repeat
I have set the code to return the Guess once it is within 0.5 of the previous Guess, and if its not to repeat the function. I'm not sure how to make it repeat or how to close the loop.
def SqrRt(Number,Guess):
while Guess2 == ((Estimate+Guess)/2):
if (Estimate - Guess2) <= 0.5:
return Guess2
elif (Estimate - Guess2) >= -0.5:
return Guess2
else:
Estimate = (Number/Guess)
Guess2 = Estimate + 1
answer = SqrRt(34567823321421,500000)
print(answer)
Using the Babylonian Method means solving (S^2 - V) = 0. Here, S is the square root of V, which is to be found. Applying Newtons Approximation leads to an iterative method where 'x_new = (x_prev + V / x_prev) / 2'. The first 'x_prev' needs to be estimated.
The iteration converges monotonously. Thus a check against a delta in development is sufficient.
x = V / 2.0 # First estimate
prev_x = x + 2 * Delta # Some value for that 'while' holds
while abs(prev_x - x) > Delta:
prev_x = x
x = (x + V/x) / 2.0
square_root = x
Choose Delta to be arbitrarily small (e.g. 0.0001).
First off
You need code that will actually run at all for a question like this. I suggest that your code should look more like this:
def SqrRt(Number,Guess):
while Guess2 == ((Estimate+Guess)/2):
if (Estimate - Guess2) <= 0.5:
return Guess2
elif (Estimate - Guess2) >= -0.5:
return Guess2
else:
Estimate = (Number/Guess)
Guess2 = Estimate + 1
answer = SqrRt(34567823321421,500000)
print(answer)
#Number to Use - 34567823321421
#Answer - 5879440.732

Calculating when the amount will be doubled using while loop

This is a simple exercise found in a book, which asks us to determine how long it takes for an amount to double at a given interest rate. My code is like this:
def main():
x = eval(raw_input("Initial Principal: "))
y = eval(raw_input("Interest rate: "))
count = 0
while x < 2*x:
x = x * (1 + y)
count = count + 1
print (x)
print (count)
main()
What it returns is:
Initial Principal: 1000
Interest rate: 0.5
inf
1734
What's wrong with my code?
Also I wonder if the above code would work if my amount and interest is small, e.g. amount = 1 and interest rate = 0.05, since there would include some floating point arithmetic I guess.
Thank you!
The culprit is the fact that you write:
while x < 2*x:
Since x > 0, that relation will always be False, you do not compare the new x with the old x, you compare the new x with twice the new x.
We can solve this effectively by using a variable x0 that store the initial amount:
def main():
x = x0 = eval(raw_input("Initial Principal: "))
y = eval(raw_input("Interest rate: "))
count = 0
while x < 2*x0:
x = x * (1 + y)
count = count + 1
print (x)
print (count)
main()
But there are still some problems with the code. For example you use eval. Do not use eval unless you absolutely have to: now a person can enter any type of Python code, also code that will break the system. Use float(..) instead to convert a string to an int:
def main():
x = x0 = float(raw_input("Initial Principal: "))
y = float(raw_input("Interest rate: "))
count = 0
while x < 2*x0:
x = x * (1 + y)
count = count + 1
print (x)
print (count)
main()
But now the code is still inefficient. There exists a fast way to calcuate the number of years using logarithms:
from math import log, ceil, pow
def main():
x = x0 = float(raw_input("Initial Principal: "))
y = float(raw_input("Interest rate: "))
count = ceil(log(2.0, y+1.0))
newx = x * pow(1.0+y, count)
print (newx)
print (count)
The problem is your while guard, which checks if the number is less than two times itself. To solve this, save the threshold you want to reach in a variable before the loop, and you have done:
threshold = 2 * x
count = 0
while x < threshold:
x = x * (1 + y)
count = count + 1

Program to find cuberoot of a number [duplicate]

This question already has answers here:
How to find cube root using Python? [duplicate]
(3 answers)
Closed 5 years ago.
So I'm a complete beginner (like less than a week) and wrote this code in python. It's supposed to find the cuberoot of a number if the solution is an integer, and approximate it otherwise. It does both instead of just one or the other. I've tried it multiple ways for hours now but it doesn't work. Any suggestions?
cube=int(input("what number's cube root do you want to find"))
epsilon = 0.01
increment = 0.0001
num_guesses = 0
for guess in range(cube+1):
if guess**3 == cube:
guess += 1
print (guess)
else:
guess1 = 0.0
while abs(guess1**3 - cube) >= epsilon:
guess1 += increment
num_guesses += 1
print('num_guesses =', num_guesses)
else:
print(guess1)
The problem is your indentation. Everything in your "else" statement needs to be indented to show that it is inside the "else" statement. You also have a few logical errors in your code. If you have found a number that, when cubed, is the desired number, you should print that number, not that number plus 1. And if you've found the solution, your program should stop there.
for guess in range(cube+1):
if guess**3 == cube:
print (guess)
return
guess1 = 0.0
Here is the working solution:
cube=int(input("what number's cube root do you want to find: "))
epsilon = 0.01
increment = 0.0001
num_guesses = 0
int_result_found = False
for guess in range(cube+1):
if guess**3 == cube:
print guess
int_result_found = True
break
if not int_result_found:
guess1 = 0.0
while abs(guess1**3 - cube) >= epsilon:
guess1 += increment
num_guesses += 1
#print 'num_guesses =', num_guesses
print(guess1)
As Erik said, there were some errors in your code. Key point is to stop after you've found integer solution, I've used boolean flag int_result_found for that.
One of the problems with you code is indenting. Python requires specific spacing in order to work properly.
The easiest way to avoid getting both answers is to create a boolean variable (I used "found_answer") to check if it is necessary to run the second code.
I've fixed you code, modifying it as little as possible:
cube=int(input("what number's cube root do you want to find"))
found_answer = False
for guess in range(cube+1):
if guess**3 == cube:
print ("integer answer:", guess)
found_answer = True
if found_answer == False:
epsilon = 0.01
increment = 0.0001
num_guesses = 0
guess1 = 0.0
while abs(guess1**3 - cube) >= epsilon:
guess1 += increment
num_guesses += 1
print('num_guesses =', num_guesses)
print("approximate answer:", guess1)
For your interest, here is a much more efficient solver:
# target function: y = x**3
def cube(x):
return x * x * x
def diff(f, epsilon = 0.001):
"""
Given function f, return a numeric approximation function for f'(x)
"""
def df(x):
return (f(x + epsilon) - f(x)) / epsilon
return df
def newton_solver(target_y, f, df = None, start_x = None, epsilon = 0.001, max_reps = 40):
"""
Newton Raphson approximation
Given real target_y and function f,
return real x such that f(x) = target_y +/- epsilon
"""
# if no differential function is provided, use a numeric approximation
if df is None:
df = diff(f)
# if no starting point is given, guess f(x) ='= x
if start_x is None:
x = target_y
else:
x = start_x
for _ in range(max_reps):
y = f(x)
err = y - target_y
if abs(err) < epsilon:
# close enough
return x
else:
# project the tangent to find a closer approximation
x -= err / (df(x) or epsilon)
# no answer found, bail out
raise ValueError("max_reps exceeded, no solution found")
def main():
y = int(input("What integer do you want to find the cube root of? "))
# find x such that y == x**3
approx_x = newton_solver(y, cube)
# round to the nearest integer
int_x = round(approx_x)
if cube(int_x) == y:
print("The exact cube root of {} is {}.".format(y, int_x))
else:
print("The cube root of {} is approximately {}.".format(y, approx_x))
if __name__ == "__main__":
main()
when it comes to "guess**3 == cube", I think you need to "break"
try this:
cube=int(input("what number's cube root do you want to find"))
epsilon = 0.01
increment = 0.0001
for i in range(cube + 1):
if i**3 == cube:
# break the loop
break
elif (i+1)**3 > cube > i**3: # this is to reduce unnecessary calculations
while (abs(i**3 - cube) >= epsilon):
i += increment
break
print(i)
and I'd like to make it a func:
cube=int(input("what number's cube root do you want to find"))
epsilon = 0.01
increment = 0.0001
def cuberoot(cube):
for i in range(cube + 1):
if i**3 == cube:
break
elif (i+1)**3 > cube > i**3:
while (abs(i**3 - cube) >= epsilon):
i += increment
break
return i
print(cuberoot(cube))
and what is more easy:
def cuberoot(cube):
return cube**(1/3)

Categories