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:
- Rewrite
det
, possibly breaking whatever required use ofc()
. - Somehow overload
c()
(or is itas.vector
?) for my object. I am not even sure how to do that. - 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)