Re: no sign() function ?
Steven D'Aprano st...@remove-this-cybersource.com.au wrote: sign_0 : 0.375 sign_1 : 0.444 (+18%) sign_2 : 0.661 (+76%) sign_3 : 0.498 (+33%) Looking at those results, and remembering that each time is for one million iterations of one thousand calls each, one million iteration only, that's enough but yes indeed this function is fast. I'd say that there's so little difference in speed between them, that you should choose whichever function is easier to understand. Yes, you're right. I just made those test for pure intellectual reason. For me sign_0 is the simplest one to understood. So in the domain of my little arcade game, this is what i'll use. I don't need the accuraccy of sign_1, because in the application i just need to know if the target is right or left or if the speed direction is right or left. At least until you profile your application and discover that the sign() function is the bottleneck keeping your program slow. In each frame i'll have to use about 10 to 20 sign() call, so it'll not be the bottleneck. -- Pierre-Alain Dorangehttp://microwar.sourceforge.net/ Ce message est sous licence Creative Commons by-nc-sa-2.0 http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
On Dec 24, 5:59 am, pdora...@pas-de-pub-merci.mac.com (Pierre-Alain Dorange) wrote: For me sign_0 is the simplest one to understood. So in the domain of my little arcade game, this is what i'll use. I don't need the accuraccy of sign_1, because in the application i just need to know if the target is right or left or if the speed direction is right or left. If there is a chance of getting bogus input to sign_0 (like a list, None or other non-numeric types) it might be worth to add a quick check like: def sign_0(x): x + 0 if x==0.0: ... -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
pdora...@pas-de-pub-merci.mac.com (Pierre-Alain Dorange) writes: def sign_0(x): if x==0.0: return 0.0 elif x0.0: return 1.0 else: return -1.0 This might be slightly faster: def sign(x): return 1 if x 0 else x and -1 -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
Steven D'Aprano ste...@remove.this.cybersource.com.au wrote: But this is just duplicating what timeit already does. Trust me, learn to use it, you won't be sorry. Here's a trick that took me a long time to learn: instead of copying your functions into the setup code of timeit, you can just import them. Thanks for the advise, i made the test using timeit and your very interesting method to import... Now i know how to use timeit simply ;-) New results on 1000 float values randomized from -500.0 to +500.0. Each test is timeit(1000) sign_0 : 0.375 sign_1 : 0.444 (+18%) sign_2 : 0.661 (+76%) sign_3 : 0.498 (+33%) It seems it don't change the relative results between the methods. Using timeit make measure accurate and remove print/range footprints. I also try Arnaud's proposition, it make sign_0 just a little better (-1%) -- Pierre-Alain Dorangehttp://microwar.sourceforge.net/ Ce message est sous licence Creative Commons by-nc-sa-2.0 http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
All algorithm including my own suffer from one mistake. Nobody accounts for NaN (not a number). You have to check for NaNs, too. NaNs have no sign at all. You could also try to do some fancy bit mask operation like ord(struct.pack(d, 0.)[7]) 0x80 0 ord(struct.pack(d, -0.)[7]) 0x80 128 But you have to take care of little endian, big endian and mixd endian IEEE 754 platforms, too. There are also platforms that don't have IEEE 754 floats at all ... Have fun :) Christian -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
On Dec 23, 2:59 pm, Christian Heimes li...@cheimes.de wrote: All algorithm including my own suffer from one mistake. Nobody accounts for NaN (not a number). You have to check for NaNs, too. NaNs have no sign at all. I think that's not quite true: NaNs have a sign; it's just not accorded any particular meaning by IEEE 754---in particular, the standard says nothing about the sign of a NaN result for most arithmetic operations. However, the sign bit of a NaN does play its usual role in operations like copysign, abs, negation. For example, here's a Python 2.6 session on OS X, where the 'default' nan is negative, in the sense that its sign bit is set: nan = float('nan') from math import copysign copysign(5.0, nan) -5.0 copysign(5.0, -nan) 5.0 copysign(5.0, abs(nan)) 5.0 Mark -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
On Dec 22, 9:18 am, Christian Heimes li...@cheimes.de wrote: Sure? :) Are you aware that the IEEE 754 standard makes a difference between the floats +0.0 and -0.0? from math import atan2 def sign(x): if x 0 or (x == 0 and atan2(x, -1.) 0.): return 1 else: return -1 Is x ** 0 0. instead of atan2(x, -1.) 0. unreliable across platforms? -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
On Dec 23, 4:27 pm, ajaksu aja...@gmail.com wrote: Is x ** 0 0. instead of atan2(x, -1.) 0. unreliable across platforms? x**0 doesn't distinguish between x = -0.0 and x = 0.0. I suspect you're confusing -0.0**0.0 with (-0.0)**0.0. Mark -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
On Dec 23, 2:45 pm, Mark Dickinson dicki...@gmail.com wrote: On Dec 23, 4:27 pm, ajaksu aja...@gmail.com wrote: Is x ** 0 0. instead of atan2(x, -1.) 0. unreliable across platforms? x**0 doesn't distinguish between x = -0.0 and x = 0.0. I suspect you're confusing -0.0**0.0 with (-0.0)**0.0. Yes, fooled me :) Thanks for the heads-up! Daniel -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
On Tue, 23 Dec 2008 14:36:53 +0100, Pierre-Alain Dorange wrote: Steven D'Aprano ste...@remove.this.cybersource.com.au wrote: But this is just duplicating what timeit already does. Trust me, learn to use it, you won't be sorry. Here's a trick that took me a long time to learn: instead of copying your functions into the setup code of timeit, you can just import them. Thanks for the advise, i made the test using timeit and your very interesting method to import... Now i know how to use timeit simply ;-) New results on 1000 float values randomized from -500.0 to +500.0. Each test is timeit(1000) sign_0 : 0.375 sign_1 : 0.444 (+18%) sign_2 : 0.661 (+76%) sign_3 : 0.498 (+33%) Looking at those results, and remembering that each time is for one million iterations of one thousand calls each, I'd say that there's so little difference in speed between them, that you should choose whichever function is easier to understand. At least until you profile your application and discover that the sign() function is the bottleneck keeping your program slow. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
no sign() function ?
I don't find any sign(x) function in the math library (return the sign of the value). I've read that math module is a wrapper to C math lib and that C math lib has not sign(), so... I've implement my own sign function of course (it's easy) but a standard one in math would be better and could be faster. How do you implement this or is there any other module with a sign() function ? -- Pierre-Alain Dorangehttp://microwar.sourceforge.net/ Ce message est sous licence Creative Commons by-nc-sa-2.0 http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
Pierre-Alain Dorange schrieb: I don't find any sign(x) function in the math library (return the sign of the value). I've read that math module is a wrapper to C math lib and that C math lib has not sign(), so... Starting with Python 2.6 the math and cmath modules have a copysign function. I've implement my own sign function of course (it's easy) but a standard one in math would be better and could be faster. Sure? :) Are you aware that the IEEE 754 standard makes a difference between the floats +0.0 and -0.0? from math import atan2 def sign(x): if x 0 or (x == 0 and atan2(x, -1.) 0.): return 1 else: return -1 -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
Christian Heimes li...@cheimes.de wrote: Pierre-Alain Dorange schrieb: I don't find any sign(x) function in the math library (return the sign of the value). I've read that math module is a wrapper to C math lib and that C math lib has not sign(), so... Starting with Python 2.6 the math and cmath modules have a copysign function. I'm using 2.5.2 at that time, but copysign() is fine. with : s=copysign(1.0,x) it return the sign (-1.0, 0.0, +1.0) I've implement my own sign function of course (it's easy) but a standard one in math would be better and could be faster. Sure? :) I was... Are you aware that the IEEE 754 standard makes a difference between the floats +0.0 and -0.0? from math import atan2 def sign(x): if x 0 or (x == 0 and atan2(x, -1.) 0.): return 1 else: return -1 Thanks As my need is for a game and that i do not have IEEE real concern, i would simply using my simple function (but not as accurate) : def sign(x): if x==0.0: return 0.0 elif x0.0: return 1.0 else: return -1.0 -- Pierre-Alain Dorangehttp://microwar.sourceforge.net/ Ce message est sous licence Creative Commons by-nc-sa-2.0 http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
On Mon, 22 Dec 2008 12:31:44 +0100, Pierre-Alain Dorange wrote: I don't find any sign(x) function in the math library (return the sign of the value). I've read that math module is a wrapper to C math lib and that C math lib has not sign(), so... [snip] As my need is for a game and that i do not have IEEE real concern, i would simply using my simple function (but not as accurate) : def sign(x): if x==0.0: return 0.0 elif x0.0: return 1.0 else: return -1.0 I found this snippet to be quite succinct (even though being smart *might* be wrong in programming):: sign = lambda x:+(x 0) or -(x 0) HTH, -- Robert Stargaming Lehmann -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
On 2008-12-22, Pierre-Alain Dorange wrote: def sign(x): if x==0.0: return 0.0 elif x0.0: return 1.0 else: return -1.0 Isn't this approximately this? :: def sign(x): return float(cmp(x, 0)) Or if you don't want a float response:: def sign(x): return cmp(x, 0) -- Regards, Stephen Thorne Development Engineer NetBox Blue - 1300 737 060 -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
Stephen Thorne step...@thorne.id.au wrote: def sign(x): if x==0.0: return 0.0 elif x0.0: return 1.0 else: return -1.0 Isn't this approximately this? :: def sign(x): return float(cmp(x, 0)) Yes cmp() is probably the closest function to sign. I'm new to python and here i discover at least 4 methods, i just make a small script for timing those methods (100 000 times each on a set of 10 values). I do not use timeit, i can't make it work easyly as it need a standalone env for each test. the test script #!/usr/bin/env python from math import atan2 import time def sign_0(x): if x==0.0: return 0.0 elif x0.0: return 1.0 else: return -1.0 def sign_1(x): if x 0 or (x == 0 and atan2(x, -1.) 0.): return 1 else: return -1 def sign_2(x): return cmp(x, 0) sign_3 = lambda x:+(x 0) or -(x 0) def main(): candidates=[1.1,0.0,-0.0,-1.2,2.4,5.6,-8.2,74.1,-23.4,7945.481] startTime = time.clock() for i in range(10): for value in candidates: s=sign_0(value) print sign_0 : ,time.clock() - startTime startTime = time.clock() for i in range(10): for value in candidates: s=sign_1(value) print sign_1 : ,time.clock() - startTime startTime = time.clock() for i in range(10): for value in candidates: s=sign_2(value) print sign_2 : ,time.clock() - startTime startTime = time.clock() for i in range(10): for value in candidates: s=sign_3(value) print sign_3 : ,time.clock() - startTime if __name__ == '__main__' : main() the results - My config : iMac (2,66 GHz intel dual core 2 duo) MacOS X 10.5.5 Python 2.5.1 sign_0 = 0.4156 second (0%) sign_1 = 0.5316 second (+28%) sign_2 = 0.6515 second (+57%) sign_3 = 0.5244 second (+26%) conclusions --- 1/ python is fast 2/ method (0) is the fastest 3/ cmp method (2) is the slowest 4/ the precise one (IEEE 754) is also fast (1) -- Pierre-Alain Dorangehttp://microwar.sourceforge.net/ Ce message est sous licence Creative Commons by-nc-sa-2.0 http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
conclusions --- try testing on a large number of candidates that are all (or mostly) positive or all (or mostly) negative and you'll see performance numbers that are substantially different than the ones you report: candidates = range(1000) In general the function sign_1() is expected to be the fastest because in most cases will detect the sign with the fewest operations, it only visits the rest of the comparison when it hits the corner cases. Only if you have lots of +/-0.0 cases will it be slower than the rest, due to having to call an expensive operation. i. -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
Istvan Albert istvan.alb...@gmail.com wrote: try testing on a large number of candidates that are all (or mostly) positive or all (or mostly) negative and you'll see performance numbers that are substantially different than the ones you report: candidates = range(1000) In general the function sign_1() is expected to be the fastest because in most cases will detect the sign with the fewest operations, it only visits the rest of the comparison when it hits the corner cases. Only if you have lots of +/-0.0 cases will it be slower than the rest, due to having to call an expensive operation. You're right. On a range or a random list sign_1 is the fastest : with : candidates=[] for i in range(1000): candidates.append(1000.0*random.random()-500.0) In my first candidate list, the two ZERO (-0.0 and +0.0) make sign_1 less productive because it call atan2(). With random number sign_1 is faster, just a bit faster, except if the candidates contain some ZERO. I also make other test, with a range(1000), sign_1 became really faster : -41% (near twice faster than sign_0). I then rewrote a sign_0 version testing first positive, then negative and ZERO as the last test. I also made tests and return integer. It make it faster +20% but not as fast as sign_1 for a range. What is strange is that when testing with range list (0 1000) or (-500 +500), sign_1 is twice as fast as with a random generated list. The only thing a saw is that range generate an int list and random a float list... So it seems sign_1 is really fastest with integer, but not with float Range from -500 to +500 sign_0 : 0.38 sign_1 : 0.27 (-40%) Range from 0 to 1000 sign_0 : 0.32 sign_1 : 0.25 (-22%) Range from -1000 to 0 sign_0 : 0.46 sign_1 : 0.30 (-35%) 1000 Random from -500 to +500 sign_0 : 0.37 sign_1 : 0.42 (+13%) -- Pierre-Alain Dorangehttp://microwar.sourceforge.net/ Ce message est sous licence Creative Commons by-nc-sa-2.0 http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ -- http://mail.python.org/mailman/listinfo/python-list
Re: no sign() function ?
On Mon, 22 Dec 2008 14:51:32 +0100, Pierre-Alain Dorange wrote: I'm new to python and here i discover at least 4 methods, i just make a small script for timing those methods (100 000 times each on a set of 10 values). I do not use timeit, i can't make it work easyly as it need a standalone env for each test. But that's just what timeit does: it creates a standalone environment for each test. the test script #!/usr/bin/env python from math import atan2 import time def sign_0(x): if x==0.0: return 0.0 elif x0.0: return 1.0 else: return -1.0 def sign_1(x): if x 0 or (x == 0 and atan2(x, -1.) 0.): return 1 else: return -1 def sign_2(x): return cmp(x, 0) sign_3 = lambda x:+(x 0) or -(x 0) def main(): candidates=[1.1,0.0,-0.0,-1.2,2.4,5.6,-8.2,74.1,-23.4,7945.481] startTime = time.clock() time.clock() is low resolution on non-Windows systems. If you are using Windows, this is okay, if you are not, you are shooting yourself in the foot. for i in range(10): for value in candidates: Horribly inaccurate, because you are including the time to build a range of 100,000 integers. In Python 3, that will only be a little bit inaccurate, but in Python 2.x that will have a MAJOR effect -- possibly swamping the actual function you are calling. s=sign_0(value) print sign_0 : ,time.clock() - startTime You are (possibly) including the time taken to print to std out in your time. startTime = time.clock() for i in range(10): for value in candidates: s=sign_1(value) print sign_1 : ,time.clock() - startTime Repeated code is poor coding practice. Write a function that takes a function as argument, and call that: def timer(function, candidates, count=10): loop = [None]*count startTime = time.clock() for i in loop: for value in candidates: s = function(value) return time.clock() - startTime But this is just duplicating what timeit already does. Trust me, learn to use it, you won't be sorry. Here's a trick that took me a long time to learn: instead of copying your functions into the setup code of timeit, you can just import them. This is what I would do (untested): candidates=[1.1,0.0,-0.0,-1.2,2.4,5.6,-8.2,74.1,-23.4,7945.481] setup = from __main__ import sign_%d, candidates from timeit import Timer template = for x in candidates: s = sign_%d(x) for i in range(4): t = min( Timer(template % i, setup % i).repeat() ) print Testing sign_%d: % i, t, seconds conclusions --- None of your conclusions are safe until you have re-tested with a better timing method. That doesn't mean you are wrong, only that your reasons for believing them are weak. -- Steven -- http://mail.python.org/mailman/listinfo/python-list