Re: no sign() function ?

2008-12-24 Thread Pierre-Alain Dorange
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 ?

2008-12-24 Thread ajaksu
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 ?

2008-12-23 Thread Arnaud Delobelle
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 ?

2008-12-23 Thread Pierre-Alain Dorange
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 ?

2008-12-23 Thread Christian Heimes
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 ?

2008-12-23 Thread Mark Dickinson
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 ?

2008-12-23 Thread ajaksu
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 ?

2008-12-23 Thread Mark Dickinson
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 ?

2008-12-23 Thread ajaksu
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 ?

2008-12-23 Thread Steven D'Aprano
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 ?

2008-12-22 Thread Pierre-Alain Dorange
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 ?

2008-12-22 Thread Christian Heimes
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 ?

2008-12-22 Thread Pierre-Alain Dorange
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 ?

2008-12-22 Thread Robert Lehmann
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 ?

2008-12-22 Thread Stephen Thorne
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 ?

2008-12-22 Thread Pierre-Alain Dorange
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 ?

2008-12-22 Thread Istvan Albert

  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 ?

2008-12-22 Thread Pierre-Alain Dorange
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 ?

2008-12-22 Thread Steven D'Aprano
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