diag() overloading

Posted on
Picture of user. tbates Joined: 07/31/2009
Hi, I was wanting to get the diagonal of an openmx output matrix and tried "diag()" as shown below with the matrix.

Question: should (can?) we overload "standard" R functions, or is there to be an mxDiag() equivalent?

If the latter, it would be nice if where possible it worked (to parameters) as the {base} library functions do.

I guess that it would be VERY helpful if code like

   a = mxRun(factorModel)
  round(diag(a$S), 2) # worked, i.e, output a matrix rounded to 2 decimal places
> diag(a$S)
Error in y[1L + 0L:(m - 1L) * (n + 1L)] <- x : 
  incompatible types (from S4 to double) in subassignment type fix

> a$S
SymmMatrix 'S' 

Labels matrix: No labels assigned.

Values matrix:
           [,1]       [,2]      [,3]       [,4]       [,5] [,6]
[1,] 0.04081422 0.00000000 0.0000000 0.00000000 0.00000000    0
[2,] 0.00000000 0.03802001 0.0000000 0.00000000 0.00000000    0
[3,] 0.00000000 0.00000000 0.0408272 0.00000000 0.00000000    0
[4,] 0.00000000 0.00000000 0.0000000 0.03938708 0.00000000    0
[5,] 0.00000000 0.00000000 0.0000000 0.00000000 0.03628711    0
[6,] 0.00000000 0.00000000 0.0000000 0.00000000 0.00000000    1
Replied on Thu, 08/13/2009 - 18:45
Picture of user. mspiegel Joined: 07/31/2009

Hi Tim,

The recommended way to do this is to use the mxEvaluate() function. In this fashion, we do not have to rewrite our own version of all the matrix operations.


factorModelOut <- mxRun(factorModel)
mxEvaluate(diag(S), factorModelOut)

Replied on Thu, 08/13/2009 - 22:25
Picture of user. mspiegel Joined: 07/31/2009

In reply to by Jeff

Thanks for removing the diag() overloading. IMO the greater argument against overloading the matrix operations is that it is restrictive to assume that matrix functions on MxObjects always occur on the values sub-matrix. I've overloaded a few functions that return the same value across all the submatrices, such as nrow() and ncol(). But if we want to operate on the value submatrix, mxEvaluate() is the way to go.
Replied on Fri, 08/14/2009 - 06:10
Picture of user. tbates Joined: 07/31/2009

In reply to by Steve

This is a small point, but one to get right early on, I think.

It didn't occurred to me to use mxEvaluate() to do this, mostly because, unlike matrix, there is nothing in R called "evaluate", so mxEvaluate is not analogous to an existing function with that name.

What it seems to be analogous, to is with()

So I'd like to suggest:

1: rename mxEvaluate() to mxWith()
   * or even better, overload this single function, so if it sees an openMx object in slot one, it behaves correctly.

2. reorder the parameters to follow with

    mxWith(thisModel, doThisCode)

It easier to read and easier to stumble across and remember

Replied on Fri, 08/14/2009 - 06:38
Picture of user. Steve Joined: 07/30/2009

In reply to by tbates

Actually, eval() is there.

eval                  package:base                  R Documentation

Evaluate an (Unevaluated) Expression

Description:

     Evaluate an R expression in a specified environment.

Usage:

     eval(expr, envir = parent.frame(),
                enclos = if(is.list(envir) || is.pairlist(envir))
                            parent.frame() else baseenv())

We could rename to mxEval(). I am not sure why the longer name was chosen.