Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: appengine/findit/libs/math/logarithms.py

Issue 2543333002: Added log-domain summation (Closed)
Patch Set: removing todos Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
Martin Barbella 2016/12/02 20:07:02 Please run gpylint on these files.
wrengr 2016/12/02 21:00:58 Done.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import math
6
7 _LOG_ZERO = float('-inf')
8
9 def logsumexp(xs):
10 """Efficiently and accurately compute a log-domain sum.
11
12 While ``math.log(math.fsum(math.exp(x) for x in xs)))`` accomplishes
13 the same end, it requires an additional ``len(xs) - 2`` logarithms
14 and introduces more opportunities for over/underflow and rounding
15 errors. Thus, this function is both more efficient and more accurate.
16
17 Args:
18 xs (collection of float): the collection of log-domain numbers to be
19 summed. The order of the elements doesn't matter, nor does the
20 concrete type of the collection (it could be ``list``, ``set``,
21 ``frozenset``, etc); the collection just needs to support ``len``,
22 ``max``, and ``iter``. Because we need the maximum before we
23 can start the iteration, this function requires (in principle)
24 two passes over the data; therefore we cannot take an iterator nor
25 generator. The length should be computed in constant time (else it
26 will introduce an unnecessary third pass over the data). Ideally
27 the maximum can also be computed in constant time (in which case
28 this function only needs to pass over the data once), though none
29 of Python's builtin types support that.
30
31 Returns:
32 The log-domain sum of ``xs``.
33 """
34 if not xs:
35 return _LOG_ZERO
36
37 maximum = max(xs)
38 if math.isinf(maximum):
39 return maximum
40
41 total = math.fsum(math.expm1(x - maximum) for x in xs)
42 return maximum + math.log1p(total + float(len(xs) - 1))
OLDNEW
« no previous file with comments | « no previous file | appengine/findit/libs/math/test/logarithms_test.py » ('j') | appengine/findit/libs/math/test/logarithms_test.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698