Distributing Distributions
A Normal Distribution Object
In this example, we expose a Normal distribution as a COM object.
This class provides methods for
-
generating samples
-
computing percentiles
-
computing quantiles
-
computing densitys
-
shifting and scaling the distribution for
subsequent computations
Unlike the S functions to which one must supply the parameters of the
distribution, objects from this class maintain state and the methods
have access to these. To do this, we generate a closure containing
simple functions that merely call the regular S functions to for
dealing with the Normal distribution. These are
rnorm,
pnorm,
qnorm,
dnorm.
Because the Normal distribution object has state given by the mean and
standard deviation, we need a closure in R to "capture" this state.
We do this by providing a generator function that defines the methods
with these settings.
g <- function(mu = 0, sigma = 1)
{
generic <- function(n, abc=10, k="My string") {
n + 10
}
sample <- function(n) {
rnorm(as.integer(n), mu, sigma)
}
percentile <- function(q, lower = TRUE) {
pnorm(as.numeric(q), mu, sigma, lower.tail = as.logical(lower))
}
quantile <- function(p) {
qnorm(as.numeric(p), mu, sigma)
}
density <- function(x) {
dnorm(as.numeric(x), mu, sigma)
}
deviate <- function() {
rnorm(1, mu, sigma)
}
list(sample = sample, percentile = percentile,
quantile = quantile, density = density,
deviate = deviate,
generic = generic,
.properties = c("mu", "sigma"),
.help = c(sample = "generate a sample of values",
percentile = "CDF values from this distribution",
quantile = "quantile values from this distribution",
density = "values of the density function for this distribution"
))
}
|
---|
Now we register this class definition with R and
for clients to access.
def = SCOMIDispatch(g, "SNormal")
def@classId = getuuid("c484d2f9-21f5-49ac-8c8d-2007e12245d3")
registerCOMClass(def)
|
---|
We can use this class in any of the COM supported classes. For
example, consider
Visual Basic (VB). We first create an instance of
this class. We declare some variables and then create the object.
Dim N as Object
Dim v as Variant
Set N = CreateObject("SNormal")
|
---|
Now we can invoke the objects methods. So we create a sample of 3
elements.
Now
v is a
VARIANT.
Unlike high-level languages such as Python or Perl,
Visual Basic doesn't convert the array returned from R directly
into a VB array. Instead, we can access it via the
variant and ask for its upper and lower indices and query
its contents.
Debug.Print TypeName(v)
Debug.Print UBound(v)
Debug.Print LBound(v)
Debug.Print v(1)
|
---|
We can iterate over its entries
as follows
For i = LBound(v) To UBound(v)
Debug.Print v(i)
Next i
|
---|