diag(-1) produces weird result

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

diag(-1) produces weird result

William Revelle
Dear list

A strange bug in the psych package is due to the behavior of the diag function:

It gives the expected values for 1, a vector (-1,1), but not for -1

Is this a known feature?


> diag(1)
     [,1]
[1,]    1
> diag(c(-1,1))
     [,1] [,2]
[1,]   -1    0
[2,]    0    1
> diag(-1)
Error in diag(-1) : invalid 'nrow' value (< 0)


Bill


William Revelle   personality-project.org/revelle.html
Professor          personality-project.org
Department of Psychology www.wcas.northwestern.edu/psych/
Northwestern University   www.northwestern.edu/
Use R for psychology         personality-project.org/r
It is 2   minutes to midnight   www.thebulletin.org

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: diag(-1) produces weird result

Duncan Murdoch-2
On 17/09/2018 12:14 PM, William Revelle wrote:
> Dear list
>
> A strange bug in the psych package is due to the behavior of the diag function:
>
> It gives the expected values for 1, a vector (-1,1), but not for -1
>
> Is this a known feature?

It is pretty clearly documented:

"diag has four distinct usages:

...

3.  x is a scalar (length-one vector) and the only argument, it returns
a square identity matrix of size given by the scalar."

Duncan Murdoch

>
>
>> diag(1)
>       [,1]
> [1,]    1
>> diag(c(-1,1))
>       [,1] [,2]
> [1,]   -1    0
> [2,]    0    1
>> diag(-1)
> Error in diag(-1) : invalid 'nrow' value (< 0)
>
>
> Bill
>
>
> William Revelle   personality-project.org/revelle.html
> Professor          personality-project.org
> Department of Psychology www.wcas.northwestern.edu/psych/
> Northwestern University   www.northwestern.edu/
> Use R for psychology         personality-project.org/r
> It is 2   minutes to midnight   www.thebulletin.org
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: diag(-1) produces weird result

Gábor Csárdi
In reply to this post by William Revelle
I would say it is a mis-feature. If the 'x' argument of diag() is a
vector of length 1, then it creates an identity matrix of that size,
instead of creating a 1x1 matrix with the given value:

❯ diag(3)
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    1    0
[3,]    0    0    1

Of course this makes it cumbersome to use diag() in a package, when
you are not sure if the input vector is longer than 1. This seems to
be a good workaround:

❯ diag(-1, nrow = 1)
     [,1]
[1,]   -1

Or, in general if you have vector v:

❯ v <- -1
❯ diag(v, nrow = length(v))
     [,1]
[1,]   -1

Gabor
On Mon, Sep 17, 2018 at 5:14 PM William Revelle <[hidden email]> wrote:

>
> Dear list
>
> A strange bug in the psych package is due to the behavior of the diag function:
>
> It gives the expected values for 1, a vector (-1,1), but not for -1
>
> Is this a known feature?
>
>
> > diag(1)
>      [,1]
> [1,]    1
> > diag(c(-1,1))
>      [,1] [,2]
> [1,]   -1    0
> [2,]    0    1
> > diag(-1)
> Error in diag(-1) : invalid 'nrow' value (< 0)
>
>
> Bill
>
>
> William Revelle            personality-project.org/revelle.html
> Professor                                 personality-project.org
> Department of Psychology www.wcas.northwestern.edu/psych/
> Northwestern University    www.northwestern.edu/
> Use R for psychology         personality-project.org/r
> It is 2   minutes to midnight   www.thebulletin.org
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: diag(-1) produces weird result

barry rowlingson
In reply to this post by William Revelle
On Mon, Sep 17, 2018 at 5:22 PM, Gábor Csárdi <[hidden email]>
wrote:

> I would say it is a mis-feature. If the 'x' argument of diag() is a
> vector of length 1, then it creates an identity matrix of that size,
> instead of creating a 1x1 matrix with the given value:
>
> ❯ diag(3)
>      [,1] [,2] [,3]
> [1,]    1    0    0
> [2,]    0    1    0
> [3,]    0    0    1
>
> Of course this makes it cumbersome to use diag() in a package, when
> you are not sure if the input vector is longer than 1. This seems to
> be a good workaround:
>
> ❯ diag(-1, nrow = 1)
>      [,1]
> [1,]   -1
>
> Or, in general if you have vector v:
>
> ❯ v <- -1
> ❯ diag(v, nrow = length(v))
>      [,1]
> [1,]   -1
> >
>

Anyone else getting deja-vu with the `sample` function?

 > sample(5:3)
 [1] 3 5 4

ok...

 > sample(5:4)
 [1] 4 5

fine...

 > sample(5:5)
 [1] 3 1 5 2 4

uh oh. Documented, of course.

B

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: diag(-1) produces weird result

Ravi Varadhan-2
In reply to this post by Gábor Csárdi
It behaves as per documentation.


" Using diag(x) can have unexpected effects if x is a vector that could be of length one. Use diag(x, nrow = length(x)) for consistent behavior."


Ravi


________________________________
From: R-devel <[hidden email]> on behalf of Gábor Csárdi <[hidden email]>
Sent: Monday, September 17, 2018 12:22:31 PM
To: [hidden email]
Cc: r-devel
Subject: Re: [Rd] diag(-1) produces weird result


I would say it is a mis-feature. If the 'x' argument of diag() is a
vector of length 1, then it creates an identity matrix of that size,
instead of creating a 1x1 matrix with the given value:

❯ diag(3)
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    1    0
[3,]    0    0    1

Of course this makes it cumbersome to use diag() in a package, when
you are not sure if the input vector is longer than 1. This seems to
be a good workaround:

❯ diag(-1, nrow = 1)
     [,1]
[1,]   -1

Or, in general if you have vector v:

❯ v <- -1
❯ diag(v, nrow = length(v))
     [,1]
[1,]   -1

Gabor
On Mon, Sep 17, 2018 at 5:14 PM William Revelle <[hidden email]> wrote:

>
> Dear list
>
> A strange bug in the psych package is due to the behavior of the diag function:
>
> It gives the expected values for 1, a vector (-1,1), but not for -1
>
> Is this a known feature?
>
>
> > diag(1)
>      [,1]
> [1,]    1
> > diag(c(-1,1))
>      [,1] [,2]
> [1,]   -1    0
> [2,]    0    1
> > diag(-1)
> Error in diag(-1) : invalid 'nrow' value (< 0)
>
>
> Bill
>
>
> William Revelle            personality-project.org/revelle.html
> Professor                                 personality-project.org
> Department of Psychology www.wcas.northwestern.edu/psych/<http://www.wcas.northwestern.edu/psych/>
> Northwestern University    www.northwestern.edu/<http://www.northwestern.edu/>
> Use R for psychology         personality-project.org/r
> It is 2   minutes to midnight   www.thebulletin.org<http://www.thebulletin.org>
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: diag(-1) produces weird result

Peter Dalgaard-2
In reply to this post by barry rowlingson
Yes, both are rooted in age-old design infelicities (in which, basically, interactive expedience has taken precedence over consistency and generality).

Unfortunately, they are quite difficult to rectify, because there are bound to be countless uses of, say, diag(5) as a 5x5 identity matrix which would break if it suddenly meant the 1x1 matrix(5) instead.

We'd need a very carefully orchestrated warn-deprecate-defunct-newBehaviour sequence, with a time scale of years, most likely. It is, in principle, doable (I think), but we don't really have the mechanisms to follow through on it.  Almost all developers have main job responsibilities, and it is very easy to get sidetracked at the wrong moment, so most changes get done on a now-or-never basis.

I have toyed with the idea of setting up for version-dependent code where code sections could be coded up front and then activated when the relevant version is reached. Then I got swamped again...

-pd

> On 17 Sep 2018, at 20:08 , Barry Rowlingson <[hidden email]> wrote:
>
> On Mon, Sep 17, 2018 at 5:22 PM, Gábor Csárdi <[hidden email]>
> wrote:
>
>> I would say it is a mis-feature. If the 'x' argument of diag() is a
>> vector of length 1, then it creates an identity matrix of that size,
>> instead of creating a 1x1 matrix with the given value:
>>
>> ❯ diag(3)
>>     [,1] [,2] [,3]
>> [1,]    1    0    0
>> [2,]    0    1    0
>> [3,]    0    0    1
>>
>> Of course this makes it cumbersome to use diag() in a package, when
>> you are not sure if the input vector is longer than 1. This seems to
>> be a good workaround:
>>
>> ❯ diag(-1, nrow = 1)
>>     [,1]
>> [1,]   -1
>>
>> Or, in general if you have vector v:
>>
>> ❯ v <- -1
>> ❯ diag(v, nrow = length(v))
>>     [,1]
>> [1,]   -1
>>>
>>
>
> Anyone else getting deja-vu with the `sample` function?
>
>> sample(5:3)
> [1] 3 5 4
>
> ok...
>
>> sample(5:4)
> [1] 4 5
>
> fine...
>
>> sample(5:5)
> [1] 3 1 5 2 4
>
> uh oh. Documented, of course.
>
> B
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

--
Peter Dalgaard, Professor,
Center for Statistics, Copenhagen Business School
Solbjerg Plads 3, 2000 Frederiksberg, Denmark
Phone: (+45)38153501
Office: A 4.23
Email: [hidden email]  Priv: [hidden email]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: diag(-1) produces weird result

Gábor Csárdi
Some languages that recognized early design mistakes introduced a
strict mode, which applies to a local context, and enforces a safer,
more consistent API. This is a pragmatic solution, as it does not
require any changes to existing code, but still allows writing better
code in the future.

Implementing a context restricted strict mode is probably not trivial,
considering the flexibility of the language, but maybe it is worth
some thinking.

Gábor
On Tue, Sep 18, 2018 at 2:00 PM peter dalgaard <[hidden email]> wrote:

>
> Yes, both are rooted in age-old design infelicities (in which, basically, interactive expedience has taken precedence over consistency and generality).
>
> Unfortunately, they are quite difficult to rectify, because there are bound to be countless uses of, say, diag(5) as a 5x5 identity matrix which would break if it suddenly meant the 1x1 matrix(5) instead.
>
> We'd need a very carefully orchestrated warn-deprecate-defunct-newBehaviour sequence, with a time scale of years, most likely. It is, in principle, doable (I think), but we don't really have the mechanisms to follow through on it.  Almost all developers have main job responsibilities, and it is very easy to get sidetracked at the wrong moment, so most changes get done on a now-or-never basis.
>
> I have toyed with the idea of setting up for version-dependent code where code sections could be coded up front and then activated when the relevant version is reached. Then I got swamped again...
>
> -pd
>
> > On 17 Sep 2018, at 20:08 , Barry Rowlingson <[hidden email]> wrote:
> >
> > On Mon, Sep 17, 2018 at 5:22 PM, Gábor Csárdi <[hidden email]>
> > wrote:
> >
> >> I would say it is a mis-feature. If the 'x' argument of diag() is a
> >> vector of length 1, then it creates an identity matrix of that size,
> >> instead of creating a 1x1 matrix with the given value:
> >>
> >> ❯ diag(3)
> >>     [,1] [,2] [,3]
> >> [1,]    1    0    0
> >> [2,]    0    1    0
> >> [3,]    0    0    1
> >>
> >> Of course this makes it cumbersome to use diag() in a package, when
> >> you are not sure if the input vector is longer than 1. This seems to
> >> be a good workaround:
> >>
> >> ❯ diag(-1, nrow = 1)
> >>     [,1]
> >> [1,]   -1
> >>
> >> Or, in general if you have vector v:
> >>
> >> ❯ v <- -1
> >> ❯ diag(v, nrow = length(v))
> >>     [,1]
> >> [1,]   -1
> >>>
> >>
> >
> > Anyone else getting deja-vu with the `sample` function?
> >
> >> sample(5:3)
> > [1] 3 5 4
> >
> > ok...
> >
> >> sample(5:4)
> > [1] 4 5
> >
> > fine...
> >
> >> sample(5:5)
> > [1] 3 1 5 2 4
> >
> > uh oh. Documented, of course.
> >
> > B
> >
> >       [[alternative HTML version deleted]]
> >
> > ______________________________________________
> > [hidden email] mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
>
> --
> Peter Dalgaard, Professor,
> Center for Statistics, Copenhagen Business School
> Solbjerg Plads 3, 2000 Frederiksberg, Denmark
> Phone: (+45)38153501
> Office: A 4.23
> Email: [hidden email]  Priv: [hidden email]
>
>
>
>
>
>
>
>
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel