Perl Monk, Perl Meditation PerlMonks

### Re: Add numbers in log domain

by salva (Abbot)
 on Jun 04, 2012 at 11:57 UTC ( #974274=note: print w/replies, xml ) Need Help??

well, suppose that x >= y, and that we are using the natural base:
```log(x + y) = log(x * (1 + y/x)) = log(x) + log(1 + y/x)

y/x = exp(log(y/x)) = exp(log(y) - log(x))

log(x + y) = log(x) + log(1 + exp(log(y) - log(x)))

And that formula can be easily calculated using regular perl scalars because log(y) - log(x) is in [-log(x), 0] and exp(log(y) - log(x)) is in (0, 1].

Replies are listed 'Best First'.
Re^2: Add numbers in log domain
by BrowserUk (Pope) on Jun 04, 2012 at 12:47 UTC

Spot on! (Though you do need to know the arbitrary base B):

```sub log2p5{ log( \$_[0] ) / log( 2.5 ) };;

\$X = log2p5( 10 );
\$Y = log2p5( 15 );
\$Z = log2p5( 10 + 15 );
print \$X, \$Y, \$Z;;
2.51294159473206 2.95544864408182 3.51294159473206

print 2.51294159473206 + log2p5( 1 + 2.5**( 2.95544864408182 - 2.51294
+159473206 ) );;
3.51294159473206

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

The start of some sanity?

yes, but it is easy to convert from any base to natural, perform the computation and then convert back to the original base.
Re^2: Add numbers in log domain
by ambrus (Abbot) on Jun 04, 2012 at 12:34 UTC

Yes, something like that should work. Take the Math::Libm module, and use the expm1 and log1p functions for this. I won't figure out the correct formula now.

Update 2012-06-10: though this won't help OP, future people who stumble this question by searching might want to look at the Math::BigApprox module.

Re^2: Add numbers in log domain
by pRaNaV (Novice) on Jun 05, 2012 at 07:20 UTC

Thanks! That will save one exponentiation step. Earlier I had to do base^x, base^y, now only one exponentiation step is required (exp(log(y) - log(x))). Btw, range for log(y) - log(x) is (-inf 0]

As I came to learn from another source where they CREATE log table for this particular problem (function logmath_init() in http://cmusphinx.svn.sourceforge.net/viewvc/cmusphinx/trunk/sphinxbase/src/libsphinxbase/util/logmath.c?revision=11275&view=markup)

It's like this - first set (log(y) - log(x)) = 0; then compute base^(1 + exp(log(y) - log(x))

then decrement log(y) - log(x) by 1 (equivalent to dividing by base) and recomputing base^(1 + exp(log(y) - log(x))

this is done untill we reach the MOST negative number. Using this table one can back-compute any log(x+y) for that particular base.

Create A New User
Node Status?
node history
Node Type: note [id://974274]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (9)
As of 2018-06-18 18:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
Should cpanminus be part of the standard Perl release?

Results (110 votes). Check out past polls.

Notices?