Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-21 Thread Edmondo Giovannozzi
Il giorno lunedì 20 marzo 2023 alle 19:10:26 UTC+1 Thomas Passin ha scritto:
> On 3/20/2023 11:21 AM, Edmondo Giovannozzi wrote: 
> > 
> >>> def sum1(): 
> >>> s = 0 
> >>> for i in range(100): 
> >>> s += i 
> >>> return s 
> >>> 
> >>> def sum2(): 
> >>> return sum(range(100)) 
> >> Here you already have the numbers you want to add. 
> > 
> > Actually using numpy you'll be much faster in this case: 
> > 
> > § import numpy as np 
> > § def sum3(): 
> > § return np.arange(1_000_000, dtype=np.int64).sum() 
> > 
> > On my computer sum1 takes 44 ms, while the numpy version just 2.6 ms 
> > One problem is that sum2 gives the wrong result. This is why I used 
> > np.arange with dtype=np.int64.
> On my computer they all give the same result. 
> 
> Python 3.10.9, PyQt version 6.4.1 
> Windows 10 AMD64 (build 10.0.19044) SP0 
> Processor: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz, 1690 Mhz, 4 
> Core(s), 8 Logical Processor(s)
> > sum2 evidently doesn't uses the python "big integers" e restrict the result 
> > to 32 bits.
> What about your system? Let's see if we can figure the reason for the 
> difference.

I'm using winpython on Windows 11 and the python version is, well, 3.11:

But it is my fault, sorry, I realised now that ipython is importing numpy 
namespace and the numpy sum function is overwriting the intrinsic sum.
The intrinsic sum is behaving correctly and is faster when used in 
sum(range(1_000_000)) then the numpy version.


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-20 Thread Thomas Passin

On 3/20/2023 11:21 AM, Edmondo Giovannozzi wrote:



def sum1():
 s = 0
 for i in range(100):
 s += i
 return s

def sum2():
 return sum(range(100))

Here you already have the numbers you want to add.


Actually using numpy you'll be much faster in this case:

§ import numpy as np
§ def sum3():
§return np.arange(1_000_000, dtype=np.int64).sum()

On my computer sum1 takes 44 ms, while the numpy version just 2.6 ms
One problem is that sum2 gives the wrong result. This is why I used np.arange 
with dtype=np.int64.


On my computer they all give the same result.

Python 3.10.9, PyQt version 6.4.1
Windows 10 AMD64 (build 10.0.19044) SP0
Processor: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz, 1690 Mhz, 4 
Core(s), 8 Logical Processor(s)




sum2 evidently doesn't uses the python "big integers" e restrict the result to 
32 bits.


What about your system?  Let's see if we can figure the reason for the 
difference.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-20 Thread MRAB

On 2023-03-20 15:21, Edmondo Giovannozzi wrote:


> def sum1(): 
> s = 0 
> for i in range(100): 
> s += i 
> return s 
> 
> def sum2(): 
> return sum(range(100))
Here you already have the numbers you want to add. 


Actually using numpy you'll be much faster in this case:

§ import numpy as np
§ def sum3():
§return np.arange(1_000_000, dtype=np.int64).sum()

On my computer sum1 takes 44 ms, while the numpy version just 2.6 ms
One problem is that sum2 gives the wrong result. This is why I used np.arange 
with dtype=np.int64.

sum2 evidently doesn't uses the python "big integers" e restrict the result to 
32 bits.


On my computer they all give the same result, as I'd expect.
--
https://mail.python.org/mailman/listinfo/python-list


Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-20 Thread Edmondo Giovannozzi

> > def sum1(): 
> > s = 0 
> > for i in range(100): 
> > s += i 
> > return s 
> > 
> > def sum2(): 
> > return sum(range(100))
> Here you already have the numbers you want to add. 

Actually using numpy you'll be much faster in this case:

§ import numpy as np
§ def sum3():
§return np.arange(1_000_000, dtype=np.int64).sum()

On my computer sum1 takes 44 ms, while the numpy version just 2.6 ms
One problem is that sum2 gives the wrong result. This is why I used np.arange 
with dtype=np.int64.

sum2 evidently doesn't uses the python "big integers" e restrict the result to 
32 bits.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-18 Thread Peter J. Holzer
On 2023-03-15 17:09:52 +, Weatherby,Gerard wrote:
> Sum is faster than iteration in the general case.

I'd say this is the special case, not the general case.

> def sum1():
> s = 0
> for i in range(100):
> s += i
> return s
> 
> def sum2():
> return sum(range(100))

Here you already have the numbers you want to add.

The OP needed to compute those numbers first.

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-16 Thread Roel Schroeven

Op 14/03/2023 om 8:48 schreef Alexander Nestorov:

I have the following code:

 ...
 for i in range(151): # 150 iterations
     ...
Nothing to do with your actual question and it's probably just a small 
oversight, but still I thought it was worth a mention: that comment does 
not accurately describe the code; the code is actually doing 151 
iterations, numbered 0 up to and including 150.


--
"I've come up with a set of rules that describe our reactions to technologies:
1. Anything that is in the world when you’re born is normal and ordinary and is
   just a natural part of the way the world works.
2. Anything that's invented between when you’re fifteen and thirty-five is new
   and exciting and revolutionary and you can probably get a career in it.
3. Anything invented after you're thirty-five is against the natural order of 
things."
-- Douglas Adams, The Salmon of Doubt

--
https://mail.python.org/mailman/listinfo/python-list


Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-15 Thread Weatherby,Gerard
Moving the generator out:

import timeit

thedata = [i for i in range(1_000_000)]
def sum1():
s = 0
for i in thedata:
s += i
return s

def sum2():
return sum(thedata)

print('For Loop Sum:', timeit.timeit(sum1, number=100))
print( 'Built-in Sum:', timeit.timeit(sum2, number=100))

---
For Loop Sum: 6.984986504539847
Built-in Sum: 0.5175364706665277

From: Weatherby,Gerard 
Date: Wednesday, March 15, 2023 at 1:09 PM
To: python-list@python.org 
Subject: Re: Debugging reason for python running unreasonably slow when adding 
numbers
Sum is faster than iteration in the general case.

Lifting a test program from Stack Overflow 
https://stackoverflow.com/questions/24578896/python-built-in-sum-function-vs-for-loop-performance,


import timeit

def sum1():
s = 0
for i in range(100):
s += i
return s

def sum2():
return sum(range(100))

print('For Loop Sum:', timeit.timeit(sum1, number=100))
print( 'Built-in Sum:', timeit.timeit(sum2, number=100))

---

For Loop Sum: 7.726335353218019
Built-in Sum: 1.0398506000638008

---


From: Python-list  on 
behalf of David Raymond 
Date: Wednesday, March 15, 2023 at 11:46 AM
To: python-list@python.org 
Subject: RE: Debugging reason for python running unreasonably slow when adding 
numbers
*** Attention: This is an external email. Use caution responding, opening 
attachments or clicking on links. ***

> Then I'm very confused as to how things are being done, so I will shut
> up. There's not enough information here to give performance advice
> without actually being a subject-matter expert already.

Short version: In this specific case "weights" is a 5,147 element list of 
floats, and "input" is a 10 element list of integers which has the indexes of 
the 10 elements in weights that he wants to add up.

sum_ = 0
for key in input:
sum_ += weights[key]

vs

sum_ = sum(weights[key] for key in input)

vs... other ways
--
https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!ikhJJxqJnllDHh6JKaMX8g2K-Ceq6ZiRDJxX7AbS-1AiBIrdAmA2qjBtYZbxel2mktyno1s9iJGo_zAl5alBIWxoVXE$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!ikhJJxqJnllDHh6JKaMX8g2K-Ceq6ZiRDJxX7AbS-1AiBIrdAmA2qjBtYZbxel2mktyno1s9iJGo_zAl5alBIWxoVXE$>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-15 Thread Weatherby,Gerard
Sum is faster than iteration in the general case.

Lifting a test program from Stack Overflow 
https://stackoverflow.com/questions/24578896/python-built-in-sum-function-vs-for-loop-performance,

import timeit

def sum1():
s = 0
for i in range(100):
s += i
return s

def sum2():
return sum(range(100))

print('For Loop Sum:', timeit.timeit(sum1, number=100))
print( 'Built-in Sum:', timeit.timeit(sum2, number=100))

---

For Loop Sum: 7.726335353218019
Built-in Sum: 1.0398506000638008

---

From: Python-list  on 
behalf of David Raymond 
Date: Wednesday, March 15, 2023 at 11:46 AM
To: python-list@python.org 
Subject: RE: Debugging reason for python running unreasonably slow when adding 
numbers
*** Attention: This is an external email. Use caution responding, opening 
attachments or clicking on links. ***

> Then I'm very confused as to how things are being done, so I will shut
> up. There's not enough information here to give performance advice
> without actually being a subject-matter expert already.

Short version: In this specific case "weights" is a 5,147 element list of 
floats, and "input" is a 10 element list of integers which has the indexes of 
the 10 elements in weights that he wants to add up.

sum_ = 0
for key in input:
sum_ += weights[key]

vs

sum_ = sum(weights[key] for key in input)

vs... other ways
--
https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!ikhJJxqJnllDHh6JKaMX8g2K-Ceq6ZiRDJxX7AbS-1AiBIrdAmA2qjBtYZbxel2mktyno1s9iJGo_zAl5alBIWxoVXE$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!ikhJJxqJnllDHh6JKaMX8g2K-Ceq6ZiRDJxX7AbS-1AiBIrdAmA2qjBtYZbxel2mktyno1s9iJGo_zAl5alBIWxoVXE$>
-- 
https://mail.python.org/mailman/listinfo/python-list


RE: Debugging reason for python running unreasonably slow when adding numbers

2023-03-15 Thread David Raymond
> Then I'm very confused as to how things are being done, so I will shut
> up. There's not enough information here to give performance advice
> without actually being a subject-matter expert already.

Short version: In this specific case "weights" is a 5,147 element list of 
floats, and "input" is a 10 element list of integers which has the indexes of 
the 10 elements in weights that he wants to add up.

sum_ = 0
for key in input:
sum_ += weights[key]

vs

sum_ = sum(weights[key] for key in input)

vs... other ways
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-15 Thread Chris Angelico
On Thu, 16 Mar 2023 at 02:14, Thomas Passin  wrote:
>
> On 3/15/2023 11:01 AM, Chris Angelico wrote:
> > On Thu, 16 Mar 2023 at 01:26, David Raymond  
> > wrote:
> >> I'm not quite sure why the built-in sum functions are slower than the for 
> >> loop,
> >> or why they're slower with the generator expression than with the list 
> >> comprehension.
> >
> > For small-to-medium data sizes, genexps are slower than list comps,
> > but use less memory. (At some point, using less memory translates
> > directly into faster runtime.) But even the sum-with-genexp version is
> > notably faster than reduce.
> >
> > Is 'weights' a dictionary? You're iterating over it, then subscripting
> > every time. If it is, try simply taking the sum of weights.values(),
> > as this should be significantly faster.
>
> It's a list.
>

Then I'm very confused as to how things are being done, so I will shut
up. There's not enough information here to give performance advice
without actually being a subject-matter expert already.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-15 Thread Thomas Passin

On 3/15/2023 11:01 AM, Chris Angelico wrote:

On Thu, 16 Mar 2023 at 01:26, David Raymond  wrote:

I'm not quite sure why the built-in sum functions are slower than the for loop,
or why they're slower with the generator expression than with the list 
comprehension.


For small-to-medium data sizes, genexps are slower than list comps,
but use less memory. (At some point, using less memory translates
directly into faster runtime.) But even the sum-with-genexp version is
notably faster than reduce.

Is 'weights' a dictionary? You're iterating over it, then subscripting
every time. If it is, try simply taking the sum of weights.values(),
as this should be significantly faster.


It's a list.

--
https://mail.python.org/mailman/listinfo/python-list


Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-15 Thread Thomas Passin

On 3/15/2023 10:24 AM, David Raymond wrote:

Or use the sum() builtin rather than reduce(), which was
*deliberately* removed from the builtins. The fact that you can get
sum() without importing, but have to go and reach for functools to get
reduce(), is a hint that you probably shouldn't use reduce when sum
will work.


Out of curiosity I tried a couple variations and am a little confused by the 
results. Maybe I'm having a brain fart and am missing something obvious?

Each of these was run with the same "data" and "perceptrons" values to keep 
that fair.
Times are averages over 150 iterations like the original.
The only thing changed in the trainPerceptron function was how to calculate sum_


Original:
sum_ = 0
for key in input:
 v = weights[key]
 sum_ += v
418ms

The reduce version:
sum_ = reduce(lambda acc, key: acc + weights[key], input)
758ms

Getting rid of the assignment to v in the original version:
sum_ = 0
for key in input:
 sum_ += weights[key]
380ms

But then using sum seems to be slower

sum with generator expression:
sum_ = sum(weights[key] for key in input)
638ms

sum with list comprehension:
sum_ = sum([weights[key] for key in input])
496ms

math.fsum with generator expression:
sum_ = math.fsum(weights[key] for key in input)
618ms

math.fsum with list comprehension:
sum_ = math.fsum([weights[key] for key in input])
480ms


I'm not quite sure why the built-in sum functions are slower than the for loop,
or why they're slower with the generator expression than with the list 
comprehension.


I tried similar variations yesterday and got similar results.  All the 
sum() versions I tried were slower.  Like you, I got the smallest times for


> for key in input:
>  sum_ += weights[key]

but I didn't get as much of a difference as you did.

I surmise that in using the sum() variations, that the entire sequence 
was constructed first, and then iterated over.  In the non-sum() 
versions, no new sequence had to be constructed first, so it would make 
sense for the latter to be slower.

--
https://mail.python.org/mailman/listinfo/python-list


Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-15 Thread Chris Angelico
On Thu, 16 Mar 2023 at 01:26, David Raymond  wrote:
> I'm not quite sure why the built-in sum functions are slower than the for 
> loop,
> or why they're slower with the generator expression than with the list 
> comprehension.

For small-to-medium data sizes, genexps are slower than list comps,
but use less memory. (At some point, using less memory translates
directly into faster runtime.) But even the sum-with-genexp version is
notably faster than reduce.

Is 'weights' a dictionary? You're iterating over it, then subscripting
every time. If it is, try simply taking the sum of weights.values(),
as this should be significantly faster.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


RE: Debugging reason for python running unreasonably slow when adding numbers

2023-03-15 Thread David Raymond
> Or use the sum() builtin rather than reduce(), which was
> *deliberately* removed from the builtins. The fact that you can get
> sum() without importing, but have to go and reach for functools to get
> reduce(), is a hint that you probably shouldn't use reduce when sum
> will work.

Out of curiosity I tried a couple variations and am a little confused by the 
results. Maybe I'm having a brain fart and am missing something obvious?

Each of these was run with the same "data" and "perceptrons" values to keep 
that fair.
Times are averages over 150 iterations like the original.
The only thing changed in the trainPerceptron function was how to calculate sum_


Original:
sum_ = 0
for key in input:
v = weights[key]
sum_ += v
418ms

The reduce version:
sum_ = reduce(lambda acc, key: acc + weights[key], input)
758ms

Getting rid of the assignment to v in the original version:
sum_ = 0
for key in input:
sum_ += weights[key]
380ms

But then using sum seems to be slower

sum with generator expression:
sum_ = sum(weights[key] for key in input)
638ms

sum with list comprehension:
sum_ = sum([weights[key] for key in input])
496ms

math.fsum with generator expression:
sum_ = math.fsum(weights[key] for key in input)
618ms

math.fsum with list comprehension:
sum_ = math.fsum([weights[key] for key in input])
480ms


I'm not quite sure why the built-in sum functions are slower than the for loop,
or why they're slower with the generator expression than with the list 
comprehension.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-14 Thread Oscar Benjamin
On Tue, 14 Mar 2023 at 16:27, Alexander Nestorov  wrote:
>
> I'm working on an NLP and I got bitten by an unreasonably slow behaviour in 
> Python while operating with small amounts of numbers.
>
> I have the following code:
>
> ```python
> import random, time
> from functools import reduce
>
> def trainPerceptron(perceptron, data):
>   learningRate = 0.002
>   weights = perceptron['weights']
>   error = 0
>   for chunk in data:
>   input = chunk['input']
>   output = chunk['output']
>
>   # 12x slower than equivalent JS
>   sum_ = 0
>   for key in input:
>   v = weights[key]
>   sum_ += v

In Python something like your task here would usually use something
along the lines of NumPy. Your two innermost loops involve adding up a
subset of numbers from a list chosen using a list of indices. This is
something that numpy can do much more efficiently with its fancy
indexing e.g.:

In [3]: a = np.array([1, 2, 3, 4, 5, 6, 7])

In [4]: b = np.array([0, 3, 5])

In [5]: a[b]
Out[5]: array([1, 4, 6])

In [6]: a[b].sum()
Out[6]: 11

This a[b].sum() operation in your code would be weights[input].sum()
and would be much faster than the loop shown (the speed difference
will be larger if you increase the size of the input array).

--
Oscar
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-14 Thread Chris Angelico
On Wed, 15 Mar 2023 at 08:53, Peter J. Holzer  wrote:
>
> On 2023-03-14 16:48:24 +0900, Alexander Nestorov wrote:
> > I'm working on an NLP and I got bitten by an unreasonably slow
> > behaviour in Python while operating with small amounts of numbers.
> >
> > I have the following code:
> [...]
> >   # 12x slower than equivalent JS
> >   sum_ = 0
> >   for key in input:
> >   v = weights[key]
> >   sum_ += v
> >
> >   # 20x slower than equivalent JS
> >   #sum_ = reduce(lambda acc, key: acc + weights[key], input)
>
> Not surprising. Modern JavaScript implementations have a JIT compiler.
> CPython doesn't.
>
> You may want to try PyPy if your code uses tight loops like that.
>
> Or alternatively it may be possible to use numpy to do these operations.
>

Or use the sum() builtin rather than reduce(), which was
*deliberately* removed from the builtins. The fact that you can get
sum() without importing, but have to go and reach for functools to get
reduce(), is a hint that you probably shouldn't use reduce when sum
will work.

Naive code is almost always going to be slower than smart code, and
comparing "equivalent" code across languages is almost always an
unfair comparison to one of them.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-14 Thread Peter J. Holzer
On 2023-03-14 16:48:24 +0900, Alexander Nestorov wrote:
> I'm working on an NLP and I got bitten by an unreasonably slow
> behaviour in Python while operating with small amounts of numbers.
> 
> I have the following code:
[...]
>       # 12x slower than equivalent JS
>       sum_ = 0
>       for key in input:
>           v = weights[key]
>           sum_ += v
> 
>       # 20x slower than equivalent JS
>       #sum_ = reduce(lambda acc, key: acc + weights[key], input)

Not surprising. Modern JavaScript implementations have a JIT compiler.
CPython doesn't.

You may want to try PyPy if your code uses tight loops like that.

Or alternatively it may be possible to use numpy to do these operations.

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Debugging reason for python running unreasonably slow when adding numbers

2023-03-14 Thread Thomas Passin

On 3/14/2023 3:48 AM, Alexander Nestorov wrote:

I'm working on an NLP and I got bitten by an unreasonably slow behaviour in 
Python while operating with small amounts of numbers.

I have the following code:

```python
import random, time
from functools import reduce

def trainPerceptron(perceptron, data):
   learningRate = 0.002
   weights = perceptron['weights']
   error = 0
   for chunk in data:
       input = chunk['input']
       output = chunk['output']

       # 12x slower than equivalent JS
       sum_ = 0
       for key in input:
           v = weights[key]
           sum_ += v

       # 20x slower than equivalent JS
       #sum_ = reduce(lambda acc, key: acc + weights[key], input)

       actualOutput = sum_ if sum_ > 0 else 0

       expectedOutput = 1 if output == perceptron['id'] else 0
       currentError = expectedOutput - actualOutput
       if currentError:
           error += currentError ** 2
           change = currentError * learningRate
           for key in input:
               weights[key] += change


[snip]
Just a speculation, but the difference with the javascript behavior 
might be because the JS JIT compiler kicked in for these loops.


--
https://mail.python.org/mailman/listinfo/python-list


Debugging reason for python running unreasonably slow when adding numbers

2023-03-14 Thread Alexander Nestorov
I'm working on an NLP and I got bitten by an unreasonably slow behaviour in 
Python while operating with small amounts of numbers.

I have the following code:

```python
import random, time
from functools import reduce

def trainPerceptron(perceptron, data):
  learningRate = 0.002
  weights = perceptron['weights']
  error = 0
  for chunk in data:
      input = chunk['input']
      output = chunk['output']

      # 12x slower than equivalent JS
      sum_ = 0
      for key in input:
          v = weights[key]
          sum_ += v

      # 20x slower than equivalent JS
      #sum_ = reduce(lambda acc, key: acc + weights[key], input)

      actualOutput = sum_ if sum_ > 0 else 0

      expectedOutput = 1 if output == perceptron['id'] else 0
      currentError = expectedOutput - actualOutput
      if currentError:
          error += currentError ** 2
          change = currentError * learningRate
          for key in input:
              weights[key] += change

  return error

# Build mock data structure
data = [{
   'input': random.sample(range(0, 5146), 10),
   'output': 0
} for _ in range(11514)]
perceptrons = [{
   'id': i,
   'weights': [0.0] * 5147,
} for i in range(60)] # simulate 60 perceptrons

# Simulate NLU
for i in range(151): # 150 iterations
  hrstart = time.perf_counter()
  for perceptron in perceptrons:
    trainPerceptron(perceptron, data)
  hrend = time.perf_counter()
  print(f'Epoch {i} - Time for training: {int((hrend - hrstart) * 1000)}ms')
```

Running it on my M1 MBP I get the following numbers.

```
Epoch 0 - Time for training: 199ms
Epoch 1 - Time for training: 198ms
Epoch 2 - Time for training: 199ms
Epoch 3 - Time for training: 197ms
Epoch 4 - Time for training: 199ms
...
Epoch 146 - Time for training: 198ms
Epoch 147 - Time for training: 200ms
Epoch 148 - Time for training: 198ms
Epoch 149 - Time for training: 198ms
Epoch 150 - Time for training: 198ms
```

Each epoch is taking around 200ms, which is unreasonably slow given the small 
amount of numbers that are being processed. I profiled the code with `cProfile` 
in order to find out what is going on:

```
         655306 function calls (655274 primitive calls) in 59.972 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      3/1    0.000    0.000   59.972   59.972 {built-in method builtins.exec}
        1    0.005    0.005   59.972   59.972 poc-small.py:1()
     9060   59.850    0.007   59.850    0.007 poc-small.py:4(trainPerceptron)
        1    0.006    0.006    0.112    0.112 poc-small.py:34()
    11514    0.039    0.000    0.106    0.000 random.py:382(sample)
   115232    0.034    0.000    0.047    0.000 
random.py:235(_randbelow_with_getrandbits)
    11548    0.002    0.000    0.012    0.000 {built-in method 
builtins.isinstance}
    11514    0.002    0.000    0.010    0.000 :117(__instancecheck__)
   183616    0.010    0.000    0.010    0.000 {method 'getrandbits' of 
'_random.Random' objects}
    11514    0.002    0.000    0.008    0.000 {built-in method 
_abc._abc_instancecheck}
    11514    0.002    0.000    0.006    0.000 :121(__subclasscheck__)
   115140    0.005    0.000    0.005    0.000 {method 'add' of 'set' objects}
    11514    0.003    0.000    0.004    0.000 {built-in method 
_abc._abc_subclasscheck}
   115232    0.004    0.000    0.004    0.000 {method 'bit_length' of 'int' 
objects}
      151    0.003    0.000    0.003    0.000 {built-in method builtins.print}
```

This wasn't too helpful, so I tried with [line_profiler][1]:

```
Timer unit: 1e-06 s

Total time: 55.2079 s
File: poc-small.py
Function: trainPerceptron at line 4

Line #      Hits         Time  Per Hit   % Time  Line Contents
==
     4                                           @profile
     5                                           def 
trainPerceptron(perceptron, data):
     6      1214        301.0      0.2      0.0    learningRate = 0.002
     7      1214        255.0      0.2      0.0    weights = 
perceptron['weights']
     8      1214        114.0      0.1      0.0    error = 0
     9  13973840    1742427.0      0.1      3.2    for chunk in data:
    10  13973840    1655043.0      0.1      3.0        input = chunk['input']
    11  13973840    1487543.0      0.1      2.7        output = chunk['output']
    12
    13                                                 # 12x slower than 
equivalent JS
    14  13973840    1210755.0      0.1      2.2        sum_ = 0
    15 139738397   13821056.0      0.1     25.0        for key in input:
    16 139738397   13794656.0      0.1     25.0            v = weights[key]
    17 139738396   14942692.0      0.1     27.1            sum_ += v
    18
    19                                                 # 20x slower than 
equivalent JS
    20                                                 #sum_ = reduce(lambda 
acc, key: acc + weights[key], input)
    21
    22  13973839    161827

Re: Are Floating Point Numbers still a Can of Worms?

2022-10-24 Thread Dennis Lee Bieber
On Mon, 24 Oct 2022 14:52:28 +, "Schachner, Joseph (US)"
 declaimed the following:

>Floating point will always be a can of worms, as long as people expect it to 
>represent real numbers with more precision that float has.  Usually this is 
>not an issue, but sometimes it is.  And, although this example does not 
>exhibit subtractive cancellation, that is the surest way to have less 
>precision that the two values you subtracted.  And if you try to add up lots 
>of values, if your sum grows large enough, tiny values will not change it 
>anymore, even if there are many of them  - there are simple algorithms to 
>avoid this effect.  But all of this is because float has limited precision.
>

Might I suggest this to those affected...
https://www.amazon.com/Real-Computing-Made-Engineering-Calculations/dp/0486442217/ref=tmm_pap_swatch_0?_encoding=UTF8=134371=8-1

(Wow -- they want a fortune for the original hard-cover, which I own)


-- 
Wulfraed Dennis Lee Bieber AF6VN
wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/
-- 
https://mail.python.org/mailman/listinfo/python-list


RE: Are Floating Point Numbers still a Can of Worms?

2022-10-24 Thread Schachner, Joseph (US)
Floating point will always be a can of worms, as long as people expect it to 
represent real numbers with more precision that float has.  Usually this is not 
an issue, but sometimes it is.  And, although this example does not exhibit 
subtractive cancellation, that is the surest way to have less precision that 
the two values you subtracted.  And if you try to add up lots of values, if 
your sum grows large enough, tiny values will not change it anymore, even if 
there are many of them  - there are simple algorithms to avoid this effect.  
But all of this is because float has limited precision.

--- Joseph S.


Teledyne Confidential; Commercially Sensitive Business Data

-Original Message-
From: Pieter van Oostrum  
Sent: Sunday, October 23, 2022 10:25 AM
To: python-list@python.org
Subject: Re: Are Floating Point Numbers still a Can of Worms?

Mostowski Collapse  writes:

> I also get:
>
> Python 3.11.0rc1 (main, Aug 8 2022, 11:30:54)
>>>> 2.718281828459045**0.8618974796837966
> 2.367649
>
> Nice try, but isn't this one the more correct?
>
> ?- X is 2.718281828459045**0.8618974796837966.
> X = 2.36764897.
>

That's probably the accuracy of the underlying C implementation of the exp 
function.

In [25]: exp(0.8618974796837966)
Out[25]: 2.367649

But even your answer can be improved:

Maxima:

(%i1) fpprec:30$

(%i2) bfloat(2.718281828459045b0)^bfloat(.8618974796837966b0);
(%o2)  2.367648983187397393143b0

but:

(%i7) bfloat(%e)^bfloat(.8618974796837966b0);
(%o7)  2.36764900085638369695b0
surprisingly closer to Python's answer.

but 2.718281828459045 isn't e. Close but no cigar.

(%i10) bfloat(2.718281828459045b0) - bfloat(%e);
(%o10)   - 2.35360287471352802147785151603b-16

Fricas:

(1) -> 2.718281828459045^0.8618974796837966 

   (1)  2.367648_98319

(2) -> exp(0.8618974796837966)

   (2)  2.367649_00086

-- 
Pieter van Oostrum 
www: http://pieter.vanoostrum.org/
PGP key: [8DAE142BE17999C4]
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are Floating Point Numbers still a Can of Worms?

2022-10-23 Thread Pieter van Oostrum
Mostowski Collapse  writes:

> I also get:
>
> Python 3.11.0rc1 (main, Aug 8 2022, 11:30:54)
 2.718281828459045**0.8618974796837966
> 2.367649
>
> Nice try, but isn't this one the more correct?
>
> ?- X is 2.718281828459045**0.8618974796837966.
> X = 2.36764897.
>

That's probably the accuracy of the underlying C implementation of the exp 
function.

In [25]: exp(0.8618974796837966)
Out[25]: 2.367649

But even your answer can be improved:

Maxima:

(%i1) fpprec:30$

(%i2) bfloat(2.718281828459045b0)^bfloat(.8618974796837966b0);
(%o2)  2.367648983187397393143b0

but:

(%i7) bfloat(%e)^bfloat(.8618974796837966b0);
(%o7)  2.36764900085638369695b0
surprisingly closer to Python's answer.

but 2.718281828459045 isn't e. Close but no cigar.

(%i10) bfloat(2.718281828459045b0) - bfloat(%e);
(%o10)   - 2.35360287471352802147785151603b-16

Fricas:

(1) -> 2.718281828459045^0.8618974796837966 

   (1)  2.367648_98319

(2) -> exp(0.8618974796837966)

   (2)  2.367649_00086

-- 
Pieter van Oostrum 
www: http://pieter.vanoostrum.org/
PGP key: [8DAE142BE17999C4]
-- 
https://mail.python.org/mailman/listinfo/python-list


[Python-announce] rounder: A Python package for rounding numbers in complex objects

2022-08-30 Thread Marcin Kozak
Hi all!

When you work with numbers and need to print them, more often than not you
want to round them. You can use the built-in round() function:
>>> round(1.123, 2)
1.12
>>> x = [1.123, 44.32, 12.11234]
>>> [round(x_i, 2) for x_i in x]
[ 1.12, 44.32, 12.11]

However, when you want to round numbers in a more complex Python object,
you need to be careful; you may also need to write a dedicated function to
round numbers in this object, and you may need to update it if the object's
structure changes.

Now, you do not need to do that: use the rounder Python package instead. It
will round numbers in any non-nested or nested Python object, using the
following functions:
* round_object(obj, digits), which rounds numbers in the object to a
provided number of decimal digits
* ceil_object(obj), which rounds numbers up to the nearest integer
* floor_object(obj), which rounds numbers down to the nearest integer
* signif_object(obj, digits), which rounds numbers to a number of
significant digits

So, for example:

>>> obj = {'float': 1.345442, 'list': [1.1222, 1.1226, "string"], 'set':
{1.1222, 1.1226}, 'tuple': (1.1222, 1.1226)}
>>> round_object(obj, 2)
{'float': 1.35, 'list': [1.12, 1.12, "string"], 'set': {1.12}, 'tuple':
(1.12, 1.12)}
>>> signif_object(obj, 3)
{'float': 1.35, 'list': [1.12, 1.12, "string"], 'set': {1.12}, 'tuple':
(1.12, 1.12)}

The package offers also two other functions:
* signif(x, digits), to round a number to significant digits
* map_object(map_function, obj, use_copy=False)

The latter function is a generalized function that applies callable
map_function to all numbers in obj. Consider this simplistic example:
>>> map_object(lambda x: x**2, {'a': 3, 'b': [1, 2, 3]})
{'a': 9, 'b': [1, 4, 9]}

The package works with objects of many different types, not only those
shown above. It works under both Windows and Linux. You can install it from
PyPi:
$ pip install rounder

You will learn more about it from its GitHub repo:
https://github.com/nyggus/rounder.

Happy rounding!

Pozdrawiam,
Marcin
___
Python-announce-list mailing list -- python-announce-list@python.org
To unsubscribe send an email to python-announce-list-le...@python.org
https://mail.python.org/mailman3/lists/python-announce-list.python.org/
Member address: arch...@mail-archive.com


Re: Convert the decimal numbers expressed in a `numpy.ndarray` into a matrix representing elements in fractional form

2022-05-23 Thread Cousin Stanley



> hongy... wrote 
>
> This method doesn't work, as shown below:
>
? b 
>
>  [0.0, -1.0, 0.0, 0.25]
>  [1.0, 0.0, 0.0, 0.25]
>  [0.0, 0.0, 1.0, 0.25]
>  [0.0, 0.0, 0.0, 1.0]
>
> a 
>
> 0  0  0  1
>

# ---

Using 

  debian 11.3 bullseye
  python 3.9
  numpy  1,21,5

  Code as I posted in my reply dated 2022-05-18


$ python3 np_array_to_fractions_2.py

  b 

 [0.0, -1.0, 0.0, 0.25]
 [1.0, 0.0, 0.0, 0.25]
 [0.0, 0.0, 1.0, 0.25]
 [0.0, 0.0, 0.0, 1.0]

  a 

0 -1 0 1/4
1 0 0 1/4
0 0 1 1/4
0 0 0 1


--
Stanley C. Kitching
Human Being
Phoenix, Arizona
--
https://mail.python.org/mailman/listinfo/python-list


Re: Convert the decimal numbers expressed in a `numpy.ndarray` into a matrix representing elements in fractional form

2022-05-22 Thread hongy...@gmail.com
On Thursday, May 19, 2022 at 5:26:25 AM UTC+8, Cousin Stanley wrote:
> #!/usr/bin/env python3 
> 
> ''' 
> NewsGroup  comp.lang.python 
> 
> Subject .. Convert the decimal numbers
> expressed in a numpy.ndarray 
> into a matrix representing elements 
> in fractiona
> Date . 2022-05-16 
> 
> Post_By .. hongy... 
> 
> Edit_By .. Stanley C. Kitching 
> '''
> import numpy as np 
> 
> from fractions import Fraction
> b = [ 
> [ 0.0 , -1.0 , 0.0 , 0.25 ] , 
> [ 1.0 , 0.0 , 0.0 , 0.25 ] , 
> [ 0.0 , 0.0 , 1.0 , 0.25 ] , 
> [ 0.0 , 0.0 , 0.0 , 1.0 ] ] 
> 
> a = [ ] 
> 
> print( '\n b  \n' ) 
> 
> for row in b : 
> arow = [] 
> print( ' ' , row ) 
> 
> for dec_x in row : 
> frac_x = Fraction( dec_x ) 
> arow.append( frac_x ) 
> 
> a.append( arow ) 
> 
> 
> # using f-string format 
> 
> print( '\n a  \n' ) 
> 
> for row in a : 
> 
> for item in row : 
> 
> print( f' {item} ' , end = '' ) 
> 
> print() 
> 
> # -- 

This method doesn't work, as shown below:


 b  

  [0.0, -1.0, 0.0, 0.25]
  [1.0, 0.0, 0.0, 0.25]
  [0.0, 0.0, 1.0, 0.25]
  [0.0, 0.0, 0.0, 1.0]

 a  

 0  0  0  1 


 
> -- 
> Stanley C. Kitching 
> Human Being 
> Phoenix, Arizona
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Convert the decimal numbers expressed in a `numpy.ndarray` into a matrix representing elements in fractional form

2022-05-18 Thread Cousin Stanley

#!/usr/bin/env python3

'''
NewsGroup  comp.lang.python

Subject .. Convert the decimal numbers
   expressed in a numpy.ndarray
   into a matrix representing elements
   in fractiona

Date . 2022-05-16

Post_By .. hongy...

Edit_By .. Stanley C. Kitching
'''

import numpy as np

from fractions import Fraction

b = [
  [ 0.0 , -1.0 , 0.0 , 0.25 ] ,
  [ 1.0 ,  0.0 , 0.0 , 0.25 ] ,
  [ 0.0 ,  0.0 , 1.0 , 0.25 ] ,
  [ 0.0 ,  0.0 , 0.0 , 1.0  ] ]

a = [ ]

print( '\n  b  \n' )

for row in b :
arow = []
print( '' , row )

for dec_x in row :
frac_x = Fraction( dec_x )
arow.append( frac_x )

a.append( arow )


# using f-string format

print( '\n  a  \n' )

for row in a :

for item in row :

print( f'{item} ' , end = '' )

print()

# --

--
Stanley C. Kitching
Human Being
Phoenix, Arizona
--
https://mail.python.org/mailman/listinfo/python-list


Re: Convert the decimal numbers expressed in a `numpy.ndarray` into a matrix representing elements in fractional form

2022-05-18 Thread Dennis Lee Bieber
On Tue, 17 May 2022 17:20:54 +0100, MRAB 
declaimed the following:

>As it's just a simple replacement, I would've thought that the 'obvious' 
>solution would be:
> a = a.replace("'", "")

Mea culpa...

Guess it's time for me to review the library reference for basic data
types again. I'm so used to the .join(.split()) (usually for other purposes
-- like a quick TSV/CSV formatting without importing the csv module).
The only firm item is that I do not look at any regular expression module
if I can come up with something using native data type methods -- and using
the overhead of re with just simple text [ie; nothing that might be called
an "expression" designed to match /varying/ content) seems really
inefficient.


-- 
Wulfraed Dennis Lee Bieber AF6VN
wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Convert the decimal numbers expressed in a `numpy.ndarray` into a matrix representing elements in fractional form

2022-05-17 Thread MRAB

On 2022-05-17 16:21, Peter J. Holzer wrote:

On 2022-05-16 20:48:02 -0400, Dennis Lee Bieber wrote:

On Mon, 16 May 2022 17:22:17 -0700 (PDT), "hongy...@gmail.com"
 declaimed the following:
>a=re.sub(r"'","",a)

Explain what you believe this operation is doing, show us the input and
the output.

The best I can make out of that is that it is looking for single quote
characters within whatever "a" is, and replacing them with nothing.
Something much more understandable, without invoking a regular expression
library (especially when neither the search nor the replacement terms are
regular expressions) with simple string operations...

stripped = "".join(quoted.split("'"))


Whether that's easier to understand it very much in the eye of the
beholder.

As it's just a simple replacement, I would've thought that the 'obvious' 
solution would be:

a = a.replace("'", "")
--
https://mail.python.org/mailman/listinfo/python-list


Re: Convert the decimal numbers expressed in a `numpy.ndarray` into a matrix representing elements in fractional form

2022-05-17 Thread Peter J. Holzer
On 2022-05-16 20:48:02 -0400, Dennis Lee Bieber wrote:
> On Mon, 16 May 2022 17:22:17 -0700 (PDT), "hongy...@gmail.com"
>  declaimed the following:
> >a=re.sub(r"'","",a)
> 
>   Explain what you believe this operation is doing, show us the input and
> the output.
> 
>   The best I can make out of that is that it is looking for single quote
> characters within whatever "a" is, and replacing them with nothing.
> Something much more understandable, without invoking a regular expression
> library (especially when neither the search nor the replacement terms are
> regular expressions) with simple string operations...
> 
>   stripped = "".join(quoted.split("'"))

Whether that's easier to understand it very much in the eye of the
beholder.

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Convert the decimal numbers expressed in a `numpy.ndarray` into a matrix representing elements in fractional form

2022-05-17 Thread Barry


> On 17 May 2022, at 05:59, hongy...@gmail.com  wrote:
> 
> On Monday, May 16, 2022 at 11:27:58 PM UTC+8, Dennis Lee Bieber wrote:
>> On Mon, 16 May 2022 02:03:26 -0700 (PDT), "hongy...@gmail.com" 
>>  declaimed the following: 
>> 
>> 
>>> print(lst) 
>> 
>> Printing higher level structures uses the repr() of the structure and 
>> its contents -- theoretically a form that could be used within code as a 
>> literal.
> 
> I tried with  the repr() method as follows, but it doesn't give any output:

Repr returns a string. You need to print its value to see it.

> 
> ```
> import os,sys
> import numpy as np
> from fractions import Fraction
> import re
> from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
> from pymatgen.core import Lattice, Structure, Molecule, IStructure
> 
> def filepath(file):
>   script_dirname=os.path.dirname(os.path.realpath(__file__))
>   return (script_dirname + '/' + file)
> 
> s=IStructure.from_file(filepath('EntryWithCollCode136212.cif'))
> a = SpacegroupAnalyzer(s)
> SymOp=a.get_symmetry_operations()
> b=SymOp[1].affine_matrix.tolist()
> 
> def strmat(m):
>   if(np.array([m]).ndim==1):
>  return str(Fraction(m))
>   else: return list(map(lambda L:strmat(L), np.array(m)))
> 
> lst=[]
> for i in SymOp:
>   lst.append(i.affine_matrix.tolist())
> 
> a=str(strmat(lst))
> a=re.sub(r"'","",a)
> repr(a)

print(repr(a))

Barry

> ```
> 
>> If you want human-readable str() you will need to write your own 
>> output loop to do the formatting of the structure, and explicitly print 
>> each item of the structure. 
> 
> 
> -- 
> https://mail.python.org/mailman/listinfo/python-list
> 

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Convert the decimal numbers expressed in a `numpy.ndarray` into a matrix representing elements in fractional form

2022-05-16 Thread hongy...@gmail.com
On Monday, May 16, 2022 at 11:27:58 PM UTC+8, Dennis Lee Bieber wrote:
> On Mon, 16 May 2022 02:03:26 -0700 (PDT), "hongy...@gmail.com" 
>  declaimed the following: 
> 
> 
> >print(lst) 
> 
> Printing higher level structures uses the repr() of the structure and 
> its contents -- theoretically a form that could be used within code as a 
> literal.

I tried with  the repr() method as follows, but it doesn't give any output:

```
import os,sys
import numpy as np
from fractions import Fraction
import re
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
from pymatgen.core import Lattice, Structure, Molecule, IStructure

def filepath(file):
   script_dirname=os.path.dirname(os.path.realpath(__file__))
   return (script_dirname + '/' + file)

s=IStructure.from_file(filepath('EntryWithCollCode136212.cif'))
a = SpacegroupAnalyzer(s)
SymOp=a.get_symmetry_operations()
b=SymOp[1].affine_matrix.tolist()

def strmat(m):
   if(np.array([m]).ndim==1):
  return str(Fraction(m))
   else: return list(map(lambda L:strmat(L), np.array(m)))

lst=[]
for i in SymOp:
   lst.append(i.affine_matrix.tolist())
   
a=str(strmat(lst))
a=re.sub(r"'","",a)
repr(a)
```

> If you want human-readable str() you will need to write your own 
> output loop to do the formatting of the structure, and explicitly print 
> each item of the structure. 
 

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Convert the decimal numbers expressed in a `numpy.ndarray` into a matrix representing elements in fractional form

2022-05-16 Thread hongy...@gmail.com
On Tuesday, May 17, 2022 at 7:11:24 AM UTC+8, hongy...@gmail.com wrote:
> On Monday, May 16, 2022 at 11:27:58 PM UTC+8, Dennis Lee Bieber wrote: 
> > On Mon, 16 May 2022 02:03:26 -0700 (PDT), "hongy...@gmail.com" 
> >  declaimed the following: 
> > 
> > 
> > >print(lst) 
> > 
> > Printing higher level structures uses the repr() of the structure and 
> > its contents -- theoretically a form that could be used within code as a 
> > literal. If you want human-readable str() you will need to write your own 
> > output loop to do the formatting of the structure, and explicitly print 
> > each item of the structure.
> Thank you for your explanation. I have come up with the following methods: 
> ``` 
> b=[[0.0, -1.0, 0.0, 0.25], [1.0, 0.0, 0.0, 0.25], [0.0, 0.0, 1.0, 0.25], 
> [0.0, 0.0, 0.0, 1.0]] 
> import numpy as np 
> from fractions import Fraction 
> import re 
> 
> def strmat(m): 
> if(np.array([m]).ndim==1): 
> return str(Fraction(m)) 
> else: return list(map(lambda L:strmat(L), np.array(m))) 
> 
> a=str(strmat(b)) 
> a=re.sub(r"'","",a) 
> repr(a) 
> print(repr(a)) 
> '[[0, -1, 0, 1/4], [1, 0, 0, 1/4], [0, 0, 1, 1/4], [0, 0, 0, 1]]' 
> ``` 
> Best, 
> HZ

See here [1] for the related discussion.

[1] 
https://discuss.python.org/t/convert-the-decimal-numbers-expressed-in-a-numpy-ndarray-into-a-matrix-representing-elements-in-fractional-form/15780
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Convert the decimal numbers expressed in a `numpy.ndarray` into a matrix representing elements in fractional form

2022-05-16 Thread hongy...@gmail.com
On Monday, May 16, 2022 at 11:27:58 PM UTC+8, Dennis Lee Bieber wrote:
> On Mon, 16 May 2022 02:03:26 -0700 (PDT), "hongy...@gmail.com" 
>  declaimed the following: 
> 
> 
> >print(lst) 
> 
> Printing higher level structures uses the repr() of the structure and 
> its contents -- theoretically a form that could be used within code as a 
> literal. If you want human-readable str() you will need to write your own 
> output loop to do the formatting of the structure, and explicitly print 
> each item of the structure.

Thank you for your explanation. I have come up with the following methods:
```
b=[[0.0, -1.0, 0.0, 0.25], [1.0, 0.0, 0.0, 0.25], [0.0, 0.0, 1.0, 0.25], [0.0, 
0.0, 0.0, 1.0]]
import numpy as np
from fractions import Fraction
import re

def strmat(m):
if(np.array([m]).ndim==1):
return str(Fraction(m))
else: return list(map(lambda L:strmat(L), np.array(m)))

a=str(strmat(b))
a=re.sub(r"'","",a)
repr(a)
print(repr(a))
'[[0, -1, 0, 1/4], [1, 0, 0, 1/4], [0, 0, 1, 1/4], [0, 0, 0, 1]]'
```
Best, 
HZ
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Convert the decimal numbers expressed in a `numpy.ndarray` into a matrix representing elements in fractional form

2022-05-16 Thread hongy...@gmail.com
On Tuesday, May 17, 2022 at 8:48:27 AM UTC+8, Dennis Lee Bieber wrote:
> On Mon, 16 May 2022 17:22:17 -0700 (PDT), "hongy...@gmail.com" 
>  declaimed the following: 
> 
> 
> >
> >I tried with the repr() method as follows, but it doesn't give any output:
> I have no idea what 50% of those libraries are supposed to do, and am 
> not going to install them just to try out your posted code. If you really 
> want such help, post the MINIMUM example code the produces your problem. 
> 
> >a=str(strmat(lst)) 
> >a=re.sub(r"'","",a) 
> 
> Explain what you believe this operation is doing, show us the input and 
> the output. 
> 
> The best I can make out of that is that it is looking for single quote 
> characters within whatever "a" is, and replacing them with nothing. 
> Something much more understandable, without invoking a regular expression 
> library (especially when neither the search nor the replacement terms are 
> regular expressions) with simple string operations... 
> 
> stripped = "".join(quoted.split("'")) 

Thank you for your above trick. I tried with the following code snippet:

```
from fractions import Fraction

def strmat(m):
   if(np.array([m]).ndim==1):
  return str(Fraction(m))
   else: return list(map(lambda L:strmat(L), np.array(m)))

# For test:
b=[[0.0, -1.0, 0.0, 0.25], [1.0, 0.0, 0.0, 0.25], [0.0, 0.0, 1.0, 0.25], [0.0, 
0.0, 0.0, 1.0]]  

a=str(strmat(b))
a1=stripped = "".join(a.split("'")) 
a=re.sub(r"'","",a)
#repr(a)
print("a1 = "+ a1)
print("a = "+ a)
```

As you can see, both methods give the same results:

```
a1 = [[0, -1, 0, 1/4], [1, 0, 0, 1/4], [0, 0, 1, 1/4], [0, 0, 0, 1]]
a = [[0, -1, 0, 1/4], [1, 0, 0, 1/4], [0, 0, 1, 1/4], [0, 0, 0, 1]]
```

> You also don't need to specify RAW format for the "'" -- Python is quite 
> happy mixing single and double quotes (that is: single quotes inside a 
> string using double quotes, double quotes inside a string using single 
> quotes, either inside strings using triply quoted delimiters) 
> 
> >>> "'" 
> "'" 
> >>> '"' 
> '"' 
> >>> """'"'""" 
> '\'"\'' 
> >>> '''"'"''' 
> '"\'"' 
> >>> 
> 
> (Note that the interactive console displays results using repr(), and hence 
> escapes ' that are internal to avoid conflict with the ones wrapping the 
> output) 
> 
> >>> repr('''"'"''') 
> '\'"\\\'"\'' 
> >>> str('''"'"''') 
> '"\'"' 
> >>> print('''"'"''') 
> "'" 
> >>> 
> 
> The print() operation does not wrap the output with extraneous quotes.

Thank your insightful explanation.

Regards,
HZ

> -- 
> Wulfraed Dennis Lee Bieber AF6VN 
> wlf...@ix.netcom.com http://wlfraed.microdiversity.freeddns.org/
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Convert the decimal numbers expressed in a `numpy.ndarray` into a matrix representing elements in fractional form

2022-05-16 Thread Dennis Lee Bieber
On Mon, 16 May 2022 02:03:26 -0700 (PDT), "hongy...@gmail.com"
 declaimed the following:


>print(lst)

Printing higher level structures uses the repr() of the structure and
its contents -- theoretically a form that could be used within code as a
literal. If you want human-readable str() you will need to write your own
output loop to do the formatting of the structure, and explicitly print
each item of the structure.


-- 
Wulfraed Dennis Lee Bieber AF6VN
wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Convert the decimal numbers expressed in a `numpy.ndarray` into a matrix representing elements in fractional form

2022-05-16 Thread Dennis Lee Bieber
On Mon, 16 May 2022 17:22:17 -0700 (PDT), "hongy...@gmail.com"
 declaimed the following:


>
>I tried with  the repr() method as follows, but it doesn't give any output:


I have no idea what 50% of those libraries are supposed to do, and am
not going to install them just to try out your posted code. If you really
want such help, post the MINIMUM example code the produces your problem.

>a=str(strmat(lst))
>a=re.sub(r"'","",a)

Explain what you believe this operation is doing, show us the input and
the output.

The best I can make out of that is that it is looking for single quote
characters within whatever "a" is, and replacing them with nothing.
Something much more understandable, without invoking a regular expression
library (especially when neither the search nor the replacement terms are
regular expressions) with simple string operations...

stripped = "".join(quoted.split("'"))

You also don't need to specify RAW format for the "'" -- Python is quite
happy mixing single and double quotes (that is: single quotes inside a
string using double quotes, double quotes inside a string using single
quotes, either inside strings using triply quoted delimiters)

>>> "'"
"'"
>>> '"'
'"'
>>> """'"'"""
'\'"\''
>>> '''"'"'''
'"\'"'
>>> 

(Note that the interactive console displays results using repr(), and hence
escapes ' that are internal to avoid conflict with the ones wrapping the
output)

>>> repr('''"'"''')
'\'"\\\'"\''
>>> str('''"'"''')
'"\'"'
>>> print('''"'"''')
"'"
>>> 

The print() operation does not wrap the output with extraneous quotes.


-- 
Wulfraed Dennis Lee Bieber AF6VN
wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/
-- 
https://mail.python.org/mailman/listinfo/python-list


[issue210627] Floating point numbers (PR#277)

2022-04-10 Thread admin


Change by admin :


___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue494873] add tests for complex numbers

2022-04-10 Thread admin


Change by admin :


--
github: None -> 35788

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue473456] float round up on decimal numbers

2022-04-10 Thread admin


Change by admin :


--
github: None -> 35373

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue403516] zipfile.py: use hex constants for magic numbers

2022-04-10 Thread admin


Change by admin :


--
github: None -> 33832

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue229417] Negative numbers are grouped incorrectly

2022-04-10 Thread admin


Change by admin :


--
github: None -> 33761

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue210627] Floating point numbers (PR#277)

2022-04-10 Thread admin


Change by admin :


--
github: None -> 32698

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue47225] Issue in subtraction of float numbers

2022-04-04 Thread Raymond Hettinger


Raymond Hettinger  added the comment:

See https://docs.python.org/3/tutorial/floatingpoint.html

--
nosy: +rhettinger
resolution:  -> wont fix
stage:  -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue47225] Issue in subtraction of float numbers

2022-04-04 Thread Prem B. Shah


New submission from Prem B. Shah :

There is an issue when subtracting float numbers ...
for e.g.
print (5.67 - 5.6)
gives an output : 0.07028

--
components: Windows
messages: 416748
nosy: MrPhenomenal3110, paul.moore, steve.dower, tim.golden, zach.ware
priority: normal
severity: normal
status: open
title: Issue in subtraction of float numbers
versions: Python 3.9

___
Python tracker 
<https://bugs.python.org/issue47225>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46974] set function for lists on numbers, sometimes sorts elements from smallest to largest, and sometimes not

2022-03-10 Thread Eric V. Smith


Eric V. Smith  added the comment:

This is expected behavior. A set has no defined order. If you convert a set to 
a list, and you want some specific order, you'll need to sort it yourself.

--
nosy: +eric.smith
resolution:  -> not a bug
stage:  -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46974] set function for lists on numbers, sometimes sorts elements from smallest to largest, and sometimes not

2022-03-10 Thread PiTeR


New submission from PiTeR :

set function for lists on numbers, sometimes sorts elements from smallest to 
largest, and sometimes not
to find this bug, sometimes you need to display the result several times
example code:
def tupla():
import random
ilosc = random.randint(0,49)
n=0
lista=[]
i=0
while True:
n = random.randint(1,100)
lista.append(n)
i=i+1
if i==ilosc-1:
break
lista = set(lista)
list(lista)
print(lista)

--
components: Windows
files: bug_1.PNG
messages: 414848
nosy: paul.moore, pio.paluchowski, steve.dower, tim.golden, zach.ware
priority: normal
severity: normal
status: open
title: set function for lists on numbers, sometimes sorts elements from 
smallest to largest, and sometimes not
type: behavior
versions: Python 3.10
Added file: https://bugs.python.org/file50666/bug_1.PNG

___
Python tracker 
<https://bugs.python.org/issue46974>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28249] doctest.DocTestFinder reports incorrect line numbers with exclude_empty=False

2022-01-09 Thread Kumar Aditya


Change by Kumar Aditya :


--
nosy: +kumaraditya303
type:  -> behavior
versions: +Python 3.10, Python 3.11, Python 3.9 -Python 2.7, Python 3.5

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28249] doctest.DocTestFinder reports incorrect line numbers with exclude_empty=False

2022-01-09 Thread Nikita Sobolev


Change by Nikita Sobolev :


--
keywords: +patch
nosy: +sobolevn
nosy_count: 2.0 -> 3.0
pull_requests: +28704
stage:  -> patch review
pull_request: https://github.com/python/cpython/pull/30498

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36048] Deprecate implicit truncating when convert Python numbers to C integers: use __index__, not __int__

2021-12-09 Thread Calin Culianu


Calin Culianu  added the comment:

Ok, Guido, thanks. Fair enough.

So regardless: what is the problem exactly if a C function expects an int but 
gets given a float? Why does such strictness matter, in that it required a 
whole other set of __index__ etc to be added?  I am having trouble seeing the 
actual problem, which was taken as a given in all the archaeology I have done 
on this ancient "issue" -- but is it a given?  There is no problem... only the 
one created by this change, really.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36048] Deprecate implicit truncating when convert Python numbers to C integers: use __index__, not __int__

2021-12-09 Thread Guido van Rossum


Guido van Rossum  added the comment:

Claim, you need to tone down the rhetoric. Python is not C++ and user 
expectations are different. You are the one who is fighting windmills here.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36048] Deprecate implicit truncating when convert Python numbers to C integers: use __index__, not __int__

2021-12-09 Thread Calin Culianu


Calin Culianu  added the comment:

Ok, well I found this in that issue you linked to:

This is the original "problem":

```
type __mul__ is wierd:

>> 'a'.__mul__(3.4)
'aaa'
>>> [1].__mul__(3.4)
[1, 1, 1]
```

And this is Guido's response:

> The problem is that on the one hand you want "i" to accept
other int-ish types that have an __int__ method. But on the
other hand you don't want it to accept float, which also has
an __int__ method. Or other float-ish types.

--- 

You have to understand -- I don't see a problem here!

Not once is there any discussion as to *why* this is really a problem. So what? 
Your float gets truncated and treated as an int.  So?

If you are calling into a C api -- why is this a problem exactly when **in the 
C Language itself** by convention and by compiler rules anyway -- this is 
**perfectly ok**.

Restricting Python in this way -- why? What is the benefit? What problem is 
being solved? I did all the digging in the world here and cannot at all discern 
what, exactly, is being solved at all.  It seems like some bizarre aesthetic 
thing, at best.  Sorry.. maybe I am wrong.  Please point me to where the real 
problem is... 

Again, I reiterate **mathematically**, by convention in computer science, the 
conversion from float -> int is well defined.  Moreover, you have the legacy 
__int__ method already that *can define it* for specific types. And Python has 
worked this way since the age of the dinosaurs (2002!!).

So.. in python this conversion is well defined. And has always been, by __int__.

I think the introduction of __index__ versus __int__ may be a mistake, 
especially if it is designed to "solve" just this problem -- which as yet, has 
to be clearly argued for as to **why** it's a problem!

This boggles my mind, guys. I.. am speechless.  Please tell me I'm wrong. To me 
it seems you guys imagined a problem that doesn't exist, then "solved" it with 
extra API stuff, and the actual end result was -- real-world problems created 
ex-nihilo for real-world programs, manifesting themselves finally in 2021.

You have to understand that .. to me as a C++ programmer.. I see no problem. I 
just see Python all of a sudden becoming less nice.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36048] Deprecate implicit truncating when convert Python numbers to C integers: use __index__, not __int__

2021-12-09 Thread Serhiy Storchaka


Serhiy Storchaka  added the comment:

See issue660144 which made float values be rejected in most cases where an 
integer is expected rather of silently truncating them. It was at 2003. Guido 
mentioned that is an age-old problem, so perhaps you can find older discussions 
on the tracker or mailing lists.

It was a partial solution. It caught unexpected floats, but not other 
non-integer numbers. Later, the __index__ special method was introduced 
specially to distinguish objects which can be implicitly converted to integer 
from these which can be explicitly converted to integer. And finally we fixed 
that age-old problem.

If you have other questions, please ask them on mailing lists, forums or other 
resources.

--

___
Python tracker 
<https://bugs.python.org/issue36048>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36048] Deprecate implicit truncating when convert Python numbers to C integers: use __index__, not __int__

2021-12-09 Thread Calin Culianu


Calin Culianu  added the comment:

Hi, I'm cculianu, the reporting user.

May I get a link or some background for the motivation for this change? It 
seems to me that there are vague allusions to "Decimal -> int cause problems in 
past", or some such, and I'd like to read the arguments presented as to what 
problems in particular, and how this change fixes those problems.

Mathematically, and by convention in computer science, conversions from 
float-like types -> int are always well defined.  It seems strangely 
un-Pythonic to restrict things in such a way.  I am very surprised by this 
change, quite frankly.  It's the wrong direction to go in, for this language, 
is my intuitive feeling.

Anyway, very curious about what the rationale was for this. Thanks.

--
nosy: +calin.culianu

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36048] Deprecate implicit truncating when convert Python numbers to C integers: use __index__, not __int__

2021-12-09 Thread Mark Dickinson


Mark Dickinson  added the comment:

For the record, #37999 is the issue that turned the deprecation warnings into 
errors for Python 3.10. (But as Serhiy says, please open a new issue, or start 
a discussion on one of the mailing lists.)

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36048] Deprecate implicit truncating when convert Python numbers to C integers: use __index__, not __int__

2021-12-09 Thread Serhiy Storchaka


Serhiy Storchaka  added the comment:

This issue was closed more than 2.5 years ago. The changes were made in 3.8, 
not in 3.10. BTW, 3.8 only accepts security fixes now. Please open a new issue 
for new discussion.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36048] Deprecate implicit truncating when convert Python numbers to C integers: use __index__, not __int__

2021-12-09 Thread Mark Dickinson


Mark Dickinson  added the comment:

@arhadthedev: Thanks for highlighting the issue.

> we need to check if the problem really has place and the PR needs to be 
> retracted until PyQt5 is ported to newer Python C API

I'm not particularly impressed by the arguments from cculianu. This was the 
right change to make: this is very general machinery, and we've seen many real 
issues over the years resulting from implicit acceptance of floats or Decimal 
objects where an integer is expected. 

It may well be that for some *specific* libraries like PyQt5 it makes sense to 
make a different choice. And indeed, PySide6 has done exactly that:

Python 3.10.0 (default, Nov 12 2021, 12:32:57) [Clang 12.0.5 
(clang-1205.0.22.11)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from PySide6.QtCore import QPoint
>>> QPoint(2, 3)
PySide6.QtCore.QPoint(2, 3)
>>> QPoint(2.1, 3.3)
PySide6.QtCore.QPoint(2, 3)

So no, I don't believe this change should be reverted. At best, we could 
re-introduce the deprecation warnings and delay the full implementation of the 
change. But the deprecation warnings were present since Python 3.8, and so 
either the PyQt5 developers noticed them but didn't want to make the change, or 
didn't notice them. Either way, it's difficult to see what difference extending 
the deprecation warning period would make. Moreover, the new behaviour is 
already released, in Python 3.10.0 and 3.10.1, and the code churn would likely 
be more annoying than helpful.

I would suggest to cculianu that they take this up with the PyQt5 developers.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36048] Deprecate implicit truncating when convert Python numbers to C integers: use __index__, not __int__

2021-12-08 Thread Oleg Iarygin


Oleg Iarygin  added the comment:

The reporter gave more details 
():

> Literally this is ok in C++ with Qt:
>
> float x = 2.3, y = 1.1;
> auto p = QPoint(x, y); // QPoint only takes 2 int params.. this works in 
> C++; floats can be always be implicitly converted to int
>
> Same code, more or less, in Python3.10 is now broken:
>
> x = 2.3
> y = 1.1
> p = QPoint(x, y)  # This fails, where previously it worked on every 
> Python version since the age of the dinosaurs...
>
> Note that most of the API for PyQt5 is auto-generated from the function 
> signatures of the C++. So in this case QPoint takes 2 ints for its c'tor 
> (just like in C++).. and breaks on Python 3.10 if given floats, when 
> previously it worked just fine with either ints or floats. This is just 1 
> example. But many codebases that use PyQt5 are hit by breakages like this one 
> now.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36048] Deprecate implicit truncating when convert Python numbers to C integers: use __index__, not __int__

2021-12-08 Thread Oleg Iarygin


Oleg Iarygin  added the comment:

Here is a report that this change breaks PyQt5 on Fedora:



> [...]
>
> Why do I care? This breaks tons of existing PyQt5 code out there, for 
> example. I wasn't aware of this change to the language until Fedora shipped 
> Python 3.10 and everything broke. So much stuff that uses PyQt5 is broken 
> now. Good job guys!!
>
> [...]

Even though the rest of comment is emotional, we need to check if the problem 
really has place and the PR needs to be retracted until PyQt5 is ported to 
newer Python C API.

--
nosy: +arhadthedev

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue45838] Incorrect line numbers in GDB Python backtraces [3.9]

2021-11-19 Thread Łukasz Langa

Łukasz Langa  added the comment:

Thanks, Sam! ✨  ✨

--
resolution:  -> fixed
stage: patch review -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue45838] Incorrect line numbers in GDB Python backtraces [3.9]

2021-11-19 Thread Łukasz Langa

Łukasz Langa  added the comment:


New changeset 2a32dbf110cf80ec9a00290ea6bc84f409948cb0 by Sam Gross in branch 
'3.9':
[3.9] bpo-45838: Fix incorrect line numbers in Tools/gdb/libpython.py (GH-29628)
https://github.com/python/cpython/commit/2a32dbf110cf80ec9a00290ea6bc84f409948cb0


--
nosy: +lukasz.langa

___
Python tracker 
<https://bugs.python.org/issue45838>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue45838] Incorrect line numbers in GDB Python backtraces [3.9]

2021-11-18 Thread Sam Gross


Change by Sam Gross :


--
keywords: +patch
pull_requests: +27860
stage:  -> patch review
pull_request: https://github.com/python/cpython/pull/29628

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue45838] Incorrect line numbers in GDB Python backtraces [3.9]

2021-11-18 Thread Sam Gross


New submission from Sam Gross :

Starting in Python 3.6 the line numbers table contains a *signed* byte 
indicating line delta. The calculation in Tools/gdb/libpython.py was not 
updated to handle signed bytes leading to incorrect line numbers when running 
"py-bt" (or printing frames) in GDB.

This issue does not exist in Python 3.10 or later because line number table was 
changed (and libpython.py was updated) in GH-23113.

--
components: Demos and Tools
messages: 406560
nosy: colesbury
priority: normal
severity: normal
status: open
title: Incorrect line numbers in GDB Python backtraces [3.9]
type: behavior
versions: Python 3.6, Python 3.7, Python 3.8, Python 3.9

___
Python tracker 
<https://bugs.python.org/issue45838>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue15996] pow() for complex numbers is rough around the edges

2021-10-22 Thread Mark Dickinson


Mark Dickinson  added the comment:

See also discussion in #44970, which is closed as a duplicate of this issue.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44344] Documentation for pow() should include the possibility of complex numbers as a return type

2021-10-21 Thread Łukasz Langa

Łukasz Langa  added the comment:

Thanks, Mark! ✨  ✨

--
resolution:  -> fixed
stage: patch review -> resolved
status: open -> closed
versions: +Python 3.10, Python 3.11

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44344] Documentation for pow() should include the possibility of complex numbers as a return type

2021-10-21 Thread Łukasz Langa

Łukasz Langa  added the comment:


New changeset c53428fe8980aab6eda3e573bafed657e6798e6e by Miss Islington (bot) 
in branch '3.9':
bpo-44344: Document that pow can return a complex number for non-complex 
inputs. (GH-27853) (GH-29134)
https://github.com/python/cpython/commit/c53428fe8980aab6eda3e573bafed657e6798e6e


--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44344] Documentation for pow() should include the possibility of complex numbers as a return type

2021-10-21 Thread Łukasz Langa

Łukasz Langa  added the comment:


New changeset 9b3cda56870d087cf50f605e91f3d26964868640 by Miss Islington (bot) 
in branch '3.10':
bpo-44344: Document that pow can return a complex number for non-complex 
inputs. (GH-27853) (GH-29135)
https://github.com/python/cpython/commit/9b3cda56870d087cf50f605e91f3d26964868640


--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44344] Documentation for pow() should include the possibility of complex numbers as a return type

2021-10-21 Thread miss-islington


Change by miss-islington :


--
pull_requests: +27411
pull_request: https://github.com/python/cpython/pull/29135

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44344] Documentation for pow() should include the possibility of complex numbers as a return type

2021-10-21 Thread miss-islington


Change by miss-islington :


--
nosy: +miss-islington
nosy_count: 7.0 -> 8.0
pull_requests: +27410
pull_request: https://github.com/python/cpython/pull/29134

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44344] Documentation for pow() should include the possibility of complex numbers as a return type

2021-10-21 Thread Łukasz Langa

Łukasz Langa  added the comment:


New changeset 887a55705bb6c05a507c2886c9978a9e0cff0dd7 by Mark Dickinson in 
branch 'main':
bpo-44344: Document that pow can return a complex number for non-complex 
inputs. (GH-27853)
https://github.com/python/cpython/commit/887a55705bb6c05a507c2886c9978a9e0cff0dd7


--
nosy: +lukasz.langa

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue15996] pow() for complex numbers is rough around the edges

2021-10-21 Thread Terry J. Reedy


Terry J. Reedy  added the comment:

In Windows, I now get the Mark's macOS result instead of the Z.D.Error.

>>> (1.0+0j)**(float('inf') + 0j)
(nan+nanj)

Has there been a revision of complex ** on another issue such that this one is 
obsolete?

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue25934] ICC compiler: ICC treats denormal floating point numbers as 0.0

2021-10-19 Thread Mark Dickinson


Mark Dickinson  added the comment:

> Closing this as out of date.

SGTM. Thanks.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue25934] ICC compiler: ICC treats denormal floating point numbers as 0.0

2021-10-18 Thread Zachary Ware


Zachary Ware  added the comment:

I no longer have access to ICC, and the ICC buildbots have been mothballed some 
years ago.  Closing this as out of date; the issue might not be, but the 
information about it here probably is :)

--
resolution:  -> out of date
stage:  -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue42914] pprint numbers with underscore

2021-10-09 Thread Stéphane Blondon

Stéphane Blondon  added the comment:

Ok, I will not send a PR to change the current behavior until python4 (in case 
it exists one day).

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue42914] pprint numbers with underscore

2021-10-05 Thread Eric V. Smith


Eric V. Smith  added the comment:

The safest thing to do is never make it the default. It would always be an 
opt-in behavior.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue42914] pprint numbers with underscore

2021-10-05 Thread Stéphane Blondon

Stéphane Blondon  added the comment:

Python 3.10 has now been released with the underscore_numbers parameter.
I wonder which release could enable the parameter by default (so it would break 
the previous behavior):
 - the next release (3.11) is probably too short.
 - the safest strategy is to wait until 3.9 will be end-of-life (2025-10 
according to [1]). In such case, it could be integrated in 3.14.

Could it be accepted before (like 3.12 or 3.13)?

If there is no reply, I will create a new issue and PR for 3.14 inclusion ( = 
safest strategy).


1: https://devguide.python.org/#status-of-python-branches

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



Re: on floating-point numbers

2021-09-12 Thread Grant Edwards
On 2021-09-11, Chris Angelico  wrote:

> Once you accept that "perfectly representable numbers" aren't
> necessarily the ones you expect them to be, 64-bit floats become
> adequate for a huge number of tasks. Even 32-bit floats are pretty
> reliable for most tasks, although I suspect that there's little reason
> to use them now - would be curious to see if there's any performance
> benefit from restricting to the smaller format, given that most FPUs
> probably have 80-bit or wider internal registers.

Not all CPUs have FPUs. Most of my development time is spent writing
code for processors without FPUs.  A soft implementation of 32-bit FP
on a 32-bit processors is way, way faster than for 64-bit FP. Not to
mention the fact that 32-bit FP data takes up half the memory of
64-bit.

There are probably not many people using Python on 32-bit CPUs w/o FP.

--
Grant


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-11 Thread Peter J. Holzer
On 2021-09-12 01:40:12 +1000, Chris Angelico wrote:
> On Sun, Sep 12, 2021 at 1:07 AM Peter J. Holzer  wrote:
> > If you have any "decimals" (i.e decimal digits to the right of your
> > decimal point) then the input values won't be exactly representable and
> > the nearest representation will use all available bits, thus losing some
> > precision with most additions.
> 
> That's an oversimplification, though - numbers like 12345.03125 can be
> perfectly accurately represented, since the fractional part is a
> (negative) power of two.

Yes. I had explained that earlier in this thread.

> The perceived inaccuracy of floating point numbers comes from an
> assumption that a string of decimal digits is exact, and the
> computer's representation of it is not. If I put this in my code:
> 
> ONE_THIRD = 0.3
> 
> then you know full well that it's not accurate, and that's nothing to
> do with IEEE floating-point! The confusion comes from the fact that
> one fifth (0.2) can be represented precisely in decimal, and not in
> binary.

Exactly.


> Once you accept that "perfectly representable numbers" aren't
> necessarily the ones you expect them to be, 64-bit floats become
> adequate for a huge number of tasks.

Yep. That's what I was trying to convey. 


> Even 32-bit floats are pretty reliable for most tasks, although I
> suspect that there's little reason to use them now - would be curious
> to see if there's any performance benefit from restricting to the
> smaller format, given that most FPUs probably have 80-bit or wider
> internal registers.

AFAIK C compilers on 64-bit AMD/Intel architecture don't use the x87 ABI
any more, they use the various vector extensions (SSE, etc.) instead.
Those have hardware support for 64 and 32 bit FP values, so 32 bit are
probably faster, if only because you can cram more of them into a
register. Modern GPUs now have 16 bit FP numbers - those are perfectly
adequate for neural networks and also some graphics tasks and you can
transfer twice as many per memory cycle ...

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-11 Thread Chris Angelico
On Sun, Sep 12, 2021 at 1:07 AM Peter J. Holzer  wrote:
> If you have any "decimals" (i.e decimal digits to the right of your
> decimal point) then the input values won't be exactly representable and
> the nearest representation will use all available bits, thus losing some
> precision with most additions.

That's an oversimplification, though - numbers like 12345.03125 can be
perfectly accurately represented, since the fractional part is a
(negative) power of two.

The perceived inaccuracy of floating point numbers comes from an
assumption that a string of decimal digits is exact, and the
computer's representation of it is not. If I put this in my code:

ONE_THIRD = 0.3

then you know full well that it's not accurate, and that's nothing to
do with IEEE floating-point! The confusion comes from the fact that
one fifth (0.2) can be represented precisely in decimal, and not in
binary.

Once you accept that "perfectly representable numbers" aren't
necessarily the ones you expect them to be, 64-bit floats become
adequate for a huge number of tasks. Even 32-bit floats are pretty
reliable for most tasks, although I suspect that there's little reason
to use them now - would be curious to see if there's any performance
benefit from restricting to the smaller format, given that most FPUs
probably have 80-bit or wider internal registers.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-11 Thread Peter J. Holzer
On 2021-09-05 23:21:14 -0400, Richard Damon wrote:
> > On Sep 5, 2021, at 6:22 PM, Peter J. Holzer  wrote:
> > On 2021-09-04 10:01:23 -0400, Richard Damon wrote:
> >>> On 9/4/21 9:40 AM, Hope Rouselle wrote:
> >>> Hm, I think I see what you're saying.  You're saying multiplication and
> >>> division in IEEE 754 is perfectly safe --- so long as the numbers you
> >>> start with are accurately representable in IEEE 754 and assuming no
> >>> overflow or underflow would occur.  (Addition and subtraction are not
> >>> safe.)
> >>> 
> >> 
> >> Addition and Subtraction are just as safe, as long as you stay within
> >> the precision limits.
> > 
> > That depends a lot on what you call "safe", 
> > 
> > a * b / a will always be very close to b (unless there's an over- or
> > underflow), but a + b - a can be quite different from b.
> > 
> > In general when analyzing a numerical algorithm you have to pay a lot
> > more attention to addition and subtraction than to multiplication and
> > division.
> > 
> Yes, it depends on your definition of safe. If ‘close’ is good enough
> then multiplication is probably safer as the problems are in more
> extreme cases. If EXACT is the question, addition tends to be better.
> To have any chance, the numbers need to be somewhat low ‘precision’,
> which means the need to avoid arbitrary decimals.

If you have any "decimals" (i.e decimal digits to the right of your
decimal point) then the input values won't be exactly representable and
the nearest representation will use all available bits, thus losing some
precision with most additions.

> Once past that, as long as the numbers are of roughly the same
> magnitude, and are the sort of numbers you are apt to just write, you
> can tend to add a lot of them before you get enough bits to accumulate
> to have a problem.

But they won't be exact. You may not care about rounding errors in the
tenth digit after the point, but you are only close, not exact. So if
you are fine with a tiny rounding error here, why are you upset about
equally tiny rounding errors on multiplication?

> With multiplication, every multiply roughly adds the number of bits of
> precision, so you quickly run out, and one divide will have a chance
> to just end the process.

Nope. The relative error stays the same unlike for addition where is can
get very large very quickly.

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-11 Thread Peter J. Holzer
On 2021-09-05 22:32:51 -, Grant Edwards wrote:
> On 2021-09-05, Peter J. Holzer  wrote:

[on the representability of fractional numbers as floating point
numbers]

> And once you understand that, ignore it and write code under the
> assumumption that nothing can be exactly represented in floating
> point.

In almost all cases even the input values aren't exact.


> If you like, you can assume that 0 can be exactly represented without
> getting into too much trouble as long as it's a literal constant value
> and not the result of any run-time FP operations.
> 
> If you want to live dangerously, you can assume that integers with
> magnitude less than a million can be exactly represented. That
> assumption is true for all the FP representations I've ever used,

If you know nothing about the FP representation you use you could do
that (however, there is half-precision (16-bit) floating-point which has
an even shorter mantissa). But if you are that conservative, you should
be equally conservative with your integers, which probably means you
can't depend on more than 16 bits (±32767).

However, we are using Python here which means we have at least 9 decimal digits
of useable mantissa
(https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex
somewhat unhelpfully states that "[f]loating point numbers are usually
implemented using double in C", but refers to
https://docs.python.org/3/library/sys.html#sys.float_info which in turn
refers directly to the DBL_* constants from C99. So DBL_EPSILON is at
most 1E-9. in practice almost certainly less than 1E-15).

> but once you start depending on it, you're one stumble from the edge
> of the cliff.

I think this attitude will prevent you from using floating point numbers
when you could, reinventing the wheel, probably badly.

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


[issue44344] Documentation for pow() should include the possibility of complex numbers as a return type

2021-09-09 Thread Raymond Hettinger


Raymond Hettinger  added the comment:

The pow() docs could use substantial updating.  All of the logic for pow() is 
implemented in base.__pow__(exp, [mod]).  Technically, it isn't restricted to 
numeric types, that is just a norm.  The relationship between "pow(a,b)" and 
"a**b" is that both make the same call, a.__pow__(b).  The discussion of 
coercion rules dates back to Python 2 where used to have a coerce() builtin.  
Now, the cross-type logic is buried in either in type(a).__pow__ or in 
type(b).__rpow__.  The equivalence of pow(a, b, c) to a more efficient form of 
"a ** b % c" is a norm but not a requirement and is only supported by ints or 
third-party types.

My suggestions

1st paragraphs:  Stay at a high level, covering only the most common use case 
and simple understanding of how most people use pow():

   Return *base* to the power *exp* giving the same result
   as ``base**exp``.

   If *mod* is present and all the arguments are integers,
   return *base* to the power *exp*, modulo *mod*.  This
   gives the same result as ``base ** exp % mod`` but is
   computed much more efficiently.

2nd paragraph:  Be precise about what pow() actually does, differentiating the 
typical case from what is actually required:

   The :func:`pow` function calls the base's meth:`__pow__` method
   falling back to the exp's meth:`__rpow__` if needed.  The logic
   and semantics of those methods varies depending on the type.
   Typically, the arguments have numeric types but this is not required.
   For types that support the three-argument form, the usual semantics
   are that ``pow(b, e, m)`` is equivalent to ``a ** b % c`` but
   this is not required.

3rd paragraph: Cover behaviors common to int, float, and complex.

4th paragraph and later:  Cover type specific behaviors (i.e. only int supports 
the three argument form and the other arguments must be ints as well).

--
nosy: +rhettinger

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44344] Documentation for pow() should include the possibility of complex numbers as a return type

2021-09-09 Thread Mark Dickinson


Mark Dickinson  added the comment:

@Erik: Do you have a moment to look at the PR (GH-27853) and see if the 
proposed changes work for you?

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



Re: on floating-point numbers

2021-09-08 Thread Hope Rouselle
Joe Pfeiffer  writes:

> Hope Rouselle  writes:
>> Christian Gollwitzer  writes:
>>>
>>> I believe it is not commutativity, but associativity, that is
>>> violated. 
>>
>> Shall we take this seriously?  (I will disagree, but that doesn't mean I
>> am not grateful for your post.  Quite the contary.)  It in general
>> violates associativity too, but the example above couldn't be referring
>> to associativity because the second sum above could not be obtained from
>> associativity alone.  Commutativity is required, applied to five pairs
>> of numbers.  How can I go from
>>
>>   7.23 + 8.41 + 6.15 + 2.31 + 7.73 + 7.77
>>
>> to 
>>
>>   8.41 + 6.15 + 2.31 + 7.73 + 7.77 + 7.23?
>>
>> Perhaps only through various application of commutativity, namely the
>> ones below. (I omit the parentheses for less typing.  I suppose that
>> does not create much trouble.  There is no use of associativity below,
>> except for the intented omission of parentheses.)
>>
>>  7.23 + 8.41 + 6.15 + 2.31 + 7.73 + 7.77
>>= 8.41 + 7.23 + 6.15 + 2.31 + 7.73 + 7.77
>>= 8.41 + 6.15 + 7.23 + 2.31 + 7.73 + 7.77
>>= 8.41 + 6.15 + 2.31 + 7.23 + 7.73 + 7.77
>>= 8.41 + 6.15 + 2.31 + 7.73 + 7.23 + 7.77
>>= 8.41 + 6.15 + 2.31 + 7.73 + 7.77 + 7.23.
>
> But these transformations depend on both commutativity and
> associativity, precisely due to those omitted parentheses.  When you
> transform
>
> 7.23 + 8.41 + 6.15 + 2.31 + 7.73 + 7.77
>
> into
>
> 8.41 + 6.15 + 2.31 + 7.73 + 7.77 + 7.23.
>
> it isn't just assuming commutativity, it's also assuming associativity
> since it is changing from
>
> (7.23 + 8.41 + 6.15 + 2.31 + 7.73) + 7.77
>
> to
>
> (8.41 + 6.15 + 2.31 + 7.73 + 7.77) + 7.23.
> 
> If I use parentheses to modify the order of operations of the first line
> to match that of the last, I get
> 7.23 + (8.41 + 6.15 + 2.31 + 7.73 + 7.77)
>
> Now, I get 39.61 evaluating either of them.

I need to go slow.  If I have just two numbers, then I don't need to
talk about associativity: I can send 7.23 to the rightmost place with a
single application of commutativity.  In symbols,

  7.23 + 8.41 = 8.41 + 7.23.

But if I have three numbers and I want to send the leftmost to the
rightmost place, I need to apply associativity

7.23 + 8.41 + 6.15
  = (7.23 + 8.41) + 6.15  -- clarifying that I go left to right
  = 7.23 + (8.41 + 6.15)  -- associativity
  = (8.41 + 6.15) + 7.23  -- commutativity

I see it.  Cool.  Thanks.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-07 Thread Joe Pfeiffer
Hope Rouselle  writes:
> Christian Gollwitzer  writes:
>>
>> I believe it is not commutativity, but associativity, that is
>> violated. 
>
> Shall we take this seriously?  (I will disagree, but that doesn't mean I
> am not grateful for your post.  Quite the contary.)  It in general
> violates associativity too, but the example above couldn't be referring
> to associativity because the second sum above could not be obtained from
> associativity alone.  Commutativity is required, applied to five pairs
> of numbers.  How can I go from
>
>   7.23 + 8.41 + 6.15 + 2.31 + 7.73 + 7.77
>
> to 
>
>   8.41 + 6.15 + 2.31 + 7.73 + 7.77 + 7.23?
>
> Perhaps only through various application of commutativity, namely the
> ones below. (I omit the parentheses for less typing.  I suppose that
> does not create much trouble.  There is no use of associativity below,
> except for the intented omission of parentheses.)
>
>  7.23 + 8.41 + 6.15 + 2.31 + 7.73 + 7.77
>= 8.41 + 7.23 + 6.15 + 2.31 + 7.73 + 7.77
>= 8.41 + 6.15 + 7.23 + 2.31 + 7.73 + 7.77
>= 8.41 + 6.15 + 2.31 + 7.23 + 7.73 + 7.77
>= 8.41 + 6.15 + 2.31 + 7.73 + 7.23 + 7.77
>= 8.41 + 6.15 + 2.31 + 7.73 + 7.77 + 7.23.

But these transformations depend on both commutativity and
associativity, precisely due to those omitted parentheses.  When you
transform

7.23 + 8.41 + 6.15 + 2.31 + 7.73 + 7.77

into

8.41 + 6.15 + 2.31 + 7.73 + 7.77 + 7.23.

it isn't just assuming commutativity, it's also assuming associativity
since it is changing from

(7.23 + 8.41 + 6.15 + 2.31 + 7.73) + 7.77

to

(8.41 + 6.15 + 2.31 + 7.73 + 7.77) + 7.23.

If I use parentheses to modify the order of operations of the first line
to match that of the last, I get
7.23 + (8.41 + 6.15 + 2.31 + 7.73 + 7.77)

Now, I get 39.61 evaluating either of them.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-06 Thread Hope Rouselle
Chris Angelico  writes:

> On Sun, Sep 5, 2021 at 1:04 PM Hope Rouselle  wrote:
>> The same question in other words --- what's a trivial way for the REPL
>> to show me such cycles occur?
>>
>> >> 7.23.as_integer_ratio()
>> >>> (2035064081618043, 281474976710656)
>>
>> Here's what I did on this case.  The REPL is telling me that
>>
>>   7.23 = 2035064081618043/281474976710656
>>
>> If that were true, then 7.23 * 281474976710656 would have to equal
>> 2035064081618043.  So I typed:
>>
>> >>> 7.23 * 281474976710656
>> 2035064081618043.0
>>
>> That agrees with the falsehood.  I'm getting no evidence of the problem.
>>
>> When take control of my life out of the hands of misleading computers, I
>> calculate the sum:
>>
>>844424930131968
>>  +5629499534213120
>> 197032483697459200
>> ==
>> 203506408161804288
>> =/= 203506408161804300
>>
>> How I can save the energy spent on manual verification?
>
> What you've stumbled upon here is actually a neat elegance of
> floating-point, and an often-forgotten fundamental of it: rounding
> occurs exactly the same regardless of the scale. The number 7.23 is
> represented with a certain mantissa, and multiplying it by some power
> of two doesn't change the mantissa, only the exponent. So the rounding
> happens exactly the same, and it comes out looking equal!

That's insightful.  Thanks!

> The easiest way, in Python, to probe this sort of thing is to use
> either fractions.Fraction or decimal.Decimal. I prefer Fraction, since
> a float is fundamentally a rational number, and you can easily see
> what's happening. You can construct a Fraction from a string, and
> it'll do what you would expect; or you can construct one from a float,
> and it'll show you what that float truly represents.
>
> It's often cleanest to print fractions out rather than just dumping
> them to the console, since the str() of a fraction looks like a
> fraction, but the repr() looks like a constructor call.
>
 Fraction(0.25)
> Fraction(1, 4)
 Fraction(0.1)
> Fraction(3602879701896397, 36028797018963968)
>
> If it looks like the number you put in, it was perfectly
> representable. If it looks like something of roughly that many digits,
> it's probably not the number you started with.

That's pretty, pretty nice.  It was really what I was looking for.

-- 
You're the best ``little lord of local nonsense'' I've ever met! :-D
(Lol.  The guy is kinda stressed out!  Plonk, plonk, plonk.  EOD.)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-06 Thread Hope Rouselle
"Peter J. Holzer"  writes:

> On 2021-09-05 03:38:55 +1200, Greg Ewing wrote:
>> If 7.23 were exactly representable, you would have got
>> 723/1000.
>> 
>> Contrast this with something that *is* exactly representable:
>> 
>> >>> 7.875.as_integer_ratio()
>> (63, 8)
>> 
>> and observe that 7875/1000 == 63/8:
>> 
>> >>> from fractions import Fraction
>> >>> Fraction(7875,1000)
>> Fraction(63, 8)
>> 
>> In general, to find out whether a decimal number is exactly
>> representable in binary, represent it as a ratio of integers
>> where the denominator is a power of 10, reduce that to lowest
>> terms,
>
> ... and check if the denominator is a power of two. If it isn't (e.g.
> 1000 == 2**3 * 5**3) then the number is not exactly representable as a
> binary floating point number.
>
> More generally, if the prime factorization of the denominator only
> contains prime factors which are also prime factors of your base, then
> the number can be exactle represented (unless either the denominator or
> the enumerator get too big). So, for base 10 (2*5), all numbers which
> have only powers of 2 and 5 in the denominator (e.g 1/10 == 1/(2*5),
> 1/8192 == 1/2**13, 1/1024000 == 1/(2**13 * 5**3)) can represented
> exactly, but those with other prime factors (e.g. 1/3, 1/7,
> 1/24576 == 1/(2**13 * 3), 1/1024001 == 1/(11 * 127 * 733)) cannot.
> Similarly, for base 12 (2*2*3) numbers with 2 and 3 in the denominator
> can be represented and for base 60 (2*2*3*5), numbers with 2, 3 and 5.

Very grateful to these paragraphs.  They destroy all the mystery.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-06 Thread Grant Edwards
On 2021-09-05, Peter J. Holzer  wrote:
> On 2021-09-05 03:38:55 +1200, Greg Ewing wrote:
>> If 7.23 were exactly representable, you would have got
>> 723/1000.
>> 
>> Contrast this with something that *is* exactly representable:
>> 
>> >>> 7.875.as_integer_ratio()
>> (63, 8)
>> 
>> and observe that 7875/1000 == 63/8:
>> 
>> >>> from fractions import Fraction
>> >>> Fraction(7875,1000)
>> Fraction(63, 8)
>> 
>> In general, to find out whether a decimal number is exactly
>> representable in binary, represent it as a ratio of integers where
>> the denominator is a power of 10, reduce that to lowest terms,
>
> ... and check if the denominator is a power of two. If it isn't
> (e.g.  1000 == 2**3 * 5**3) then the number is not exactly
> representable as a binary floating point number.
>
> More generally, if the prime factorization of the denominator only
> contains prime factors which are also prime factors of your base,
> then the number can be exactle represented (unless either the
> denominator or the enumerator get too big).

And once you understand that, ignore it and write code under the
assumumption that nothing can be exactly represented in floating
point.

If you like, you can assume that 0 can be exactly represented without
getting into too much trouble as long as it's a literal constant value
and not the result of any run-time FP operations.

If you want to live dangerously, you can assume that integers with
magnitude less than a million can be exactly represented. That
assumption is true for all the FP representations I've ever used, but
once you start depending on it, you're one stumble from the edge of
the cliff.

--
Grant




-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-06 Thread Dennis Lee Bieber
On Sat, 04 Sep 2021 10:40:35 -0300, Hope Rouselle 
declaimed the following:

>course, I don't even have floats to worry about.)  If I'm given 1.17,
>say, I am not confident that I could turn this number into 117 by
>multiplying it by 100.  And that was the question.  Can I always
>multiply such IEEE 754 dollar amounts by 100?
>

HOW are you "given" that 1.17? If that is coming from some
user-readable source (keyboard entry, text-based file [CSV/TSV, even SYLK])
you do NOT have a number -- you have a string, which needs to be converted
by some algorithm.

For money, the best solution, again, is to use the Decimal module and
feed the /string/ to the initialization call. If you want to do it
yourself, to get a scaled integer, you will have to code a
parser/converter.

*   strip extraneous punctuation ($, etc -- but not comma, decimal
point, or + and -)
*   strip any grouping separators (commas, but beware, some 
countries
group using a period -- "1.234,56" vs "1,234.56"). "1,234.56" => "1234.56"
*   ensure there is a decimal point (again, you may have to convert 
a
comma to decimal point), if not append a "." to the input
*   append enough 0s to the end to ensure you have whatever scale
factor you are using behind the decimal point (as mentioned M$ Excel money
type uses four places) "1234.56" => "1234.5600"
*   remove the decimal marker. "1234.5600" => "12345600"
*   convert to native integer. int("12345600") => 12345600 [as 
integer]
{may fail if +/- are not in the required position for Python}

If the number is coming from some binary file format, it is already too
late. And you might need to study any DBMS being used. Some transfer values
as text strings, and reconvert to DBMS numeric types on receipt. Make sure
the DBMS is using a decimal number type and not a floating type for the
field (which leaves out SQLite3  which will store anything in any field,
but uses some slightly obscure logic to determine what conversion is done)


-- 
Wulfraed Dennis Lee Bieber AF6VN
wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-05 Thread Richard Damon


> On Sep 5, 2021, at 6:22 PM, Peter J. Holzer  wrote:
> 
> On 2021-09-04 10:01:23 -0400, Richard Damon wrote:
>>> On 9/4/21 9:40 AM, Hope Rouselle wrote:
>>> Hm, I think I see what you're saying.  You're saying multiplication and
>>> division in IEEE 754 is perfectly safe --- so long as the numbers you
>>> start with are accurately representable in IEEE 754 and assuming no
>>> overflow or underflow would occur.  (Addition and subtraction are not
>>> safe.)
>>> 
>> 
>> Addition and Subtraction are just as safe, as long as you stay within
>> the precision limits.
> 
> That depends a lot on what you call "safe", 
> 
> a * b / a will always be very close to b (unless there's an over- or
> underflow), but a + b - a can be quite different from b.
> 
> In general when analyzing a numerical algorithm you have to pay a lot
> more attention to addition and subtraction than to multiplication and
> division.
> 
>hp
> 
> -- 
Yes, it depends on your definition of safe. If ‘close’ is good enough then 
multiplication is probably safer as the problems are in more extreme cases. If 
EXACT is the question, addition tends to be better. To have any chance, the 
numbers need to be somewhat low ‘precision’, which means the need to avoid 
arbitrary decimals. Once past that, as long as the numbers are of roughly the 
same magnitude, and are the sort of numbers you are apt to just write, you can 
tend to add a lot of them before you get enough bits to accumulate to have a 
problem. With multiplication, every multiply roughly adds the number of bits of 
precision, so you quickly run out, and one divide will have a chance to just 
end the process.

Remember, the question came up because the sum was’t associative because of 
fractional bits. That points to thinking of exact operations, and addition does 
better at that.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-05 Thread Peter J. Holzer
On 2021-09-04 10:01:23 -0400, Richard Damon wrote:
> On 9/4/21 9:40 AM, Hope Rouselle wrote:
> > Hm, I think I see what you're saying.  You're saying multiplication and
> > division in IEEE 754 is perfectly safe --- so long as the numbers you
> > start with are accurately representable in IEEE 754 and assuming no
> > overflow or underflow would occur.  (Addition and subtraction are not
> > safe.)
> > 
> 
> Addition and Subtraction are just as safe, as long as you stay within
> the precision limits.

That depends a lot on what you call "safe", 

a * b / a will always be very close to b (unless there's an over- or
underflow), but a + b - a can be quite different from b.

In general when analyzing a numerical algorithm you have to pay a lot
more attention to addition and subtraction than to multiplication and
division.

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-05 Thread Peter J. Holzer
On 2021-09-05 03:38:55 +1200, Greg Ewing wrote:
> If 7.23 were exactly representable, you would have got
> 723/1000.
> 
> Contrast this with something that *is* exactly representable:
> 
> >>> 7.875.as_integer_ratio()
> (63, 8)
> 
> and observe that 7875/1000 == 63/8:
> 
> >>> from fractions import Fraction
> >>> Fraction(7875,1000)
> Fraction(63, 8)
> 
> In general, to find out whether a decimal number is exactly
> representable in binary, represent it as a ratio of integers
> where the denominator is a power of 10, reduce that to lowest
> terms,

... and check if the denominator is a power of two. If it isn't (e.g.
1000 == 2**3 * 5**3) then the number is not exactly representable as a
binary floating point number.

More generally, if the prime factorization of the denominator only
contains prime factors which are also prime factors of your base, then
the number can be exactle represented (unless either the denominator or
the enumerator get too big). So, for base 10 (2*5), all numbers which
have only powers of 2 and 5 in the denominator (e.g 1/10 == 1/(2*5),
1/8192 == 1/2**13, 1/1024000 == 1/(2**13 * 5**3)) can represented
exactly, but those with other prime factors (e.g. 1/3, 1/7,
1/24576 == 1/(2**13 * 3), 1/1024001 == 1/(11 * 127 * 733)) cannot.
Similarly, for base 12 (2*2*3) numbers with 2 and 3 in the denominator
can be represented and for base 60 (2*2*3*5), numbers with 2, 3 and 5.

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-05 Thread Peter J. Holzer
On 2021-09-04 09:48:40 -0300, Hope Rouselle wrote:
> Christian Gollwitzer  writes:
> > Am 02.09.21 um 15:51 schrieb Hope Rouselle:
> >>>>> ls = [7.23, 8.41, 6.15, 2.31, 7.73, 7.77]
> >>>>> sum(ls)
> >> 39.594
> >> 
> >>>>> ls = [8.41, 6.15, 2.31, 7.73, 7.77, 7.23]
> >>>>> sum(ls)
> >> 39.61
> >> All I did was to take the first number, 7.23, and move it to the
> >> last
> >> position in the list.  (So we have a violation of the commutativity of
> >> addition.)
> >
> > I believe it is not commutativity, but associativity, that is
> > violated. 

I agree.


> Shall we take this seriously?  (I will disagree, but that doesn't mean I
> am not grateful for your post.  Quite the contary.)  It in general
> violates associativity too, but the example above couldn't be referring
> to associativity because the second sum above could not be obtained from
> associativity alone.  Commutativity is required, applied to five pairs
> of numbers.  How can I go from
> 
>   7.23 + 8.41 + 6.15 + 2.31 + 7.73 + 7.77
> 
> to 
> 
>   8.41 + 6.15 + 2.31 + 7.73 + 7.77 + 7.23?

Simple:

>>> 7.23 + 8.41 + 6.15 + 2.31 + 7.73 + 7.77
39.594
>>> 7.23 + (8.41 + 6.15 + 2.31 + 7.73 + 7.77)
39.61

Due to commutativity, this is the same as

>>> (8.41 + 6.15 + 2.31 + 7.73 + 7.77) + 7.23
39.61

So commutativity is preserved but associativity is lost. (Of course a
single example doesn't prove that this is always the case, but it can be
seen from the guarantees that IEEE-754 arithmetic gives you that this is
actually the case).

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-04 Thread Chris Angelico
On Sun, Sep 5, 2021 at 12:58 PM Greg Ewing  wrote:
>
> On 5/09/21 2:42 am, Hope Rouselle wrote:
> > Here's what I did on this case.  The REPL is telling me that
> >
> >7.23 = 2035064081618043/281474976710656
>
> If 7.23 were exactly representable, you would have got
> 723/1000.
>
> Contrast this with something that *is* exactly representable:
>
>  >>> 7.875.as_integer_ratio()
> (63, 8)
>
> and observe that 7875/1000 == 63/8:
>
>  >>> from fractions import Fraction
>  >>> Fraction(7875,1000)
> Fraction(63, 8)
>
> In general, to find out whether a decimal number is exactly
> representable in binary, represent it as a ratio of integers
> where the denominator is a power of 10, reduce that to lowest
> terms, and compare with the result of as_integer_ratio().
>

Or let Python do that work for you!

>>> from fractions import Fraction
>>> Fraction("7.875") == Fraction(7.875)
True
>>> Fraction("7.8") == Fraction(7.8)
False

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-04 Thread Chris Angelico
On Sun, Sep 5, 2021 at 12:55 PM Hope Rouselle  wrote:
>
> Julio Di Egidio  writes:
>
> > On Thursday, 2 September 2021 at 16:51:24 UTC+2, Christian Gollwitzer wrote:
> >> Am 02.09.21 um 16:49 schrieb Julio Di Egidio:
> >> > On Thursday, 2 September 2021 at 16:41:38 UTC+2, Peter Pearson wrote:
> >> >> On Thu, 02 Sep 2021 10:51:03 -0300, Hope Rouselle wrote:
> >> >
> >> >>> 39.61
> >> >>
> >> >> Welcome to the exciting world of roundoff error:
> >> >
> >> > Welcome to the exiting world of Usenet.
> >> >
> >> > *Plonk*
> >>
> >> Pretty harsh, isn't it? He gave a concise example of the same inaccuracy
> >> right afterwards.
> >
> > And I thought you were not seeing my posts...
> >
> > Given that I have already given a full explanation, you guys, that you
> > realise it or not, are simply adding noise for the usual pub-level
> > discussion I must most charitably guess.
> >
> > Anyway, just my opinion.  (EOD.)
>
> Which is certainly appreciated --- as a rule.  Pub-level noise is pretty
> much unavoidable in investigation, education.  Being wrong is, too,
> unavoidable in investigation, education.  There is a point we eventually
> publish at the most respected journals, but that's a whole other
> interval of the time-line.  IOW, chill out! :-D (Give us a C-k and meet
> us up in the next thread.  Oh, my, you're not a Gnus user: you are a
> G2/1.0 user.  That's pretty scary.)
>

I'm not a fan of the noise level in a pub, but I have absolutely no
problem with arguing these points out. And everyone (mostly) in this
thread is being respectful. I don't mind when someone else is wrong,
especially since - a lot of the time - I'm wrong too (or maybe I'm the
only one who's wrong).

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-04 Thread Chris Angelico
On Sun, Sep 5, 2021 at 12:44 PM Hope Rouselle  wrote:
>
> Chris Angelico  writes:
>
> > On Fri, Sep 3, 2021 at 4:29 AM Hope Rouselle  wrote:
> >>
> >> Just sharing a case of floating-point numbers.  Nothing needed to be
> >> solved or to be figured out.  Just bringing up conversation.
> >>
> >> (*) An introduction to me
> >>
> >> I don't understand floating-point numbers from the inside out, but I do
> >> know how to work with base 2 and scientific notation.  So the idea of
> >> expressing a number as
> >>
> >>   mantissa * base^{power}
> >>
> >> is not foreign to me. (If that helps you to perhaps instruct me on
> >> what's going on here.)
> >>
> >> (*) A presentation of the behavior
> >>
> >> >>> import sys
> >> >>> sys.version
> >> '3.8.10 (tags/v3.8.10:3d8993a, May 3 2021, 11:48:03) [MSC v.1928 64
> >> bit (AMD64)]'
> >>
> >> >>> ls = [7.23, 8.41, 6.15, 2.31, 7.73, 7.77]
> >> >>> sum(ls)
> >> 39.594
> >>
> >> >>> ls = [8.41, 6.15, 2.31, 7.73, 7.77, 7.23]
> >> >>> sum(ls)
> >> 39.61
> >>
> >> All I did was to take the first number, 7.23, and move it to the last
> >> position in the list.  (So we have a violation of the commutativity of
> >> addition.)
> >
> > It's not about the commutativity of any particular pair of operands -
> > that's always guaranteed.
>
> Shall we take this seriously?  It has to be about the commutativity of
> at least one particular pair because it is involved with the
> commutavitity of a set of pairs.  If various pairs are involved, then at
> least one is involved.  IOW, it is about the commutativity of some pair
> of operands and so it could not be the case that it's not about the
> commutativity of any.  (Lol.  I hope that's not too insubordinate.  I
> already protested against a claim for associativity in this thread and
> now I'm going for the king of the hill, for whom I have always been so
> grateful!)

No, that is not the case. Look at the specific pairs of numbers that get added.

ls = [7.23, 8.41, 6.15, 2.31, 7.73, 7.77]

>>> 7.23 + 8.41
15.64
>>> _ + 6.15
21.79
>>> _ + 2.31
24.098
>>> _ + 7.73
31.83
>>> _ + 7.77
39.594

And with the other list:

ls = [8.41, 6.15, 2.31, 7.73, 7.77, 7.23]

>>> 8.41 + 6.15
14.56
>>> _ + 2.31
16.87
>>> _ + 7.73
24.6
>>> _ + 7.77
32.375
>>> _ + 7.23
39.61

If commutativity is being violated, then there should be some
situation where you could have written "7.73 + _" instead of "_ +
7.73" or equivalent, and gotten a different result. But that is simply
not the case. What you are seeing is NOT commutativity, but the
consequences of internal rounding, which is a matter of associativity.

> Alright.  Thanks so much for this example.  Here's a new puzzle for me.
> The REPL makes me think that both 21.79 and 2.31 *are* representable
> exactly in Python's floating-point datatype because I see:
>
> >>> 2.31
> 2.31
> >>> 21.79
> 21.79
>
> When I add them, the result obtained makes me think that the sum is
> *not* representable exactly in Python's floating-point number:
>
> >>> 21.79 + 2.31
> 24.098
>
> However, when I type 24.10 explicitly, the REPL makes me think that
> 24.10 *is* representable exactly:
>
> >>> 24.10
> 24.1
>
> I suppose I cannot trust the appearance of the representation?  What's
> really going on there?  (Perhaps the trouble appears while Python is
> computing the sum of the numbers 21.79 and 2.31?)  Thanks so much!

The representation is a conversion from the internal format into
decimal digits. It is rounded for convenience of display, because you
don't want it to look like this:

>>> print(Fraction(24.10))
3391773469363405/140737488355328

Since that's useless, the repr of a float rounds it to the shortest
plausible number as represented in decimal digits. This has nothing to
do with whether it is exactly representable, and everything to do with
displaying things usefully in as many situations as possible :)

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-04 Thread Chris Angelico
On Sun, Sep 5, 2021 at 1:04 PM Hope Rouselle  wrote:
> The same question in other words --- what's a trivial way for the REPL
> to show me such cycles occur?
>
> >> 7.23.as_integer_ratio()
> >>> (2035064081618043, 281474976710656)
>
> Here's what I did on this case.  The REPL is telling me that
>
>   7.23 = 2035064081618043/281474976710656
>
> If that were true, then 7.23 * 281474976710656 would have to equal
> 2035064081618043.  So I typed:
>
> >>> 7.23 * 281474976710656
> 2035064081618043.0
>
> That agrees with the falsehood.  I'm getting no evidence of the problem.
>
> When take control of my life out of the hands of misleading computers, I
> calculate the sum:
>
>844424930131968
>  +5629499534213120
> 197032483697459200
> ==
> 203506408161804288
> =/= 203506408161804300
>
> How I can save the energy spent on manual verification?
>

What you've stumbled upon here is actually a neat elegance of
floating-point, and an often-forgotten fundamental of it: rounding
occurs exactly the same regardless of the scale. The number 7.23 is
represented with a certain mantissa, and multiplying it by some power
of two doesn't change the mantissa, only the exponent. So the rounding
happens exactly the same, and it comes out looking equal!

The easiest way, in Python, to probe this sort of thing is to use
either fractions.Fraction or decimal.Decimal. I prefer Fraction, since
a float is fundamentally a rational number, and you can easily see
what's happening. You can construct a Fraction from a string, and
it'll do what you would expect; or you can construct one from a float,
and it'll show you what that float truly represents.

It's often cleanest to print fractions out rather than just dumping
them to the console, since the str() of a fraction looks like a
fraction, but the repr() looks like a constructor call.

>>> Fraction(0.25)
Fraction(1, 4)
>>> Fraction(0.1)
Fraction(3602879701896397, 36028797018963968)

If it looks like the number you put in, it was perfectly
representable. If it looks like something of roughly that many digits,
it's probably not the number you started with.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-04 Thread Chris Angelico
On Sun, Sep 5, 2021 at 12:50 PM Hope Rouselle  wrote:
>
> Christian Gollwitzer  writes:
>
> > Am 02.09.21 um 15:51 schrieb Hope Rouselle:
> >> Just sharing a case of floating-point numbers.  Nothing needed to be
> >> solved or to be figured out.  Just bringing up conversation.
> >> (*) An introduction to me
> >> I don't understand floating-point numbers from the inside out, but I
> >> do
> >> know how to work with base 2 and scientific notation.  So the idea of
> >> expressing a number as
> >>mantissa * base^{power}
> >> is not foreign to me. (If that helps you to perhaps instruct me on
> >> what's going on here.)
> >> (*) A presentation of the behavior
> >>
> >>>>> import sys
> >>>>> sys.version
> >> '3.8.10 (tags/v3.8.10:3d8993a, May 3 2021, 11:48:03) [MSC v.1928 64
> >> bit (AMD64)]'
> >>
> >>>>> ls = [7.23, 8.41, 6.15, 2.31, 7.73, 7.77]
> >>>>> sum(ls)
> >> 39.594
> >>
> >>>>> ls = [8.41, 6.15, 2.31, 7.73, 7.77, 7.23]
> >>>>> sum(ls)
> >> 39.61
> >> All I did was to take the first number, 7.23, and move it to the
> >> last
> >> position in the list.  (So we have a violation of the commutativity of
> >> addition.)
> >
> > I believe it is not commutativity, but associativity, that is
> > violated.
>
> Shall we take this seriously?  (I will disagree, but that doesn't mean I
> am not grateful for your post.  Quite the contary.)  It in general
> violates associativity too, but the example above couldn't be referring
> to associativity because the second sum above could not be obtained from
> associativity alone.  Commutativity is required, applied to five pairs
> of numbers.  How can I go from
>
>   7.23 + 8.41 + 6.15 + 2.31 + 7.73 + 7.77
>
> to
>
>   8.41 + 6.15 + 2.31 + 7.73 + 7.77 + 7.23?
>
> Perhaps only through various application of commutativity, namely the
> ones below. (I omit the parentheses for less typing.  I suppose that
> does not create much trouble.  There is no use of associativity below,
> except for the intented omission of parentheses.)
>
>  7.23 + 8.41 + 6.15 + 2.31 + 7.73 + 7.77
>= 8.41 + 7.23 + 6.15 + 2.31 + 7.73 + 7.77
>    = 8.41 + 6.15 + 7.23 + 2.31 + 7.73 + 7.77
>= 8.41 + 6.15 + 2.31 + 7.23 + 7.73 + 7.77
>= 8.41 + 6.15 + 2.31 + 7.73 + 7.23 + 7.77
>= 8.41 + 6.15 + 2.31 + 7.73 + 7.77 + 7.23.
>

Show me the pairs of numbers. You'll find that they are not the same
numbers. Commutativity is specifically that a+b == b+a and you won't
find any situation where that is violated.

As soon as you go to three or more numbers, what you're doing is
changing which numbers get added first, which is this:

a + (b + c) != (a + b) + c

and this can most certainly be violated due to intermediate rounding.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-04 Thread Chris Angelico
On Sun, Sep 5, 2021 at 12:48 PM Hope Rouselle  wrote:
>
> Chris Angelico  writes:
>
> > On Fri, Sep 3, 2021 at 4:58 AM Hope Rouselle  wrote:
> >>
> >> Hope Rouselle  writes:
> >>
> >> > Just sharing a case of floating-point numbers.  Nothing needed to be
> >> > solved or to be figured out.  Just bringing up conversation.
> >> >
> >> > (*) An introduction to me
> >> >
> >> > I don't understand floating-point numbers from the inside out, but I do
> >> > know how to work with base 2 and scientific notation.  So the idea of
> >> > expressing a number as
> >> >
> >> >   mantissa * base^{power}
> >> >
> >> > is not foreign to me. (If that helps you to perhaps instruct me on
> >> > what's going on here.)
> >> >
> >> > (*) A presentation of the behavior
> >> >
> >> >>>> import sys
> >> >>>> sys.version
> >> > '3.8.10 (tags/v3.8.10:3d8993a, May 3 2021, 11:48:03) [MSC v.1928 64
> >> > bit (AMD64)]'
> >> >
> >> >>>> ls = [7.23, 8.41, 6.15, 2.31, 7.73, 7.77]
> >> >>>> sum(ls)
> >> > 39.594
> >> >
> >> >>>> ls = [8.41, 6.15, 2.31, 7.73, 7.77, 7.23]
> >> >>>> sum(ls)
> >> > 39.61
> >> >
> >> > All I did was to take the first number, 7.23, and move it to the last
> >> > position in the list.  (So we have a violation of the commutativity of
> >> > addition.)
> >>
> >> Suppose these numbers are prices in dollar, never going beyond cents.
> >> Would it be safe to multiply each one of them by 100 and therefore work
> >> with cents only?  For instance
> >
> > Yes and no. It absolutely *is* safe to always work with cents, but to
> > do that, you have to be consistent: ALWAYS work with cents, never with
> > floating point dollars.
> >
> > (Or whatever other unit you choose to use. Most currencies have a
> > smallest-normally-used-unit, with other currency units (where present)
> > being whole number multiples of that minimal unit. Only in forex do
> > you need to concern yourself with fractional cents or fractional yen.)
> >
> > But multiplying a set of floats by 100 won't necessarily solve your
> > problem; you may have already fallen victim to the flaw of assuming
> > that the numbers are represented accurately.
>
> Hang on a second.  I see it's always safe to work with cents, but I'm
> only confident to say that when one gives me cents to start with.  In
> other words, if one gives me integers from the start.  (Because then, of
> course, I don't even have floats to worry about.)  If I'm given 1.17,
> say, I am not confident that I could turn this number into 117 by
> multiplying it by 100.  And that was the question.  Can I always
> multiply such IEEE 754 dollar amounts by 100?
>
> Considering your last paragraph above, I should say: if one gives me an
> accurate floating-point representation, can I assume a multiplication of
> it by 100 remains accurately representable in IEEE 754?

Humans usually won't give you IEEE 754 floats. What they'll usually
give you is a text string. Let's say you ask someone to type in the
prices of various items, the quantities thereof, and the shipping. You
take strings like "1.17" (or "$1.17"), and you parse that into the
integer 117.

> Hm, I think I see what you're saying.  You're saying multiplication and
> division in IEEE 754 is perfectly safe --- so long as the numbers you
> start with are accurately representable in IEEE 754 and assuming no
> overflow or underflow would occur.  (Addition and subtraction are not
> safe.)
>

All operations are equally valid. Anything that causes rounding can
cause loss of data, and that can happen with multiplication/division
as well as addition/subtraction. But yes, with the caveats you give,
everything is safe.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-04 Thread Christian Gollwitzer

Am 04.09.21 um 14:48 schrieb Hope Rouselle:

Christian Gollwitzer  writes:


Am 02.09.21 um 15:51 schrieb Hope Rouselle:

Just sharing a case of floating-point numbers.  Nothing needed to be
solved or to be figured out.  Just bringing up conversation.
(*) An introduction to me
I don't understand floating-point numbers from the inside out, but I
do
know how to work with base 2 and scientific notation.  So the idea of
expressing a number as
mantissa * base^{power}
is not foreign to me. (If that helps you to perhaps instruct me on
what's going on here.)
(*) A presentation of the behavior


import sys
sys.version

'3.8.10 (tags/v3.8.10:3d8993a, May 3 2021, 11:48:03) [MSC v.1928 64
bit (AMD64)]'


ls = [7.23, 8.41, 6.15, 2.31, 7.73, 7.77]
sum(ls)

39.594


ls = [8.41, 6.15, 2.31, 7.73, 7.77, 7.23]
sum(ls)

39.61
All I did was to take the first number, 7.23, and move it to the
last
position in the list.  (So we have a violation of the commutativity of
addition.)


I believe it is not commutativity, but associativity, that is
violated.


Shall we take this seriously?  (I will disagree, but that doesn't mean I
am not grateful for your post.  Quite the contary.)  It in general
violates associativity too, but the example above couldn't be referring
to associativity because the second sum above could not be obtained from
associativity alone.  Commutativity is required, applied to five pairs
of numbers.  How can I go from

   7.23 + 8.41 + 6.15 + 2.31 + 7.73 + 7.77

to

   8.41 + 6.15 + 2.31 + 7.73 + 7.77 + 7.23?

Perhaps only through various application of commutativity, namely the
ones below. (I omit the parentheses for less typing.  I suppose that
does not create much trouble.  There is no use of associativity below,
except for the intented omission of parentheses.)


With the parens it will become more obvious.



  7.23 + 8.41 + 6.15 + 2.31 + 7.73 + 7.77
= 8.41 + 7.23 + 6.15 + 2.31 + 7.73 + 7.77


The sum is evaluated as

(((7.23 + 8.41) + 6.15 + ...)

For the first shift, you are correct that commutativity will result in

(((8.41 + 7.23) + 6.15 + ...)

But you can't go in one step to

(((8.41 + 6.15) + 7.23 + ...)

with  the commutativity law alone. Instead, a sequence of associativity 
and commutativity is required to move the 7.23 out of the first pair of 
parentheses.


And what I was trying to say, the commutative steps *are* equal in 
floating point arithmetics, whereas the associative steps are not.


Christian

--
https://mail.python.org/mailman/listinfo/python-list


Re: on floating-point numbers

2021-09-04 Thread Hope Rouselle
Christian Gollwitzer  writes:

> Am 04.09.21 um 14:48 schrieb Hope Rouselle:
>> Christian Gollwitzer  writes:
>> 
>>> Am 02.09.21 um 15:51 schrieb Hope Rouselle:
>>>> Just sharing a case of floating-point numbers.  Nothing needed to be
>>>> solved or to be figured out.  Just bringing up conversation.
>>>> (*) An introduction to me
>>>> I don't understand floating-point numbers from the inside out, but I
>>>> do
>>>> know how to work with base 2 and scientific notation.  So the idea of
>>>> expressing a number as
>>>> mantissa * base^{power}
>>>> is not foreign to me. (If that helps you to perhaps instruct me on
>>>> what's going on here.)
>>>> (*) A presentation of the behavior
>>>>
>>>>>>> import sys
>>>>>>> sys.version
>>>> '3.8.10 (tags/v3.8.10:3d8993a, May 3 2021, 11:48:03) [MSC v.1928 64
>>>> bit (AMD64)]'
>>>>
>>>>>>> ls = [7.23, 8.41, 6.15, 2.31, 7.73, 7.77]
>>>>>>> sum(ls)
>>>> 39.594
>>>>
>>>>>>> ls = [8.41, 6.15, 2.31, 7.73, 7.77, 7.23]
>>>>>>> sum(ls)
>>>> 39.61
>>>> All I did was to take the first number, 7.23, and move it to the
>>>> last
>>>> position in the list.  (So we have a violation of the commutativity of
>>>> addition.)
>>>
>>> I believe it is not commutativity, but associativity, that is
>>> violated.
>> Shall we take this seriously?  (I will disagree, but that doesn't
>> mean I
>> am not grateful for your post.  Quite the contary.)  It in general
>> violates associativity too, but the example above couldn't be referring
>> to associativity because the second sum above could not be obtained from
>> associativity alone.  Commutativity is required, applied to five pairs
>> of numbers.  How can I go from
>>7.23 + 8.41 + 6.15 + 2.31 + 7.73 + 7.77
>> to
>>8.41 + 6.15 + 2.31 + 7.73 + 7.77 + 7.23?
>> Perhaps only through various application of commutativity, namely
>> the
>> ones below. (I omit the parentheses for less typing.  I suppose that
>> does not create much trouble.  There is no use of associativity below,
>> except for the intented omission of parentheses.)
>
> With the parens it will become more obvious.
>
>>   7.23 + 8.41 + 6.15 + 2.31 + 7.73 + 7.77
>> = 8.41 + 7.23 + 6.15 + 2.31 + 7.73 + 7.77
>
> The sum is evaluated as
>
>   (((7.23 + 8.41) + 6.15 + ...)
>
> For the first shift, you are correct that commutativity will result in
>
>   (((8.41 + 7.23) + 6.15 + ...)
>
> But you can't go in one step to
>
>   (((8.41 + 6.15) + 7.23 + ...)
>
> with  the commutativity law alone. Instead, a sequence of
> associativity and commutativity is required to move the 7.23 out of
> the first pair of parentheses.
>
> And what I was trying to say, the commutative steps *are* equal in
> floating point arithmetics, whereas the associative steps are not.

Oh, I see it.  Very good point!  Lesson learned.
-- 
https://mail.python.org/mailman/listinfo/python-list


  1   2   3   4   5   6   7   8   9   10   >