2

I have overloaded the determinant function for a S4 class in R. The base determinant function returns a list with elements modulus and sign; the values, however, are my S4 objects (for which * is overloaded). I then redefined the det function (I had to dig through the source code of the Matrix package to figure out how to do this, which was a horrorshow in its own right.) to be base::det with my environment.

For reasons I do not understand, base::det is defined as follows:

function (x, ...) 
{
    z <- determinant(x, logarithm = TRUE, ...)
    c(z$sign * exp(z$modulus))
}

When called on my object, the z is computed as expected, and z$sign and z$modulus are fine. I have overloaded * and exp so that z$sign * exp(z$modulus) evaluates to one of my objects.

BUT WHY THE c ?

When wrapped in c() the return value is no longer a scalar numeric, but a list with one element in it: my object. This is not what I want, and it breaks my unit tests. Some optional workarounds:

  1. Rewrite det, possibly breaking whatever required use of c().
  2. Somehow overload c() (or is it as.vector?) for my object. I am not even sure how to do that.
  3. Something else?

What is the recommended solution, and how should I proceed? Extra points for the proper way to document this mess with roxygen2.

(For reference, the package is now on github at https://github.com/shabbychef/madness )

EDIT The MWE would look as follows:

require(devtools)
install_github("shabbychef/madness")
require(madness)
xmat <- matrix(rnorm(16),ncol=4)
xmad <- madness(xmat)
detv <- det(xmad)
# detv is a list. I want it to be a madness object:
str(detv)
what_i_want <- detv[[1]]
str(what_i_want)
smci
  • 32,567
  • 20
  • 113
  • 146
shabbychef
  • 1,940
  • 3
  • 16
  • 28
  • 1
    What exactly do you want this function to return? Something other than a numeric value? The `c()` should just be stripping the class information basically. It would help if you included a self-contained, minimal [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) in your question. – MrFlick Dec 02 '15 at 05:29
  • @MrFlick The object contains the computed value and the derivative with respect to some other quantity (via forward differentiation). I would like that object to be returned. One can treat it as a numeric via `as.numeric` if needed. I will cook up a MWE. – shabbychef Dec 02 '15 at 05:35
  • `c()` is already a generic function (see `methods(c)`). You can define a method for your class if that would make sense. This link may help with that: http://adv-r.had.co.nz/OO-essentials.html#s4 – MrFlick Dec 02 '15 at 05:37
  • 1
    I think I got it: the `c()` exists to strip the _attributes_ from `z$modulus` and `z$sign`, and I have to think of a way of vectorizing my objects; and `c.objectname` is the way to do that. – shabbychef Dec 03 '15 at 04:23

0 Answers0