From tplate at blackmesacapital.com  Tue Mar  2 17:55:28 2004
From: tplate at blackmesacapital.com (tplate@blackmesacapital.com)
Date: Tue Mar  2 17:55:35 2004
Subject: [Rd] *s behaviour (PR#6633)
Message-ID: <20040302165528.3B78AF271@slim.kubism.ku.dk>

This does appear to be a shortcoming in the '*' code.  If I understand 
Berwin's concerns correctly, here is a simpler example with matrix and 
vector, which should generate a warning, but doesn't, and an example with 
two vectors, which does generate a warning:

 > matrix(1:6,2) * 1:4
      [,1] [,2] [,3]
[1,]    1    9    5
[2,]    4   16   12
 > 1:6 * 1:4
[1]  1  4  9 16  5 12
Warning message:
longer object length
         is not a multiple of shorter object length in: 1:6 * 1:4
 >

The operators "+", "-", "/", "%/%", "^", "&", and "|" behave in a similar 
manner (and switching the arguments does not change the behavior).

In S-plus 6.1, examples of this type stop with an error.

As far as I know, it is standard in the S language for "*" to treat both 
its arguments as vectors (dimension attributes are only used to construct 
the dimension attributes of the returned value). So as Berwin notes, the 
matrix * vector case should generate a warning when the lengths of the 
arguments are not multiples.

The problem appears to be in the functions lbinary() in logic.c and 
R_binary() in arithmetic.c -- length checking is not done at all if either 
x or y is an array.

The fix in arithmetic.c is to move the block of code:
>     if (nx == ny || nx == 1 || ny == 1) mismatch = 0;
>     else if (nx > 0 && ny > 0) {
>         if (nx > ny) mismatch = nx % ny;
>         else mismatch = ny % nx;
>     }
from inside the else block of "if (xarray || yarray) {" to after the end of 
the else (so that it always gets executed) (also, as far as I can see the 
first "if" that sets mismatch=0 is redundant and could be deleted).

The fix in logic.c is to move the block of code:
>         nx = length(x);
>         ny = length(y);
>         if(nx > 0 && ny > 0) {
>             if(nx > ny) mismatch = nx % ny;
>             else mismatch = ny % nx;
>         }
from inside the else block of "if (xarray || yarray) {" to after the end of 
the else (so that it always gets executed).

With these changes (including the deletion of the redundant code) R 1.9.0 
compiled and ran "make tests" with errors only in "running code in 
'reg-tests-3.R'" (which appeared due to not being able to find packages 
MASS and survival) and differences in the internet tests (as expected.)

-- Tony Plate


At Monday 09:57 PM 3/1/2004, berwin@maths.uwa.edu.au wrote:
>Dear all,
>
>While showing some commands of R to my students, I came across the
>following behaviour of * which surprised me.
>
> > set.seed(20)                    # to make it reproducible
>                                   # create some objects
> > z <- matrix(rnorm(6), ncol=2)   # 3x2 matrix
> > x1 <- rnorm(3)                  # vector of length 3
> > y1 <- rnorm(4)                  # vector of length 4
> > y2 <- matrix(y1, ncol=1)        # 4x1 matrix
>
> > z*x1                            # works fine, as expected
>
> > x1*y1                           # warning message, as expected
>[1] 1.60535635 0.01749800 0.06943188 1.81510895
>Warning message:
>longer object length
>         is not a multiple of shorter object length in: x1 * y1
>
> > z*y2                            # also expected
>Error in z * y2 : non-conformable arrays
>
> > z*y1                            # no warning, no error?
>             [,1]        [,2]
>[1,] -0.64591924  0.83703776
>[2,]  0.01179780  0.24808611
>[3,] -0.26850220 -0.01146923
>
> > x1*y2                           # no warning, no error?
>            [,1]
>[1,] 1.60535635
>[2,] 0.01749800
>[3,] 0.06943188
>[4,] 1.81510895
>
>I was expecting warning messages in the last examples.
>
>But after consulting the help page (?*) and the 'R Language
>definition', I am not sure what I should have expected. :)
>
>The help page says that "[t]hese binary operators perform arithmetic
>on vector objects" and "[o]bjects such as arrays [...] can be operated
>on this way provided they are conformable".  The R Language definition
>states "a vector is not the same as a one-dimensional array since the
>latter has a dim attribute of length one, whereas the former has no
>dim attribute".
>
>So technically, I guess, the last two examples are operations between
>a vector object and an array object.  And the help page doesn't seem
>to say anything about this situation.
>
>I have a vague memory that there as been discussion on this subject in
>the (distant?) past, but unfortunately I don't remember what behaviour
>was deemed to be sensible.  I also couldn't find any recent posts
>about this on the bug archives.
>
>Thus, after careful consideration I decided to fill out this bug
>report since I came to the conclusion that for these examples either
>a) both operands should have been treated as a vector objects and a
>    warning message should have been issued; or
>b) the documentation should make it clear that the warning is not
>    issued if one operates on a vector object and an array object.
>
>My apologies if this was already reported and I missed it in the bugs
>archives.
>
>Cheers,
>
>         Berwin
>
>
>
>--please do not edit the information below--
>
>Version:
>  platform = i686-pc-linux-gnu
>  arch = i686
>  os = linux-gnu
>  system = i686, linux-gnu
>  status =
>  major = 1
>  minor = 8.1
>  year = 2003
>  month = 11
>  day = 21
>  language = R
>
>Search Path:
>  .GlobalEnv, package:methods, package:ctest, package:mva, package:modreg, 
> package:nls, package:ts, Autoloads, package:base
>
>______________________________________________
>R-devel@stat.math.ethz.ch mailing list
>https://www.stat.math.ethz.ch/mailman/listinfo/r-devel


[Rd] *s behaviour (PR#6633)
tplate@blackmesacapital.com