This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author steven.daprano
Recipients cheryl.sabella, cool-RR, koobs, mark.dickinson, martin.panter, python-dev, rhettinger, steven.daprano, vstinner
Date 2019-03-28.23:37:04
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <20190328233658.GM31406@ando.pearwood.info>
In-reply-to <1553451861.52.0.943199842847.issue27181@roundup.psfhosted.org>
Content
> In the spirit of "perfect is the enemy of good", would it be 
> reasonable to start with a simple, fast implementation using 
> exp-mean-log?  Then if someone wants to make it more accurate later, 
> they can do so.

I think that is a reasonable idea. On the basis that something is better 
than nothing, go ahead. We can discuss accuracy and speed issues later.

Getting some tricky cases down for reference:

# older (removed) implementation
py> geometric_mean([7]*2)
7.0
py> geometric_mean([7]*15)
7.0

# Raymond's newer (faster) implementation
py> exp(fmean(map(log, [7]*2)))
6.999999999999999
py> exp(fmean(map(log, [7]*15)))
6.999999999999999

py> geometric_mean([3,27])
9.0
py> geometric_mean([3,27]*5)
9.0

py> exp(fmean(map(log, [3,27])))
9.000000000000002
py> exp(fmean(map(log, [3,27]*5)))
8.999999999999998

py> x = 2.5e15
py> geometric_mean([x]*100)
2500000000000000.0
py> exp(fmean(map(log, [x]*100)))
2499999999999999.5

On the other hand, sometimes rounding errors work in our favour:

py> geometric_mean([1e50, 1e-50])  # people might expect 1.0
0.9999999999999998
py> 1e-50 == 1/(1e50)  # even though they aren't quite inverses
False

py> exp(fmean(map(log, [1e50, 1e-50])))
1.0
History
Date User Action Args
2019-03-28 23:37:04steven.dapranosetrecipients: + steven.daprano, rhettinger, mark.dickinson, vstinner, cool-RR, python-dev, martin.panter, koobs, cheryl.sabella
2019-03-28 23:37:04steven.dapranolinkissue27181 messages
2019-03-28 23:37:04steven.dapranocreate