Adding Math.log2 and Math.logn to the core library


#1

In a world of humans and finance, it’s quite common to need base-10
logarithms. (Yay for Math.log10!)

In a world of computers, it’s also quite common to need base-2
logarithms. Ruby only gives you ‘natural’ logarithms in the form of
Math.log. (Bummer.)

It has probably been more than 5 times that I’ve had to look up the
formula to discover than
log-base-n(x) == log-base-whatever(x) / log-base-whatever(n)

I was reminded by it when Martin had to write his own log2 function to
answer my previous question.

Is there any objection to me proposing to add both:
Math.log2(x) - base-2 logarithm
Math.logn(x,n) - base-n logarithm
directly to the core of Ruby?

Ideally they’d be implemented in C, but of course the simple Ruby
implementation is just:
def Math.log2( x ); Math.log( x ) / Math.log( 2 ); end
def Math.logn( x, n ); Math.log( x ) / Math.log( n ); end

Since they’re so simple, I’m almost hesitant to ask for them in
core…except that they’ve cropped up for me again and again, and it
always takes me a while to hunt them down. Languages like Lua thrive
on simplicity of implementation. I think Ruby thrives on the richness
of the immediately-available methods in core and stdlib. I feel these
are common enough to deserve general inclusion.


#2

perhaps it would be wiser to add

def log_(n, x)
log x / log n
end

so that any log base may be used.

or you could just google the formula like any one else who didn’t pay
attention to math class.


#3

On Feb 7, 2007, at 2:50 PM, Phrogz wrote:

Ideally they’d be implemented in C, but of course the simple Ruby
implementation is just:
def Math.log2( x ); Math.log( x ) / Math.log( 2 ); end
def Math.logn( x, n ); Math.log( x ) / Math.log( n ); end

I second the motion.

The log2 function is now in the C math library, so I think it would
easy to add it the Ruby Math library. I would like see log for
arbitrary base added too. But here I would suggest a slightly
different name and argument order:

def Math.logb(b, x); Math.log(x) / Math.log(b); end

This, I believe, would be more in accord with other programming
languages that already offer this function.

Regards, Morton


#4

On 2/8/07, Morton G. removed_email_address@domain.invalid wrote:

easy to add it the Ruby Math library. I would like see log for
And while we’re at it, I’d really like to see log aliased to ln

martin


#5

On Feb 7, 2:57 pm, Keynan P. removed_email_address@domain.invalid wrote:

perhaps it would be wiser to add

def log_(n, x)
log x / log n
end

so that any log base may be used.

Other than changing the order of parameters (which I’m personally
ambivalent about, and would certainly accept this order if that’s how
most other libraries do it) and changing the name to end in an
underscore (which I’m not sure I like), what are you proposing that I
wasn’t? Simply that we ONLY add the log-base-n capability that I
described, without a specific method for log-base-2 calculations?


#6

On Feb 7, 2007, at 6:20 PM, Phrogz wrote:

ambivalent about, and would certainly accept this order if that’s how
most other libraries do it) and changing the name to end in an
underscore (which I’m not sure I like), what are you proposing that I
wasn’t? Simply that we ONLY add the log-base-n capability that I
described, without a specific method for log-base-2 calculations?

Well, I can find examples with the base first or second. Perhaps for
Ruby it would most idiomatic to define log as follows

def Math.log(x, b=Math::E); ... ; end

as the core method with log10 and log2 handled (for performance) as
special cases within this method. Given that, I would still want Math
to implement log10 and log2 methods for convenience.

If we were to go with a two argument log, I prefer the “logb” name to
“logn” because “n” suggests an integer and the base doesn’t have to
be an integer (e.g., it could be Math::E).

Regards, Morton


#7

On Feb 7, 4:07 pm, “Martin DeMello” removed_email_address@domain.invalid wrote:

The log2 function is now in the C math library, so I think it would
easy to add it the Ruby Math library. I would like see log for

And while we’re at it, I’d really like to see log aliased to ln

Thank you, yes. I thought I was the only one for whom “log” implied
base 2 or 10.


#8

On Feb 7, 7:08 pm, Morton G. removed_email_address@domain.invalid wrote:

Well, I can find examples with the base first or second. Perhaps for
Ruby it would most idiomatic to define log as follows

def Math.log(x, b=Math::E); ... ; end

as the core method with log10 and log2 handled (for performance) as
special cases within this method. Given that, I would still want Math
to implement log10 and log2 methods for convenience.

Math.log calls the log in the standard math library, which I suspect
implements the natural log calculation pretty efficiently. If you
make the second parameter the base, you’ll either have to check it
against Math::E and treat it as a special case or do two log
calculations for the natural log case. I don’t like either of those
options.

Eric


#9

Hi,

In message “Re: Adding Math.log2 and Math.logn to the core library.”
on Thu, 8 Feb 2007 09:08:38 +0900, Morton G.
removed_email_address@domain.invalid writes:

|Well, I can find examples with the base first or second. Perhaps for
|Ruby it would most idiomatic to define log as follows
|
| def Math.log(x, b=Math::E); … ; end

1.9 Math.log does work so.

          matz.

#10

On Feb 7, 2007, at 9:00 PM, Eric I. wrote:

Math.log calls the log in the standard math library, which I suspect
implements the natural log calculation pretty efficiently. If you
make the second parameter the base, you’ll either have to check it
against Math::E and treat it as a special case or do two log
calculations for the natural log case. I don’t like either of those
options.

If there’s too much of a performance penalty for this, I would have
no problem with the general case being implemented under a different
name, and I would suggest “logb” – that is,

def Math.logb(x, b=Math::E); ... ; end

My main point is that I think the general case should default its
base to Math::E. If we were to end up with Math.log (alias Math.ln),
Math.log10, Math.log2, and Math.logb (the general case) that would
be fine.

Regards, Morton