Finding the sum of a geometric progression - python

I'm being asked to add the first 100 terms f the sequence (1 + 1/2 + 1/4 + 1/8 ...etc)
what i ve been trying is something Iike
for x in range(101):
n = ((1)/(2**x))
sum(n)
gives me an error, guess you cant put ranges to a power
print(n)
will give me a list of all the values, but i need them summed together
anyone able to give me a hand?
using qtconsole if that's of any relevance, i'm quite new to this if you haven't already guessed

You keep only one value at a time. If you want the sum, you need to aggregate the results, and for that you'd need an initial value, to which you can add each round the current term:
n = 0 # initial value
for x in range(100):
n += 1 / 2**x # add current term
print(n)

Hmm, there is actually a formula for sum of geometric series:
In your question, a is 1, r is 0.5 and n is 100
So we can do like
a = 1
r = 0.5
n = 100
print(a * (1 - r ** n) / (1 - r))

It is important to initialize sum_n to zero. With each iteration, you add (1/2**x) from your sequence/series to sum_n until you reach n_range.
n_range = 101
sum_n = 0 # initialize sum_n to zero
for x in range(n_range):
sum_n += (1/(2**x))
print(sum_n)

You are getting an error because sum takes an iterable and you are passing it a float:
sum(iterable[, start])
To solve your problem, as others have suggested, you need to init an accumulator and add your power on every iteration.
If you absolutely must use the sum function:
>>> import math
>>> sum(map(lambda x:math.pow(2,-x),range(100)))
2.0

Related

Summation of multiples

I am learning python and can't get my head around this program.
I just can't seem to find the right loop to get the result.
Q:Create a Python function named sum Of Multiples that has two integer parameters x and n.
Example:sum Of Multiples(3,5);
Expected output:46
This is simple math, the sum is equivalent to 1 + x*(1+2+3+...+n), so 1 + x*(n*(n+1)//2):
def sumOfMultiples(x,n):
print(1+x*n*(n+1)//2)
sumOfMultiples(3, 5)
46
sum = 1 + x + 2x + 3x + ... +
could be written as sum = 1+x(0+1+2+3+...)
so just use a for loop from 0 to n or n+1 depending on where you're supposed to stop and multiply the result with x. Or even shorter use sum and range:
def sumOfMultiples(x, n):
print(1+sum(range(n+1))*x)
The question basically is asking you to sum all n mutliples of x. So just do this,
def sumOfMultiples(x, n):
m_sum = 1
for i in range(1, n+1):
m_sum += i*x
return m_sum
sumOfMultiples(3,5)
You can also do this,
sumOfMultiples = lambda x,n: sum([1] + [x*i for i in range(1, n+1)])
sumOfMultiples(3,5)
Let's just say this should get the job done, but not really optimized:
def sumOfMultiples(x,n):
x_muti = [1]
for i in range(1,n+1):
x_muti.append(x*i)
print(sum(x_muti))
sumOfMultiples(3,5)

Is ther any other way to get sum 1 to 100 with recursion?

I'm studing recursive function and i faced question of
"Print sum of 1 to n with no 'for' or 'while' "
ex ) n = 10
answer =
55
n = 100
answer = 5050
so i coded
import sys
sys.setrecursionlimit(1000000)
sum = 0
def count(n):
global sum
sum += n
if n!=0:
count(n-1)
count(n = int(input()))
print(sum)
I know it's not good way to get right answer, but there was a solution
n=int(input())
def f(x) :
if x==1 :
return 1
else :
return ((x+1)//2)*((x+1)//2)+f(x//2)*2
print(f(n))
and it works super well , but i really don't know how can human think that logic and i have no idea how it works.
Can you guys explain how does it works?
Even if i'm looking that formula but i don't know why he(or she) used like that
And i wonder there is another solution too (I think it's reall important to me)
I'm really noob of python and code so i need you guys help, thank you for watching this
Here is a recursive solution.
def rsum(n):
if n == 1: # BASE CASE
return 1
else: # RECURSIVE CASE
return n + rsum(n-1)
You can also use range and sum to do so.
n = 100
sum_1_to_n = sum(range(n+1))
you can try this:
def f(n):
if n == 1:
return 1
return n + f(n - 1)
print(f(10))
this function basically goes from n to 1 and each time it adds the current n, in the end, it returns the sum of n + n - 1 + ... + 1
In order to get at a recursive solution, you have to (re)define your problems in terms of finding the answer based on the result of a smaller version of the same problem.
In this case you can think of the result sumUpTo(n) as adding n to the result of sumUpTo(n-1). In other words: sumUpTo(n) = n + sumUpTo(n-1).
This only leaves the problem of finding a value of n for which you know the answer without relying on your sumUpTo function. For example sumUpTo(0) = 0. That is called your base condition.
Translating this to Python code, you get:
def sumUpTo(n): return 0 if n==0 else n + sumUpTo(n-1)
Recursive solutions are often very elegant but require a different way of approaching problems. All recursive solutions can be converted to non-recursive (aka iterative) and are generally slower than their iterative counterpart.
The second solution is based on the formula ∑1..n = n*(n+1)/2. To understand this formula, take a number (let's say 7) and pair up the sequence up to that number in increasing order with the same sequence in decreasing order, then add up each pair:
1 2 3 4 5 6 7 = 28
7 6 5 4 3 2 1  = 28
-- -- -- -- -- -- -- --
8 8 8 8 8 8 8 = 56
Every pair will add up to n+1 (8 in this case) and you have n (7) of those pairs. If you add them all up you get n*(n+1) = 56 which correspond to adding the sequence twice. So the sum of the sequence is half of that total n*(n+1)/2 = 28.
The recursion in the second solution reduces the number of iterations but is a bit artificial as it serves only to compensate for the error introduced by propagating the integer division by 2 to each term instead of doing it on the result of n*(n+1). Obviously n//2 * (n+1)//2 isn't the same as n*(n+1)//2 since one of the terms will lose its remainder before the multiplication takes place. But given that the formula to obtain the result mathematically is part of the solution doing more than 1 iteration is pointless.
There are 2 ways to find the answer
1. Recursion
def sum(n):
if n == 1:
return 1
if n <= 0:
return 0
else:
return n + sum(n-1)
print(sum(100))
This is a simple recursion code snippet when you try to apply the recurrent function
F_n = n + F_(n-1) to find the answer
2. Formula
Let S = 1 + 2 + 3 + ... + n
Then let's do something like this
S = 1 + 2 + 3 + ... + n
S = n + (n - 1) + (n - 2) + ... + 1
Let's combine them and we get
2S = (n + 1) + (n + 1) + ... + (n + 1) - n times
From that you get
S = ((n + 1) * n) / 2
So for n = 100, you get
S = 101 * 100 / 2 = 5050
So in python, you will get something like
sum = lambda n: ( (n + 1) * n) / 2
print(sum(100))

Incorrect answer while calculating pi value from given series

I was trying to calculate value of pi using this formula:
I had written this code for finding it for a given n:
def pisum(n):
sum=3.0
x=2.0
while (n>0):
if n%2==1:
sum=sum+(4/(x*(x+1)*(x+2)))
else :
sum=sum-(4/(x*(x+1)*(x+2)))
x=x+2
n=n-1
return str(sum)
It runs fine for n=0 and n=1 and gives output 3.0, 3.16666666667. But for n=50 the output should be 3.1415907698497954 but it is giving 2.85840923015. Why so much difference? Please help to correct if i had done something wrong.
The problem is that you are using n%2 in order to determine whether to subtract or add. It is not the amount of loops that you start with that should matter, but which loop you're in. To see that, try using your function for an odd number, e.g. 51 and you will see that it will give you a correct answer.
To explain further, if you start with n=50, you will initially subtract (4/(x*(x+1)*(x+2))) from 3 rather than add to it, but if you start with n=51, you will initially add.
If you modify your function as follows:
def pisum(n):
sum = 3.0
x = 2.0
for i in range(n):
if i % 2 == 0:
sum = sum + (4 / (x * (x + 1) * (x + 2)))
else:
sum = sum - (4 / (x * (x + 1) * (x + 2)))
x = x + 2
return str(sum)
you will always get a correct result.
You made a small mistake.
One correct program:
def pisum(n):
sum = 3.
for i in xrange(2, 2*n+2, 2):
sum += (4. if (i&2) == 2 else -4.)/i/(i+1)/(i+2)
return sum
Being more conservative with number of lines:
def pisum(n):
return 3. + sum([(4. if (i&2) == 2 else -4.)/i/(i+1)/(i+2) for i in xrange(2,2*n+2,2)])
Mistake in yours:
You are iterating on n in reverse, thus one time (odd value of n) you are calculating:
and for another value of n (even value apart from 0) you are calculating

Sum a sequence of numbers

Given: Two positive integers a and b (a
Return: The sum of all odd integers from a through b, inclusively.
#My code:
a = 100
b = 200
for i in range(a,b):
if i%2 == 1:
print i
At the moment it's just showing a drop down list of all the odd integers. I do not know how to affix a "range" to this properly, if need be. How can I add on to my code above to get the sum of all the odd integers?
Thanks
Sum all the numbers between a and b if odd.
sum(i for i in xrange(a, b) if i%2)
A rather quick way to do it would be:
result = 0
for i in range(a,b+1):
if i%2 == 1:
result += i
print result
There are a bunch of ways to do this. If you think about the math, though, it's a lot like Gauss's old problem. Gauss was asked to add the numbers between 1 and 100, and he realized that each pair of high and low values summed to 101 (100 + 1, 99 + 2, 98 + 3…)
high = b
low = a
So we have to multiply some number of b + a values. How many are there? For all the integers, that's just
num_pairs = (high-low) // 2
Then we multiply that number by high + low to get the answer:
result = (high + low) * num_pairs
But you only want every other ones, so we divide by two again:
result //= 2
Totally:
def sumrange(low, high, step):
num_pairs = (high - low) // 2
result = (high + low) * num_pairs
return result // step
or sumrange = lambda low, high, step: (high - low) * (high + low) // (2 * step)
Now this still isn't quite an answer to your question, because it needs to be offset depending on whether your low value is odd, and whether your high value is included or excluded. But I will leave that as an exercise.
Making this a CW answer so someone can edit if my math is messy.
Some mathematical tricks can solve your problem much efficiently.
For example, sum of first n odd numbers = n*n square(n)
So you can use for
Sum of odd numbers [m,n] = n*n - (m-2)*(m-2) where m!=1 and m and n are odds
One more useful analysis is, AP (arithmetic progression)
Formula : (n/2)*(a+l) where n= no. of elements, a = first term, l= last term
Here,
a = m [if m is odd]
a = m+1 [if m is even]
l = n [if n is odd]
l = n-1 [if n is even]
n = ( ( l - a ) / 2 ) + 1
By applying in code, you can easily get the answer...
And the numpy version of the solution:
import numpy as np
a = 100
b = 200
r = np.linspace(a,b-1,b-a)
r = np.sum(np.mod(r,2)*r)
print(r)

Generating digits of square root of 2

I want to generate the digits of the square root of two to 3 million digits.
I am aware of Newton-Raphson but I don't have much clue how to implement it in C or C++ due to lack of biginteger support. Can somebody point me in the right direction?
Also, if anybody knows how to do it in python (I'm a beginner), I would also appreciate it.
You could try using the mapping:
a/b -> (a+2b)/(a+b) starting with a= 1, b= 1. This converges to sqrt(2) (in fact gives the continued fraction representations of it).
Now the key point: This can be represented as a matrix multiplication (similar to fibonacci)
If a_n and b_n are the nth numbers in the steps then
[1 2] [a_n b_n]T = [a_(n+1) b_(n+1)]T
[1 1]
which now gives us
[1 2]n [a_1 b_1]T = [a_(n+1) b_(n+1)]T
[1 1]
Thus if the 2x2 matrix is A, we need to compute An which can be done by repeated squaring and only uses integer arithmetic (so you don't have to worry about precision issues).
Also note that the a/b you get will always be in reduced form (as gcd(a,b) = gcd(a+2b, a+b)), so if you are thinking of using a fraction class to represent the intermediate results, don't!
Since the nth denominators is like (1+sqrt(2))^n, to get 3 million digits you would likely need to compute till the 3671656th term.
Note, even though you are looking for the ~3.6 millionth term, repeated squaring will allow you to compute the nth term in O(Log n) multiplications and additions.
Also, this can easily be made parallel, unlike the iterative ones like Newton-Raphson etc.
EDIT: I like this version better than the previous. It's a general solution that accepts both integers and decimal fractions; with n = 2 and precision = 100000, it takes about two minutes. Thanks to Paul McGuire for his suggestions & other suggestions welcome!
def sqrt_list(n, precision):
ndigits = [] # break n into list of digits
n_int = int(n)
n_fraction = n - n_int
while n_int: # generate list of digits of integral part
ndigits.append(n_int % 10)
n_int /= 10
if len(ndigits) % 2: ndigits.append(0) # ndigits will be processed in groups of 2
decimal_point_index = len(ndigits) / 2 # remember decimal point position
while n_fraction: # insert digits from fractional part
n_fraction *= 10
ndigits.insert(0, int(n_fraction))
n_fraction -= int(n_fraction)
if len(ndigits) % 2: ndigits.insert(0, 0) # ndigits will be processed in groups of 2
rootlist = []
root = carry = 0 # the algorithm
while root == 0 or (len(rootlist) < precision and (ndigits or carry != 0)):
carry = carry * 100
if ndigits: carry += ndigits.pop() * 10 + ndigits.pop()
x = 9
while (20 * root + x) * x > carry:
x -= 1
carry -= (20 * root + x) * x
root = root * 10 + x
rootlist.append(x)
return rootlist, decimal_point_index
As for arbitrary big numbers you could have a look at The GNU Multiple Precision Arithmetic Library (for C/C++).
For work? Use a library!
For fun? Good for you :)
Write a program to imitate what you would do with pencil and paper. Start with 1 digit, then 2 digits, then 3, ..., ...
Don't worry about Newton or anybody else. Just do it your way.
Here is a short version for calculating the square root of an integer a to digits of precision. It works by finding the integer square root of a after multiplying by 10 raised to the 2 x digits.
def sqroot(a, digits):
a = a * (10**(2*digits))
x_prev = 0
x_next = 1 * (10**digits)
while x_prev != x_next:
x_prev = x_next
x_next = (x_prev + (a // x_prev)) >> 1
return x_next
Just a few caveats.
You'll need to convert the result to a string and add the decimal point at the correct location (if you want the decimal point printed).
Converting a very large integer to a string isn't very fast.
Dividing very large integers isn't very fast (in Python) either.
Depending on the performance of your system, it may take an hour or longer to calculate the square root of 2 to 3 million decimal places.
I haven't proven the loop will always terminate. It may oscillate between two values differing in the last digit. Or it may not.
The nicest way is probably using the continued fraction expansion [1; 2, 2, ...] the square root of two.
def root_two_cf_expansion():
yield 1
while True:
yield 2
def z(a,b,c,d, contfrac):
for x in contfrac:
while a > 0 and b > 0 and c > 0 and d > 0:
t = a // c
t2 = b // d
if not t == t2:
break
yield t
a = (10 * (a - c*t))
b = (10 * (b - d*t))
# continue with same fraction, don't pull new x
a, b = x*a+b, a
c, d = x*c+d, c
for digit in rdigits(a, c):
yield digit
def rdigits(p, q):
while p > 0:
if p > q:
d = p // q
p = p - q * d
else:
d = (10 * p) // q
p = 10 * p - q * d
yield d
def decimal(contfrac):
return z(1,0,0,1,contfrac)
decimal((root_two_cf_expansion()) returns an iterator of all the decimal digits. t1 and t2 in the algorithm are minimum and maximum values of the next digit. When they are equal, we output that digit.
Note that this does not handle certain exceptional cases such as negative numbers in the continued fraction.
(This code is an adaptation of Haskell code for handling continued fractions that has been floating around.)
Well, the following is the code that I wrote. It generated a million digits after the decimal for the square root of 2 in about 60800 seconds for me, but my laptop was sleeping when it was running the program, it should be faster that. You can try to generate 3 million digits, but it might take a couple days to get it.
def sqrt(number,digits_after_decimal=20):
import time
start=time.time()
original_number=number
number=str(number)
list=[]
for a in range(len(number)):
if number[a]=='.':
decimal_point_locaiton=a
break
if a==len(number)-1:
number+='.'
decimal_point_locaiton=a+1
if decimal_point_locaiton/2!=round(decimal_point_locaiton/2):
number='0'+number
decimal_point_locaiton+=1
if len(number)/2!=round(len(number)/2):
number+='0'
number=number[:decimal_point_locaiton]+number[decimal_point_locaiton+1:]
decimal_point_ans=int((decimal_point_locaiton-2)/2)+1
for a in range(0,len(number),2):
if number[a]!='0':
list.append(eval(number[a:a+2]))
else:
try:
list.append(eval(number[a+1]))
except IndexError:
pass
p=0
c=list[0]
x=0
ans=''
for a in range(len(list)):
while c>=(20*p+x)*(x):
x+=1
y=(20*p+x-1)*(x-1)
p=p*10+x-1
ans+=str(x-1)
c-=y
try:
c=c*100+list[a+1]
except IndexError:
c=c*100
while c!=0:
x=0
while c>=(20*p+x)*(x):
x+=1
y=(20*p+x-1)*(x-1)
p=p*10+x-1
ans+=str(x-1)
c-=y
c=c*100
if len(ans)-decimal_point_ans>=digits_after_decimal:
break
ans=ans[:decimal_point_ans]+'.'+ans[decimal_point_ans:]
total=time.time()-start
return ans,total
Python already supports big integers out of the box, and if that's the only thing holding you back in C/C++ you can always write a quick container class yourself.
The only problem you've mentioned is a lack of big integers. If you don't want to use a library for that, then are you looking for help writing such a class?
Here's a more efficient integer square root function (in Python 3.x) that should terminate in all cases. It starts with a number much closer to the square root, so it takes fewer steps. Note that int.bit_length requires Python 3.1+. Error checking left out for brevity.
def isqrt(n):
x = (n >> n.bit_length() // 2) + 1
result = (x + n // x) // 2
while abs(result - x) > 1:
x = result
result = (x + n // x) // 2
while result * result > n:
result -= 1
return result

Categories