How to calculate sine and cosine without importing math? [closed] - python

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I started programming in python not too long ago and I am having trouble with a part of a program. The program will ask for input from the user and he can input: A, B, C, M, or Q. I have completed the A, M, and Q part but I can't figure out how to do the parts for B (calculate the sine of the number you want) and C (calculate the sine).
All the information I was given was:
The power series approximation for the sine of X can be expressed as:
sine(X) = X – (X3/3!) + (X5/5!) – (X7/7!) + (X9/9!) .... Note that an
individual term in that power series can be expressed as: (-1)k *
X2k+1 / (2k+1)! where k = 0, 1, 2, 3, ….
Oooh, and (but for this a while loop should do right?):
When computing the sine of X or the cosine of X, the program will expand the power series
until the absolute value of the next term in the series is less than 1.0e-8 (the specified epsilon).
That term will not be included in the approximation.
And I can't use import math.
Can anyone give me an idea of how I can do this? I sincerely have no idea of where to even start hahaha.
Thanks in advance!
***Hey guys, I've been trying to do this for the last 3 hours. I'm really new to programming and some of yours answers made it a bit more understandable for me but my program is not working, I really don't know how to do this. And yes, I went to speak with a tutor today but he didn't know either. So yeah, I guess I'll just wait until I get the program graded by my teacher and then I can ask him how it was supposed to be done. Thank you for all the answers though, I appreciate them! :)

>>> e = 2.718281828459045
>>> X = 0.1
>>> (e**(X*1j)).imag # sin(X)
0.09983341664682815
>>> (e**(X*1j)).real # cos(X)
0.9950041652780258
Verify
>>> from math import sin, cos
>>> sin(X)
0.09983341664682815
>>> cos(X)
0.9950041652780258
You'll probably get better marks if you sum up the series explicitly though
result = 0
n = 1
while True:
term = ...
result += term
if term <= epsilon:
break
n += 2

It seems that you aren't supposed to import math because you are supposed to write your own function to compute sine. You are supposed to use the power series approximation.
I suggest you start by writing a factorial function, then write a loop that uses this factorial function to compute the power series.
If you still can't figure it out, I suggest you talk to your teacher or a teacher's assistant.

Since you have a condition to finish the loop last_term < 1.0e-8, you should use a while:
while last_term > 1.0e-8:
You will need a counter to keep the count of k (starting from 0) and a variable to keep the last term:
k = 10 # some initial value
last_term = 0
while ...:
last_term = ... # formula here
and also a result variable, let' say sin_x:
while ...:
...
sin_x += last_term
Note: In the formula you are using factorial, so will need to define a function that computes the factorial of a number, and use it properly.

Related

i need more decimal places for pi calculation [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I'm trying to make a Pi calculator in python but I need more decimal places.
it would help a lot if someone edited my code and carefully explained what they did.
this is the code I'm using.
import math
d = 0
ans = 0
display = 0
while True:
display += 1
d += 1
ans += 1/d**2
if display == 1000000:
print(math.sqrt(ans*6))
display = 0
# displays value calculated every 1m iterations
output after ~85m iterations: (3.14159264498239)
I need more than 15 decimal places (3.14159264498239........)
You’re using a very slowly converging series for π²∕6, so you are not going to get a very precise value this way. Floating point limitations prevent further progress after 3.14159264498239, but you’re not going to get much further in any reasonable amount of time, anyway. You can get around these issues by some combination of
micro-optimising your code,
storing a list of values, reversing it and using math.fsum,
using decimal.Decimal,
using a better series (like this one),
using a method that converges to the value of π quickly, instead of a series (like this one),
using PyPy, or a faster language than Python,
from math import pi.
you could try with a generator:
def oddnumbers():
n = 1
while True:
yield n
n += 2
def pi_series():
odds = oddnumbers()
approximation = 0
while True:
approximation += (4 / next(odds))
yield approximation
approximation -= (4 / next(odds))
yield approximation
approx_pi = pi_series()
for x in range(10000000):
print(next(approx_pi))

Strategies to avoid division by zero error [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
Is there a best practice to avoid ZeroDivisionErrorin python? For instance, consider the following function:
def division (x,y):
return x / y
In this function if y is set to zero, the ZeroDivisionError is raised. One strategy would be to replace the denominator of the division by y+1, so the function would be:
def division (x,y):
return x / (y+1)
or the other strategy can be returning nan value if denominator is zero:
def division (x,y):
if y == 0:
return np.nan
else:
return x / y
What are the cons of the above strategies? Is there any other approach to avoid ZeroDivisionError? Exception handling is also a popular solution for this problem, but I'm more looking for prevention strategy not intervention.
This follows the same conditioning strategy, but you can use this approach:
def division(x, y):
return x/y if y else 0
Con of your add one strategy is that if y is a small number (not -1) then your results will be very incorrect. Only sort of works when y is very large.
Con of returning NaN is that you need to document this clearly for the person calling your function. np.nan can surprise the caller. For example what is expected when you do comparison like division(1, 0) == division(2,0)
Raising an error is the right thing to do and let the caller handle according to their rules.
Keep in mind that numpy.true_divide() never returns ZeroDivisionError. Returns inf. instead.
i.e
a = [1,2,3]
b = [0,1,2]
np.true_divide(a, b)
RuntimeWarning: divide by zero encountered in true_divide
array([inf, 2. , 1.5])
It usually means that your algorithm is not carefully designed. Just taking care of +/- 0 is not going to help you in most cases. Almost every algorithm in literature deals with division by zero either by adding an ε to the absolute value or by thresholding the absolute value. One could also avoid such cases by limiting processing only on those values where denominator is significant.

Python Iteration Homework [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have 2 questions I need to ask for help with. One question I don't entirely understand so if someone could help me to that would be great.
Question One (the one I don't entirely understand):
One definition of e is
Formula for e
This can be calculated as my_e = 1/math.factorial(0) + 1/math.factorial(1) + 1/math.factorial(2) + 1/math.factorial(3) + …
Let n be the input number of the math.factorial() function. n successively takes on 0, 1, 2, 3 and so on. Find the smallest n such that the absolute value of (my_e – math.e) is less than or equal to 10-10. That is, abs(my_e - math.e) <= (10 ** -10).
I just don't entirely understand what I am being asked to do. Clarification would be great. Thanks!
Question 2:
Ask the user to type in a series of integers. Sum them up and print out the sum and the number of integers the user has entered.
My code
So what should happen is after I enter the numbers I want to enter and hit the enter key, it should calculate and print out "sum = 25 count = 3". The screenshot shows what error message I am getting.
Any help you have is welcomed and greatly appreciated.
As far as you first question goes:
>>> import math
>>> math.e
2.718281828459045
>>> sum(1.0/math.factorial(i) for i in range(5))
2.708333333333333
>>> abs(sum(1.0/math.factorial(i) for i in range(5)) - math.e) < 10**-10
False
>>> abs(sum(1.0/math.factorial(i) for i in range(30)) - math.e) < 10**-10
True
So, somewhere between n == 5 and n == 30 you get 10 decimal places for e. Create the sum term by term in a while-loop (instead of by using the sum function as I have, since you are unlikely to have seen that syntax yet). At each pass through the loop, compare the sum with math.e. Stop when you get the target accuracy. Return the final n.

How can I write a program in python that approximates the value of pi by summing the terms of the Leibniz series? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Below are the guidelines for the problem. My class is using Python 3.5. Thank you so much!
Write a program that approximates the value of pi by summing the terms of the Gregory Leibniz
series:
-4/1 – 4/3 + 4/5 – 4/7 + 4/9 – 4/11 + 4/13 …
-The program must prompt the user for the number of terms to sum, then display the iteration number, approximation of pi, and the absolute value of the difference between pi from the math library and your approximation each time a new term is included in the series.
This is what I have so far:
def main():
n = int(input("Please enter a value for N:"))
for i in range(1,n,7):
total = ((1.0/(i+i+1))-(1.0)/(i+i+2))+(1.0)/(i+i+4)
value = 4*(1-total)
print(value)
main()
There are 3 things wrong with your code:
You're incrementing i by 7 in range(1, n, 7).
Every second term in the Leibniz series is negative, yours is not.
You are not adding the terms to total, you are only storing the last value into total.
Editing your code, this will give you what you want:
def main():
n = int(input("Please enter a value for N:"))
total=0
for i in range(1,n):
total += (-1)**(i+1)*((1.0/(i+i+1)))
value = 4*(1-total)
print(value)
main()
Now giving a value of 1000 for N, you would get 3.1405926538397924.
Oups!
You made great efforts to make as many mistakes in so few lines of code :-)
As every second term in Leibniz series is negative, you should process numbers stepping by 2:
def main():
n = int(input("Please enter a value for N:"))
total = 0
for i in range(0,n,2):
total += ((1.0/(i+i+1))-(1.0)/(i+i+3))
value = 4*total
print(value)
But Leibniz series has a very slow convergence. For n=10000 you still only get 3.14149265359 ...

Pi calculation in python [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
n=iterations
for some reason this code will need a lot more iterations for more accurate result from other codes, Can anyone explain why this is happening? thanks.
n,s,x=1000,1,0
for i in range(0,n,2):
x+=s*(1/(1+i))*4
s=-s
print(x)
As I mentioned in a comment, the only way to speed this is to transform the sequence. Here's a very simple way, related to the Euler transformation (see roippi's link): for the sum of an alternating sequence, create a new sequence consisting of the average of each pair of successive partial sums. For example, given the alternating sequence
a0 -a1 +a2 -a3 +a4 ...
where all the as are positive, the sequences of partial sums is:
s0=a0 s1=a0-a1 s2=a0-a1+a2 s3=a0-a1+a2-a3 s4=a0-a1+a2-a3+a4 ...
and then the new derived sequence is:
(s0+s1)/2 (s1+s2)/2 (s2+s3)/2 (s3+s4)/2 ...
That can often converge faster - and the same idea can applied to this sequence. That is, create yet another new sequence averaging the terms of that sequence. This can be carried on indefinitely. Here I'll take it one more level:
from math import pi
def leibniz():
from itertools import count
s, x = 1.0, 0.0
for i in count(1, 2):
x += 4.0*s/i
s = -s
yield x
def avg(seq):
a = next(seq)
while True:
b = next(seq)
yield (a + b) / 2.0
a = b
base = leibniz()
d1 = avg(base)
d2 = avg(d1)
d3 = avg(d2)
for i in range(20):
x = next(d3)
print("{:.6f} {:8.4%}".format(x, (x - pi)/pi))
Output:
3.161905 0.6466%
3.136508 -0.1619%
3.143434 0.0586%
3.140770 -0.0262%
3.142014 0.0134%
3.141355 -0.0076%
3.141736 0.0046%
3.141501 -0.0029%
3.141654 0.0020%
3.141550 -0.0014%
3.141623 0.0010%
3.141570 -0.0007%
3.141610 0.0005%
3.141580 -0.0004%
3.141603 0.0003%
3.141585 -0.0003%
3.141599 0.0002%
3.141587 -0.0002%
3.141597 0.0001%
3.141589 -0.0001%
So after just 20 terms, we've already got pi to about 6 significant digits. The base Leibniz sequence is still at about 2 digits correct:
>>> next(base)
3.099944032373808
That's an enormous improvement. A key point here is that the partial sums of the base Leibniz sequence give approximations that alternate between "too big" and "too small". That's why averaging them gets closer to the truth. The same (alternating between "too big" and "too small") is also true of the derived sequences, so averaging their terms also helps.
That's all hand-wavy, of course. Rigorous justification probably isn't something you're interested in ;-)
That is because you are using the Leibniz series and it is known to converge very (very) slowly.

Categories

Resources