Skip to content

prod(numeric(0)) surprise

11 messages · Ben Bolker, Duncan Murdoch, Martin Maechler +5 more

#
It surprised me that prod(numeric(0)) is 1.
I guess if you say (operation(nothing) == identity
element) this makes sense, but ??

    Looking in the code, this makes sense:
basically (s=1; for i=0 to length(x),
multiply s by x[i]) -- which comes out to 1.

   What *should* prod(numeric(0)) produce?
I couldn't find the answer documented anywhere.

   (And how about sum(numeric(0))==0,
which for some reason makes more intuitive sense
to me, but is really exactly the same thing --
consider exp(sum(log(numeric(0)))) ... ?)

   cheers
     Ben Bolker
#
On 1/8/2006 9:24 PM, Ben Bolker wrote:
What value were you expecting, or were you expecting an error?  I can't 
think how any other value could be justified, and throwing an error 
would make a lot of formulas more complicated.
That's a fairly standard mathematical convention, which is presumably 
why sum and prod work that way.

Duncan Murdoch
#
Duncan Murdoch wrote:
OK.  I guess I was expecting NaN/NA (as opposed to an error),
but I take the "this makes everything else more complicated" point.
Should this be documented or is it just too obvious ... ?
(Funny -- I'm willing to take gamma(1)==1 without any argument
or suggestion that it should be documented ...)


   cheers
     Ben
#

        
Ben> Duncan Murdoch wrote:
>> On 1/8/2006 9:24 PM, Ben Bolker wrote:
>> 
    >>> It surprised me that prod(numeric(0)) is 1.  I guess if
    >>> you say (operation(nothing) == identity element) this
    >>> makes sense, but ??
    >> 
    >> 
    >> What value were you expecting, or were you expecting an
    >> error?  I can't think how any other value could be
    >> justified, and throwing an error would make a lot of
    >> formulas more complicated.
    >> 
    >>>
    >> 
    >> 
    >> That's a fairly standard mathematical convention, which
    >> is presumably why sum and prod work that way.
    >> 
    >> Duncan Murdoch

    Ben>    OK.  I guess I was expecting NaN/NA (as opposed to
    Ben> an error), but I take the "this makes everything else
    Ben> more complicated" point.  Should this be documented or
    Ben> is it just too obvious ... ?  (Funny -- I'm willing to
    Ben> take gamma(1)==1 without any argument or suggestion
    Ben> that it should be documented ...)

see?  so it looks to me as if you have finally convinced
yourself that '1' is the most reasonable result.. ;-)

Anyway, I've added a sentence to help(prod)  {which matches
the sentence in help(sum), BTW}.

Martin
#
I'm a little confused. I understand that numeric(0) means an empty
numeric vector, not the number 0 expressed as numeric. As it is now,
prod(numeric(0)) generates something -- a vector of length 1
containing the number 1 -- from nothing. I would have expected

prod(numeric(0)) ==> numeric(0)

this is consistent with

numeric(0) ==> numeric(0)
numeric(0) * 1 ==> numeric(0)
cumprod(numeric(0)) ==> numeric(0)

and, because concatenation occus before function evaluation,

prod(c(numeric(0),1)) ==> prod( c(1) ) ==> 1

I would expect sum() to behave the same way, e.g., sum(numeric(0)) ==>
numeric(0). From below,
I would have expected numeric(0) as the result (numeric(0) is the
result from log(numeric(0)), etc).

Martin (Morgan)


Martin Maechler <maechler at stat.math.ethz.ch> writes:
#
On 1/9/2006 12:40 PM, Martin Morgan wrote:
I think the code below works as I'd expect.  Would you really like the 
last answer to be numeric(0)?

 > x <- 1:10
 > sum(x)
[1] 55
 > sum(x[x>5])
[1] 40
 > sum(x[x>10])
[1] 0

Duncan Murdoch
#
The way to think about it is:

   prod(rep(x,n)) == x^n

and that works for n=0 too.
On 1/9/06, Martin Morgan <mtmorgan at fhcrc.org> wrote:
#
I guess I have to say yes, I'd exepct

x <- 1:10
sum(x[x>10]) ==> numeric(0)

this would be reinforced by recongnizing that numeric(0) is not zero,
but nothing. I guess the summation over an empty set is an empty set,
rather than a set containing the number 0. Certainly these

exp(x[x>10]) ==> numeric(0)
numeric(0) + 1 ==> numeric(0)

would give me pause.


Gabor Grothendieck <ggrothendieck at gmail.com> writes:
Hmm, Not sure what to put in for x and n? do you mean x == numeric(0),
n == 0 (0 copies of an empty set), x == ANY n == numeric(0) (an empty
set of ANYthing), x == numeric(0), n == numeric(0) ? For all of these,
x^n evaluates to numeric(0).

Martin (Morgan)

Duncan Murdoch <murdoch at stats.uwo.ca> writes:
#
On Mon, 9 Jan 2006, Martin Morgan wrote:

            
There are some fairly simple rules in how R does it.  You do need to 
distinguish between functions (binary operators) that map two vectors of 
length n to a vector of length n and functions such as prod and sum that 
map a vector of length n to a vector of length 1.

The output of sum and prod is always of length 1, so sum(numeric(0)) and 
prod(numeric(0)) should be of length 1 (or give an error).  It is 
convenient that sum(c(x,y)) is equal to sum(x)+sum(y) and that 
prod(c(x,y)) is equal to prod(x)*prod(y), which motivates making 
sum(numeric(0)) give 0 and prod(numeric(0)) give 1.

Single argument functions such as exp(numeric(0)) seem fairly obvious: you 
have no numbers and you exponentiate them so you still have no numbers. 
You could also argue based on c() and exp() commuting.

The rules for binary operators are a little less tidy [my fault]. They 
come from the idea that x+1 should always add 1 to each element of x.  If 
you add 1 to each element of numeric(0) you get numeric(0).  The usual 
recycling rule says that the shorter vector should be repeated to make it 
the same length as the longer vector, so this is a wart.  On the other 
hand, you can't recycle a vector of length 0 to have length 1, so the 
usual recycling rule can't be applied here. This also makes matrix 
operations work, at least in the sense of getting 
matrices of the right dimension.

 	-thomas
#
On Jan 9, 2006, at 3:35 PM, Kjetil Halvorsen wrote:

            
No - as Thomas explained very nicely they are a different kind of  
functions. cumXXX are n-to-n length vector functions, whereas prod/ 
sum are n to 1 vector length functions. So R is in fact very  
consistent and Thomas did exactly describe the rules.

Cheers,
Simon