So I have to approximate Pi with following way: 4*(1-1/3+1/5-1/7+1/9-...). Also it should be based on number of iterations. So the function should look like this:
>>> piApprox(1)
4.0
>>> piApprox(10)
3.04183961893
>>> piApprox(300)
3.13825932952
But it works like this:
>>> piApprox(1)
4.0
>>> piApprox(10)
2.8571428571428577
>>> piApprox(300)
2.673322240709928
What am I doing wrong? Here is the code:
def piApprox(num):
pi=4.0
k=1.0
est=1.0
while 1<num:
k+=2
est=est-(1/k)+1/(k+2)
num=num-1
return pi*est
This is what you're computing:
4*(1-1/3+1/5-1/5+1/7-1/7+1/9...)
You can fix it just by adding a k += 2 at the end of your loop:
def piApprox(num):
pi=4.0
k=1.0
est=1.0
while 1<num:
k+=2
est=est-(1/k)+1/(k+2)
num=num-1
k+=2
return pi*est
Also the way you're counting your iterations is wrong since you're adding two elements at the time.
This is a cleaner version that returns the output that you expect for 10 and 300 iterations:
def approximate_pi(rank):
value = 0
for k in xrange(1, 2*rank+1, 2):
sign = -(k % 4 - 2)
value += float(sign) / k
return 4 * value
Here is the same code but more compact:
def approximate_pi(rank):
return 4 * sum(-float(k%4 - 2) / k for k in xrange(1, 2*rank+1, 2))
Important edit:
whoever expects this approximation to yield PI -- quote from Wikipedia:
It converges quite slowly, though – after 500,000 terms, it produces
only five correct decimal digits of π
Original answer:
This is an educational example. You try to use a shortcut and attempt to implement the "oscillating" sign of the summands by handling two steps for k in the same iteration. However, you adjust k only by one step per iteration.
Usually, in math at least, an oscillating sign is achieved with (-1)**i. So, I have chosen this for a more readable implementation:
def pi_approx(num_iterations):
k = 3.0
s = 1.0
for i in range(num_iterations):
s = s-((1/k) * (-1)**i)
k += 2
return 4 * s
As you can see, I have changed your approach a bit, to improve readability. There is no need for you to check for num in a while loop, and there is no particular need for your pi variable. Your est actually is a sum that grows step by step, so why not call it s ("sum" is a built-in keyword in Python). Just multiply the sum with 4 in the end, according to your formula.
Test:
>>> pi_approx(100)
3.1514934010709914
The convergence, however, is not especially good:
>>> pi_approx(100) - math.pi
0.009900747481198291
Your expected output is flaky somehow, because your piApprox(300) (should be 3.13825932952, according to your) is too far away from PI. How did you come up with that? Is that possibly affected by an accumulated numerical error?
Edit
I would not trust the book too much in regard of what the function should return after 10 and 300 iterations. The intermediate result, after 10 steps, should be rather free of numerical errors, indeed. There, it actually makes a difference whether you take two steps of k at the same time or not. So this most likely is the difference between my pi_approx(10) and the books'. For 300 iterations, numerical error might have severely affected the result in the book. If this is an old book, and they have implemented their example in C, possibly using single precision, then a significant portion of the result may be due to accumulation of numerical error (note: this is a prime example for how bad you can be affected by numerical errors: a repeated sum of small and large values, it does not get worse!).
What counts is that you have looked at the math (the formula for PI), and you have implemented a working Python version of approximating that formula. That was the learning goal of the book, so go ahead and tackle the next problem :-).
def piApprox(num):
pi=4.0
k=3.0
est=1.0
while 1<num:
est=est-(1/k)+1/(k+2)
num=num-1
k+=4
return pi*est
Also for real task use math.pi
Here is a slightly simpler version:
def pi_approx(num_terms):
sign = 1. # +1. or -1.
pi_by_4 = 1. # first term
for div in range(3, 2 * num_terms, 2): # 3, 5, 7, ...
sign = -sign # flip sign
pi_by_4 += sign / div # add next term
return 4. * pi_by_4
which gives
>>> for n in [1, 10, 300, 1000, 3000]:
... print(pi_approx(n))
4.0
3.0418396189294032
3.1382593295155914
3.140592653839794
3.1412593202657186
While all of these answers are perfectly good approximations, if you are using the Madhava-Leibniz Series than you should arrive at ,"an approximation of π correct to 11 decimal places as 3.14159265359" within in first 21 terms according to this website: https://en.wikipedia.org/wiki/Approximations_of_%CF%80
Therefore, a more accurate solution could be any variation of this:
import math
def estimate_pi(terms):
ans = 0.0
for k in range(terms):
ans += (-1.0/3.0)**k/(2.0*k+1.0)
return math.sqrt(12)*ans
print(estimate_pi(21))
Output: 3.141592653595635
after googling a while, I'm posting here for help.
I have two float64 variables returned from a function.
Both of them are apparently 1:
>>> x, y = somefunc()
>>> print x,y
>>> if x < 1 : print "x < 1"
>>> if y < 1 : print "y < 1"
1.0 1.0
y < 1
Behavior changes when variables are defined float32, in which case the 'y<1' statement doesn't appear.
I tried setting
np.set_printoptions(precision=10)
expecting to see the differences between variables but even so, both of them appear as 1.0 when printed.
I am a bit confused at this point.
Is there a way to visualize the difference of these float64 numbers?
Can "if/then" be used reliably to check float64 numbers?
Thanks
Trevarez
The printed values are not correct. In your case y is smaller than 1 when using float64 and bigger or equal to 1 when using float32. this is expected since rounding errors depend on the size of the float.
To avoid this kind of problems, when dealing with floating point numbers you should always decide a "minimum error", usually called epsilon and, instead of comparing for equality, checking whether the result is at most distant epsilon from the target value:
In [13]: epsilon = 1e-11
In [14]: number = np.float64(1) - 1e-16
In [15]: target = 1
In [16]: abs(number - target) < epsilon # instead of number == target
Out[16]: True
In particular, numpy already provides np.allclose which can be useful to compare arrays for equality given a certain tolerance. It works even when the arguments aren't arrays(e.g. np.allclose(1 - 1e-16, 1) -> True).
Note however than numpy.set_printoptions doesn't affect how np.float32/64 are printed. It affects only how arrays are printed:
In [1]: import numpy as np
In [2]: np.float(1) - 1e-16
Out[2]: 0.9999999999999999
In [3]: np.array([1 - 1e-16])
Out[3]: array([ 1.])
In [4]: np.set_printoptions(precision=16)
In [5]: np.array([1 - 1e-16])
Out[5]: array([ 0.9999999999999999])
In [6]: np.float(1) - 1e-16
Out[6]: 0.9999999999999999
Also note that doing print y or evaluating y in the interactive interpreter gives different results:
In [1]: import numpy as np
In [2]: np.float(1) - 1e-16
Out[2]: 0.9999999999999999
In [3]: print(np.float64(1) - 1e-16)
1.0
The difference is that print calls str while evaluating calls repr:
In [9]: str(np.float64(1) - 1e-16)
Out[9]: '1.0'
In [10]: repr(np.float64(1) - 1e-16)
Out[10]: '0.99999999999999989'
In [26]: x = numpy.float64("1.000000000000001")
In [27]: print x, repr(x)
1.0 1.0000000000000011
In other words, you are plagued by loss of precision in print statement. The value is very slightly different than 1.
Following the advices provided here I summarize the answers in this way:
To make comparisons between floats, the programmer has to define a minimum distance (eps) for them to be considered different (eps=1e-12, for example). Doing so, the conditions should be written like this:
Instead of (x>a), use (x-a)>eps
Instead of (x<a), use (a-x)>eps
Instead of (x==a), use abs(x-a)<eps
This doesn't apply to comparison between integer numbers since difference between them is fixed to 1.
Hope it helps others as it helped me.
I am using scipy and want to create an an array of legnth n with a particular average.
Suppose I want an random arrays of length 3 with an average of 2.5 hence the possible options could be:
[1.5, 3.5, 2.5]
[.25, 7.2, .05]
and so on and so forth...
I need to create many such arrays with varying lengths and different averages(specified) for each, so a generalized solution will be welcome.
Just generate numbers over the range you want (0...10 in this case)
>>> import random
>>> nums = [10*random.random() for x in range(5)]
Work out the average
>>> sum(nums)/len(nums)
4.2315222659844824
Shift the average to where you want it
>>> nums = [x - 4.2315222659844824 + 2.5 for x in nums]
>>> nums
[-0.628013346633133, 4.628537956666447, -1.7219257458163257, 7.617565127420011, 2.6038360083629986]
>>> sum(nums)/len(nums)
2.4999999999999996
You can use whichever distribution/range you like. By shifting the average this way it will always get you an average of 2.5 (or very close to it)
You haven't specified what distribution you want.
It's also not clear whether you want the average of the actual array to be 2.5, or the amortized average over all arrays to be 2.5.
The simplest solution—three random numbers in an even distribution from 0 to 2*avg—is this:
return 2*avg * np.random.rand(3)
If you want to guarantee that the average of the array is 2.5, that's a pretty simple constraint, but there are many different ways you could satisfy it, and you need to describe which way you want. For example:
n0 = random.random() * 2*avg
n1 = random.random() * (2*avg - n0)
n2 = random.random() * (2*avg - n0 - n1)
return np.array((n0, n1, n2))
I found a solution to the problem.
numpy.random.triangular(left, mode, right, size=None)
Visit: http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.triangular.html#numpy.random.triangular
However, the minor problem is that it forces a triangular distribution on the samples.
I try to implement Hampel tanh estimators to normalize highly asymmetric data. In order to do this, I need to perform the following calculation:
Given x - a sorted list of numbers and m - the median of x, I need to find a such that approximately 70% of the values in x fall into the range (m-a; m+a). We know nothing about the distribution of values in x. I write in python using numpy, and the best idea that I had is to write some sort of stochastic iterative search (for example, as was described by Solis and Wets), but I suspect that there is a better approach, either in form of better algorithm or as a ready function. I searched the numpy and scipy documentation, but couldn't find any useful hint.
EDIT
Seth suggested to use scipy.stats.mstats.trimboth, however in my test for a skewed distribution, this suggestion didn't work:
from scipy.stats.mstats import trimboth
import numpy as np
theList = np.log10(1+np.arange(.1, 100))
theMedian = np.median(theList)
trimmedList = trimboth(theList, proportiontocut=0.15)
a = (trimmedList.max() - trimmedList.min()) * 0.5
#check how many elements fall into the range
sel = (theList > (theMedian - a)) * (theList < (theMedian + a))
print np.sum(sel) / float(len(theList))
The output is 0.79 (~80%, instead of 70)
You need to first symmetrize your distribution by folding all values less than the mean over to the right. Then you can use the standard scipy.stats functions on this one-sided distribution:
from scipy.stats import scoreatpercentile
import numpy as np
theList = np.log10(1+np.arange(.1, 100))
theMedian = np.median(theList)
oneSidedList = theList[:] # copy original list
# fold over to the right all values left of the median
oneSidedList[theList < theMedian] = 2*theMedian - theList[theList < theMedian]
# find the 70th centile of the one-sided distribution
a = scoreatpercentile(oneSidedList, 70) - theMedian
#check how many elements fall into the range
sel = (theList > (theMedian - a)) * (theList < (theMedian + a))
print np.sum(sel) / float(len(theList))
This gives the result of 0.7 as required.
Restate the problem slightly. You know the length of the list, and what fraction of the numbers in the list to consider. Given that, you can determine the difference between the first and last indices in the list that give you the desired range. The goal then is to find the indices that will minimize a cost function corresponding to the desired symmetric values about the median.
Let the smaller index be n1 and the larger index by n2; these are not independent. The values from the list at the indices are x[n1] = m-b and x[n2]=m+c. You now want to choose n1 (and thus n2) so that b and c are as close as possible. This occurs when (b - c)**2 is minimal. That's pretty easy using numpy.argmin. Paralleling the example in the question, here's an interactive session illustrating the approach:
$ python
Python 2.6.5 (r265:79063, Jun 12 2010, 17:07:01)
[GCC 4.3.4 20090804 (release) 1] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> theList = np.log10(1+np.arange(.1, 100))
>>> theMedian = np.median(theList)
>>> listHead = theList[0:30]
>>> listTail = theList[-30:]
>>> b = np.abs(listHead - theMedian)
>>> c = np.abs(listTail - theMedian)
>>> squaredDiff = (b - c) ** 2
>>> np.argmin(squaredDiff)
25
>>> listHead[25] - theMedian, listTail[25] - theMedian
(-0.2874888056626983, 0.27859407466756614)
What you want is scipy.stats.mstats.trimboth. Set proportiontocut=0.15. After trimming, take (max-min)/2.
How does one round a number UP in Python?
I tried round(number) but it rounds the number down. Example:
round(2.3) = 2.0
and not 3, as I would like.
The I tried int(number + .5) but it round the number down again! Example:
int(2.3 + .5) = 2
The math.ceil (ceiling) function returns the smallest integer higher or equal to x.
For Python 3:
import math
print(math.ceil(4.2))
For Python 2:
import math
print(int(math.ceil(4.2)))
I know this answer is for a question from a while back, but if you don't want to import math and you just want to round up, this works for me.
>>> int(21 / 5)
4
>>> int(21 / 5) + (21 % 5 > 0)
5
The first part becomes 4 and the second part evaluates to "True" if there is a remainder, which in addition True = 1; False = 0. So if there is no remainder, then it stays the same integer, but if there is a remainder it adds 1.
If working with integers, one way of rounding up is to take advantage of the fact that // rounds down: Just do the division on the negative number, then negate the answer. No import, floating point, or conditional needed.
rounded_up = -(-numerator // denominator)
For example:
>>> print(-(-101 // 5))
21
Interesting Python 2.x issue to keep in mind:
>>> import math
>>> math.ceil(4500/1000)
4.0
>>> math.ceil(4500/1000.0)
5.0
The problem is that dividing two ints in python produces another int and that's truncated before the ceiling call. You have to make one value a float (or cast) to get a correct result.
In javascript, the exact same code produces a different result:
console.log(Math.ceil(4500/1000));
5
You might also like numpy:
>>> import numpy as np
>>> np.ceil(2.3)
3.0
I'm not saying it's better than math, but if you were already using numpy for other purposes, you can keep your code consistent.
Anyway, just a detail I came across. I use numpy a lot and was surprised it didn't get mentioned, but of course the accepted answer works perfectly fine.
Use math.ceil to round up:
>>> import math
>>> math.ceil(5.4)
6.0
NOTE: The input should be float.
If you need an integer, call int to convert it:
>>> int(math.ceil(5.4))
6
BTW, use math.floor to round down and round to round to nearest integer.
>>> math.floor(4.4), math.floor(4.5), math.floor(5.4), math.floor(5.5)
(4.0, 4.0, 5.0, 5.0)
>>> round(4.4), round(4.5), round(5.4), round(5.5)
(4.0, 5.0, 5.0, 6.0)
>>> math.ceil(4.4), math.ceil(4.5), math.ceil(5.4), math.ceil(5.5)
(5.0, 5.0, 6.0, 6.0)
I am surprised nobody suggested
(numerator + denominator - 1) // denominator
for integer division with rounding up. Used to be the common way for C/C++/CUDA (cf. divup)
The syntax may not be as pythonic as one might like, but it is a powerful library.
https://docs.python.org/2/library/decimal.html
from decimal import *
print(int(Decimal(2.3).quantize(Decimal('1.'), rounding=ROUND_UP)))
For those who want to round up a / b and get integer:
Another variant using integer division is
def int_ceil(a, b):
return (a - 1) // b + 1
>>> int_ceil(19, 5)
4
>>> int_ceil(20, 5)
4
>>> int_ceil(21, 5)
5
Note: a and b must be non-negative integers
Here is a way using modulo and bool
n = 2.3
int(n) + bool(n%1)
Output:
3
Try this:
a = 211.0
print(int(a) + ((int(a) - a) != 0))
Be shure rounded value should be float
a = 8
b = 21
print math.ceil(a / b)
>>> 0
but
print math.ceil(float(a) / b)
>>> 1.0
The above answers are correct, however, importing the math module just for this one function usually feels like a bit of an overkill for me. Luckily, there is another way to do it:
g = 7/5
g = int(g) + (not g.is_integer())
True and False are interpreted as 1 and 0 in a statement involving numbers in python. g.is_interger() basically translates to g.has_no_decimal() or g == int(g). So the last statement in English reads round g down and add one if g has decimal.
In case anyone is looking to round up to a specific decimal place:
import math
def round_up(n, decimals=0):
multiplier = 10 ** decimals
return math.ceil(n * multiplier) / multiplier
Without importing math // using basic envionment:
a) method / class method
def ceil(fl):
return int(fl) + (1 if fl-int(fl) else 0)
def ceil(self, fl):
return int(fl) + (1 if fl-int(fl) else 0)
b) lambda:
ceil = lambda fl:int(fl)+(1 if fl-int(fl) else 0)
>>> def roundup(number):
... return round(number+.5)
>>> roundup(2.3)
3
>>> roundup(19.00000000001)
20
This function requires no modules.
x * -1 // 1 * -1
Confusing but it works: For x=7.1, you get 8.0. For x = -1.1, you get -1.0
No need to import a module.
For those who doesn't want to use import.
For a given list or any number:
x = [2, 2.1, 2.5, 3, 3.1, 3.5, 2.499,2.4999999999, 3.4999999,3.99999999999]
You must first evaluate if the number is equal to its integer, which always rounds down. If the result is True, you return the number, if is not, return the integer(number) + 1.
w = lambda x: x if x == int(x) else int(x)+1
[w(i) for i in z]
>>> [2, 3, 3, 3, 4, 4, 3, 3, 4, 4]
Math logic:
If the number has decimal part: round_up - round_down == 1, always.
If the number doens't have decimal part: round_up - round_down == 0.
So:
round_up == x + round_down
With:
x == 1 if number != round_down
x == 0 if number == round_down
You are cutting the number in 2 parts, the integer and decimal. If decimal isn't 0, you add 1.
PS:I explained this in details since some comments above asked for that and I'm still noob here, so I can't comment.
If you don't want to import anything, you can always write your own simple function as:
def RoundUP(num):
if num== int(num):
return num
return int(num + 1)
To do it without any import:
>>> round_up = lambda num: int(num + 1) if int(num) != num else int(num)
>>> round_up(2.0)
2
>>> round_up(2.1)
3
I know this is from quite a while back, but I found a quite interesting answer, so here goes:
-round(-x-0.5)
This fixes the edges cases and works for both positive and negative numbers, and doesn't require any function import
Cheers
I'm surprised I haven't seen this answer yet round(x + 0.4999), so I'm going to put it down. Note that this works with any Python version. Changes made to the Python rounding scheme has made things difficult. See this post.
Without importing, I use:
def roundUp(num):
return round(num + 0.49)
testCases = list(x*0.1 for x in range(0, 50))
print(testCases)
for test in testCases:
print("{:5.2f} -> {:5.2f}".format(test, roundUp(test)))
Why this works
From the docs
For the built-in types supporting round(), values are rounded to the closest multiple of 10 to the power minus n; if two multiples are equally close, rounding is done toward the even choice
Therefore 2.5 gets rounded to 2 and 3.5 gets rounded to 4. If this was not the case then rounding up could be done by adding 0.5, but we want to avoid getting to the halfway point. So, if you add 0.4999 you will get close, but with enough margin to be rounded to what you would normally expect. Of course, this will fail if the x + 0.4999 is equal to [n].5000, but that is unlikely.
You could use round like this:
cost_per_person = round(150 / 2, 2)
You can use floor devision and add 1 to it.
2.3 // 2 + 1
when you operate 4500/1000 in python, result will be 4, because for default python asume as integer the result, logically:
4500/1000 = 4.5 --> int(4.5) = 4
and ceil of 4 obviouslly is 4
using 4500/1000.0 the result will be 4.5 and ceil of 4.5 --> 5
Using javascript you will recieve 4.5 as result of 4500/1000, because javascript asume only the result as "numeric type" and return a result directly as float
Good Luck!!
I think you are confusing the working mechanisms between int() and round().
int() always truncates the decimal numbers if a floating number is given; whereas round(), in case of 2.5 where 2 and 3 are both within equal distance from 2.5, Python returns whichever that is more away from the 0 point.
round(2.5) = 3
int(2.5) = 2
My share
I have tested print(-(-101 // 5)) = 21 given example above.
Now for rounding up:
101 * 19% = 19.19
I can not use ** so I spread the multiply to division:
(-(-101 //(1/0.19))) = 20
I'm basically a beginner at Python, but if you're just trying to round up instead of down why not do:
round(integer) + 1