Title: | Utilities for Simulation, Plots, Quantile Functions and Programming |
---|---|
Description: | Plot density and distribution functions with automatic selection of suitable regions. Numerically invert (compute quantiles) distribution functions. Simulate real and complex numbers from distributions of their magnitude and arguments. Optionally, the magnitudes and/or arguments may be fixed in almost arbitrary ways. Create polynomials from roots given in Cartesian or polar form. Small programming utilities: check if an object is identical to NA, count positional arguments in a call, set intersection of more than two sets, check if an argument is unnamed, compute the graph of S4 classes in packages. |
Authors: | Georgi N. Boshnakov [aut, cre] |
Maintainer: | Georgi N. Boshnakov <[email protected]> |
License: | GPL (>=2) |
Version: | 0.5.0.9000 |
Built: | 2024-11-06 02:55:28 UTC |
Source: | https://github.com/geobosh/gbutils |
Get inheritance graph of classes in one or more packages.
adjacencyOfClasses(packages, externalSubclasses = FALSE, result = c("default", "matrixOfPairs", "adjacencyMatrix"), Wolfram = FALSE)
adjacencyOfClasses(packages, externalSubclasses = FALSE, result = c("default", "matrixOfPairs", "adjacencyMatrix"), Wolfram = FALSE)
packages |
names of one or more packages, a character vector |
externalSubclasses |
if |
result |
format of the result, can be missing or one of
|
Wolfram |
if |
adjacencyOfClasses
computes a graph representation of the
dependencies of S4 classes defined in one or more packages (as
specified by argument package
) and returns a list. The
contents of the list returned by adjacencyOfClasses
depend on
argument result
. Partial matching is used for the value of
argument result
, e.g., "adj" is equivalent to
"adjacencyMatrix".
If externalSubclasses = FALSE
, the default, subclasses defined
outside the requested packages are excluded. This is typically what
the user will be looking for. To get a complete tree, set
externalSubclasses
to TRUE
.
The S4 classes are represented by the vertices of the graph.
Component "vertices"
of the result gives them as a character
vector. References below to the th class or vertex
correspond to the order in this vector. No attempt is made to arrange
the vertices in a particular order. An empty list is returned if this
vector is empty.
If result
is missing or "default"
, the edges of the
graph are represented by a character vector. Each edge is represented
by a string with an arrow "->"
from a superclass to a
subclass. Here is an example that shows that this package defines one
class, which is a subclass of "list"
:
adjacencyOfClasses("gbutils") ##: $vertices ##: [1] "objectPad" "list" ##: $edges ##: [1] "list -> objectPad"
This illustrates the effect of argument "externalSubclasses"
:
adjacencyOfClasses("gbutils", externalSubclasses = TRUE) ##: $vertices ##: [1] "objectPad" "list" "vector" ##: $edges ##: [1] "list -> objectPad" "vector -> list"
The edge, "vector -> list" was omitted in the previous example since
this relationship is defined elsewhere. This resulted in class
"vector"
being dropped also from the vertices, since it is not
defined in "gbutils"
and none of the remaining edges contains
it.
If result
is "matrixOfPairs"
, the edges of the
graph are represented by a character matrix with two columns, where each row
represents an edge from the element in the first column to the element
in the second. In this example there is one edge, so the matrix
contains one row:
adjacencyOfClasses("gbutils", result = "matrixOfPairs") ##: $vertices ##: [1] "objectPad" "list" ##: $edges ##: [,1] [,2] ##: [1,] "list" "objectPad"
If result
is "adjacencyMatrix"
, the adjacency matrix of
the graph is in component "AM" of the returned list. Element of
this matrix is equal to one, if the
th class is a superclass
to the
th. In other words, the
th column gives the
superclasses of the
th class. Here the element in position
(1,2) is non-zero, so
"list"
is the superclass of "objectPad"
:
adjacencyOfClasses("gbutils", result = "adjacencyMatrix") ##: $vertices ##: [1] "objectPad" "list" ##: $AM ##: objectPad list ##: objectPad 0 1 ##: list 0 0
Note that including the vertices in the result is not redundant, since some may not be in any edge. This can happen if a class does not have any superclasses and subclasses.
As described above the result is not converted to a graph object but it can be fed to functions provided by a number of R packages.
An additional option is to use argument Wolfram
. If
Wolfram
is TRUE
, a suitable Mathematica command is
printed. It can be evaluated in a Mathematica session (e.g., by
copy/paste) to produce a graphical representation of the graph and/or
be manipulated further by it. This feature is a side effect, the
return value of adjacencyOfClasses
is as controlled by the
other arguments. For example, the return value below is as without
argument "Wolfram"
but, in addition, the printed line defines a
Wolfram language graph in terms of its vertices and edges:
adjacencyOfClasses("gbutils", Wolfram = TRUE) ##: Graph[{objectPad,list}, {list -> objectPad}, VertexLabels -> Automatic] ##: $vertices ##: [1] "objectPad" "list" ##: $edges ##: [1] "list -> objectPad"
Setting result = "adjacencyMatrix"
in the last R command
exports the graph in terms of its adjacency matrix:
adjacencyOfClasses("gbutils", Wolfram = TRUE, result = "adjacencyMatrix") ##: AdjacencyGraph[{objectPad,list}, {{0, 0}, ##: {1, 0} } ##: , VertexLabels -> Automatic] ##: $vertices ##: [1] "objectPad" "list" ##: $AM ##: objectPad list ##: objectPad 0 1 ##: list 0 0
a list with some of the following components (as described in Details):
vertices |
a character vector of S4 class names, |
edges |
the edges of the graph, in the format controlled by
argument |
AM |
the adjacency matrix of the graph (present only when
|
Georgi N. Boshnakov
Gentleman R, Whalen E, Huber W, Falcon S (2017). graph: A package to handle graph data structures. R package version 1.56.0.
Hansen KD, Gentry J, Long L, Gentleman R, Falcon S, Hahne F, Sarkar D (2017). Rgraphviz: Provides plotting capabilities for R graph objects. R package version 2.22.0.
Maechler M (2015). classGraph: Construct Graphs of S4 Class Hierarchies. (partly based on code from Robert Gentleman) R package version 0.7-5, https://CRAN.R-project.org/package=classGraph.
?methods::classesToAM
which is used for the main computation
here,
Maechler (2015) for a suite of related functions. Gentleman et al. (2017) for creation and manipulation of graphs, and Hansen et al. (2017) for visualisation of graphs.
adjacencyOfClasses("gbutils") adjacencyOfClasses("gbutils", TRUE) adjacencyOfClasses("gbutils", FALSE, "matrixOfPairs") adjacencyOfClasses("gbutils", TRUE, "matrixOfPairs") adjacencyOfClasses("gbutils", FALSE, "adjacencyMatrix") adjacencyOfClasses("gbutils", TRUE, "adjacencyMatrix") ## as above, also represent the graph using the edges adjacencyOfClasses("gbutils", Wolfram = TRUE) adjacencyOfClasses("gbutils", TRUE, Wolfram = TRUE) ## here the graph is represented by the adjacency matrix: adjacencyOfClasses("gbutils", FALSE, "adjacencyMatrix", Wolfram = TRUE) adjacencyOfClasses("gbutils", TRUE, "adjacencyMatrix", Wolfram = TRUE) if(requireNamespace("graph", quietly = TRUE) && requireNamespace("Rgraphviz", quietly = TRUE)) withAutoprint({ ## another package adjacencyOfClasses("graph") ac1 <- adjacencyOfClasses("graph", FALSE, "adjacencyMatrix") ## note the use of t() below gr_ac1 <- graph::graphAM(adjMat = t(ac1$AM), edgemode = "directed") if(require("Rgraphviz", quietly = TRUE, warn.conflicts = FALSE)) plot(gr_ac1) ## more than one package ac2 <- adjacencyOfClasses(c("graph", "Rgraphviz"), FALSE, "adjacencyMatrix") gr_ac2 <- graph::graphAM(adjMat = t(ac2$AM), edgemode = "directed") if(require("Rgraphviz", quietly = TRUE)) plot(gr_ac2) })
adjacencyOfClasses("gbutils") adjacencyOfClasses("gbutils", TRUE) adjacencyOfClasses("gbutils", FALSE, "matrixOfPairs") adjacencyOfClasses("gbutils", TRUE, "matrixOfPairs") adjacencyOfClasses("gbutils", FALSE, "adjacencyMatrix") adjacencyOfClasses("gbutils", TRUE, "adjacencyMatrix") ## as above, also represent the graph using the edges adjacencyOfClasses("gbutils", Wolfram = TRUE) adjacencyOfClasses("gbutils", TRUE, Wolfram = TRUE) ## here the graph is represented by the adjacency matrix: adjacencyOfClasses("gbutils", FALSE, "adjacencyMatrix", Wolfram = TRUE) adjacencyOfClasses("gbutils", TRUE, "adjacencyMatrix", Wolfram = TRUE) if(requireNamespace("graph", quietly = TRUE) && requireNamespace("Rgraphviz", quietly = TRUE)) withAutoprint({ ## another package adjacencyOfClasses("graph") ac1 <- adjacencyOfClasses("graph", FALSE, "adjacencyMatrix") ## note the use of t() below gr_ac1 <- graph::graphAM(adjMat = t(ac1$AM), edgemode = "directed") if(require("Rgraphviz", quietly = TRUE, warn.conflicts = FALSE)) plot(gr_ac1) ## more than one package ac2 <- adjacencyOfClasses(c("graph", "Rgraphviz"), FALSE, "adjacencyMatrix") gr_ac2 <- graph::graphAM(adjMat = t(ac2$AM), edgemode = "directed") if(require("Rgraphviz", quietly = TRUE)) plot(gr_ac2) })
Numerically calculate a quantile from a distribution function.
cdf2quantile(p, cdf, interval = c(-3, 3), lower = min(interval), upper = max(interval), ...)
cdf2quantile(p, cdf, interval = c(-3, 3), lower = min(interval), upper = max(interval), ...)
p |
a number in the interval (0,1). |
cdf |
cumulative distribution function, a function. |
interval |
interval in which to look for the root, see Details. |
lower |
lower end point of the interval. |
upper |
upper end point of the interval. |
... |
any further arguments to be passed to the root finding function and the cdf, see Details. |
The quantile, , is computed numerically as the solution of the
equation
.
Function uniroot
is used to find the root. To request higher
precision, set argument tol
. Other arguments in ...
are
passed on to cdf
.
uniroot
needs an interval where to look for the root.
There is a default one, which is extended automatically if it does not
contain the quantile. This assumes that argument cdf
is an
increasing function (as it should be).
To override the default interval, use argument interval
(a
vector of two numbers) or lower
and/or upper
. This may
be necessary if the support of the distribution is not the whole real
line and cdf
does not cope with values outside the support of
the distribution.
The computed quantile as a number.
Georgi N. Boshnakov
cdf2quantile(0.95, pnorm) cdf2quantile(0.05, pexp) # support [0,Inf) is no problem for cdf2quantile(0.05, plnorm) # for built-in distributions. ## default predicision is about 4 digits after decimal point cdf2quantile(0.95, pnorm, mean = 3, sd = 1) cdf2quantile(0.05, pnorm, mean = 3, sd = 1) qnorm(c(0.95, 0.05), mean = 3, sd = 1) ## request a higher precision: cdf2quantile(0.05, pnorm, mean = 3, sd = 1, tol = 1e-8) cdf2quantile(0.05, pnorm, mean = 3, sd = 1, tol = 1e-12) ## see also examples for plotpdf()
cdf2quantile(0.95, pnorm) cdf2quantile(0.05, pexp) # support [0,Inf) is no problem for cdf2quantile(0.05, plnorm) # for built-in distributions. ## default predicision is about 4 digits after decimal point cdf2quantile(0.95, pnorm, mean = 3, sd = 1) cdf2quantile(0.05, pnorm, mean = 3, sd = 1) qnorm(c(0.95, 0.05), mean = 3, sd = 1) ## request a higher precision: cdf2quantile(0.05, pnorm, mean = 3, sd = 1, tol = 1e-8) cdf2quantile(0.05, pnorm, mean = 3, sd = 1, tol = 1e-12) ## see also examples for plotpdf()
Check if a component of a list is not named.
isargunnamed(x, k)
isargunnamed(x, k)
x |
a list. |
k |
an integer, specifies a position in |
isargunnamed(x,k)
returns TRUE if the k-th component of
x
is not named and FALSE otherwise.
Argument x
is typically a list of arguments used in a call
to a function, such as the one obtained by list(...)
in the
body of a function definition.
If k
is not positive, isargunnamed
returns FALSE.
TRUE or FALSE
Georgi N. Boshnakov
match.call
in base package
li1 <- list(a=1, 2, 3) isargunnamed(li1, 1) isargunnamed(li1, 2) ## wholly unnamed list li2 <- list(1, 2, 3) isargunnamed(li2, 1) isargunnamed(li2, 2) ## using in a function definition f1 <- function(...){ dots <- list(...) for(i in seq(along=dots)) cat(i, isargunnamed(dots, i), "\n") } f1(1) f1(a = 3, 4, c = 5) f1(x = "a", y = "b")
li1 <- list(a=1, 2, 3) isargunnamed(li1, 1) isargunnamed(li1, 2) ## wholly unnamed list li2 <- list(1, 2, 3) isargunnamed(li2, 1) isargunnamed(li2, 2) ## using in a function definition f1 <- function(...){ dots <- list(...) for(i in seq(along=dots)) cat(i, isargunnamed(dots, i), "\n") } f1(1) f1(a = 3, 4, c = 5) f1(x = "a", y = "b")
Check if an object is NA. Always return TRUE of FALSE, a logical vector of length one.
isNA(x)
isNA(x)
x |
any R object. |
isNA
returns TRUE if the argument is a single NA, i.e. it is
atomic, has length one, and represents an NA value. In any other case
isNA
returns FALSE
.
isNA
is suitable for use in conditional constructs since it
always returns a single value which is never NA.
Note that identical()
distinguishes different types of NA,
i.e. identical(x, NA)
is TRUE only if x
is NA (logical).
TRUE or FALSE
The requirement that x
is atomic means that
isNA(list(NA))
gives FALSE
.
For comparison, is.na(list(NA))
gives TRUE
. The same
holds for classed lists, such as is.na(structure(list(NA), class
= "myclass"))
.
Georgi N. Boshnakov
v <- c(1, NA, 3) isNA(v[2]) # TRUE ## a vector of two or more Na's is not isNA isNA(rep(NA,3)) # FALSE ## a list containing NA is not isNA isNA(list(NA)) # FALSE ## ... but is.na(list(NA)) # TRUE ## identical() distinguishes different types of NA: class(v) # "numeric", not "integer" identical(v[2], NA) # FALSE, NA on its own is "logical" identical(v[2], NA_integer_) # FALSE identical(v[2], NA_real_) # TRUE vi <- c(1L, NA_integer_, 3L) isNA(vi[2]) # TRUE class(vi) # "integer" identical(vi[2], NA_integer_) # TRUE identical(vi[2], NA_real_) # FALSE ## is.na(NULL) would give a warning isNA(NULL) # FALSE ## a length zero object is not NA, so isNA() returns FALSE: isNA(logical(0)) # FALSE ## is.na() has a different remit and returns a 0-length vector: is.na(logical(0)) # logical(0)
v <- c(1, NA, 3) isNA(v[2]) # TRUE ## a vector of two or more Na's is not isNA isNA(rep(NA,3)) # FALSE ## a list containing NA is not isNA isNA(list(NA)) # FALSE ## ... but is.na(list(NA)) # TRUE ## identical() distinguishes different types of NA: class(v) # "numeric", not "integer" identical(v[2], NA) # FALSE, NA on its own is "logical" identical(v[2], NA_integer_) # FALSE identical(v[2], NA_real_) # TRUE vi <- c(1L, NA_integer_, 3L) isNA(vi[2]) # TRUE class(vi) # "integer" identical(vi[2], NA_integer_) # TRUE identical(vi[2], NA_real_) # FALSE ## is.na(NULL) would give a warning isNA(NULL) # FALSE ## a length zero object is not NA, so isNA() returns FALSE: isNA(logical(0)) # FALSE ## is.na() has a different remit and returns a 0-length vector: is.na(logical(0)) # logical(0)
Set intersection of arbitrary number of arguments.
mintersect(...)
mintersect(...)
... |
arguments to be intersected, vectors of the same mode,
see |
The base R function intersect
is a binary
operation. mintersect
works with any positive number of
arguments.
If called with one argument, mintersect
returns it. This is
unlike intersect
which gives an error in this case.
Calling mintersect
with no arguments is an error (as it is for
intercect
).
a vector representing the intersection of the arguments
Georgi N. Boshnakov
mintersect(1:20, 3:18, 7:12) mintersect(letters[1:20], letters[3:18], letters[7:12]) mintersect(1:4)
mintersect(1:20, 3:18, 7:12) mintersect(letters[1:20], letters[3:18], letters[7:12]) mintersect(1:4)
Check if an element of a pairlist is missing.
missing_arg(arg)
missing_arg(arg)
arg |
the object to test. |
The argument passed to missing_arg
is typically an element of a
pairlist
or the list produced by alist()
. missing_arg
returns TRUE
if it is missing and FALSE
otherwise.
Objects of type pairlist
come up at R level almost exclusively
as the formal arguments of functions. missing_arg
can be useful
when they are manipulated programmatically.
TRUE or FALSE
Georgi N. Boshnakov
lmargs <- formals(lm) class(lmargs) # pairlist missing_arg(lmargs$data) ## which arguments of lm() have no (explicit) defaults? sapply(lmargs, missing_arg) ## This gives an error: ## pairlist(x = 3, y = , z = 5) ## an example with alist() pl2 <- alist(a = "", b = , c = 3) class(pl2) # list ## this shows that 'b' is missing, 'a' and 'c' are not: sapply(pl2, missing_arg) # FALSE TRUE FALSE ## superficially, 'b' is equal to the empty string: pl2[[2]] sapply(pl2, function(x) x == "") # TRUE TRUE FALSE ## with pairlist the results are the same: g <- function(a = "", b, c = 3) NULL a.g <- formals(g) class(a.g) # pairlist sapply(a.g, missing_arg) # FALSE TRUE FALSE a.g[[2]] sapply(a.g, function(x) x == "") # TRUE TRUE FALSE
lmargs <- formals(lm) class(lmargs) # pairlist missing_arg(lmargs$data) ## which arguments of lm() have no (explicit) defaults? sapply(lmargs, missing_arg) ## This gives an error: ## pairlist(x = 3, y = , z = 5) ## an example with alist() pl2 <- alist(a = "", b = , c = 3) class(pl2) # list ## this shows that 'b' is missing, 'a' and 'c' are not: sapply(pl2, missing_arg) # FALSE TRUE FALSE ## superficially, 'b' is equal to the empty string: pl2[[2]] sapply(pl2, function(x) x == "") # TRUE TRUE FALSE ## with pairlist the results are the same: g <- function(a = "", b, c = 3) NULL a.g <- formals(g) class(a.g) # pairlist sapply(a.g, missing_arg) # FALSE TRUE FALSE a.g[[2]] sapply(a.g, function(x) x == "") # TRUE TRUE FALSE
Small utility functions
myouter(x, y, fun) shiftleft(x, k = 1) shiftright(x, k = 1)
myouter(x, y, fun) shiftleft(x, k = 1) shiftright(x, k = 1)
x |
a vector. |
y |
a vector. |
k |
a non-negative integer. |
fun |
a function, see ‘Details’. |
myouter(x,y,fun)
computes the outer product of x
and
y
using the function fun
. The result is a matrix with
th element equal to
fun(x[i],y[j])
. It is not
required for fun to be able to work with vector arguments. The function
does the computations in R using a simple double loop. So, it is a
convenience function, not a speed improving one.
shiftright(x,k)
rotates the vector x
k
positions
to the right.
shiftleft(x,k)
rotates the vector x
k
positions to
the left.
for myouter
, a matrix, as described in ‘Details’
for shiftleft
and shiftright
, a vector
Georgi N. Boshnakov
Calculates the number of positional arguments used in a call.
nposargs(x, a = FALSE)
nposargs(x, a = FALSE)
x |
a call object, usually obtained from |
a |
if |
nposargs
is mainly for use in the body of function definitions,
paricularly for functions or methods that wish to mimic the behaviour
of "["
.
nposargs
gives the number of positional arguments used in a
call. It also takes into account empty arguments like those used in
expressions like x[1, ]
.
Optionally, it makes a particular correction that is peculiar
for "[" - if there are no named arguments in the call and the count
of the arguments is 2 and a[1]=TRUE
, it decreases the count by
one, i.e. returns 1. This is to distinguish between a x[]
and
x[i]
which both would give 2 otherwise. I have forgotten the details but,
roughly speaking, x[i] becomes "["(x,i) while x[] becomes "["(x,),
i.e. R puts the comma after x in any case.
the number of positional arguments in the call
I wrote this function (a long time ago) for use in methods for
"["
.
a[1]
above is typically obtained by a call missing(i)
somewhere at the beginning of the function. In my application I put
the results of several such calls in a vector, hence the check for
a[1]
rather than a
, For "["
, we may set
a = c(missing(i), missing(j), missing(k))
.
Georgi N. Boshnakov
f <- function(x,y,z,...){ call <- sys.call() nposargs(call) } f(a,b,c) # 3 f(a, , ) # 3 f(a, ) # 2 f(a) # 1 f(, ) # 2 f(, a, ) # 3 f() # 0
f <- function(x,y,z,...){ call <- sys.call() nposargs(call) } f(a,b,c) # 3 f(a, , ) # 3 f(a, ) # 2 f(a) # 1 f(, ) # 2 f(, a, ) # 3 f() # 0
Parse expressions residing in character vectors. Similar to parse() but keeping or not the source is controlled by an argument rather than global options.
parse_text(text, ..., keep = TRUE)
parse_text(text, ..., keep = TRUE)
text |
the text to parse, normally a character vector but can be
anything that |
... |
additional arguments to be passed on to |
keep |
required setting for option |
This is like parse(text=text,...)
, except that whether or not
the source is kept is controlled by argument keep
, not by
options("keep.source")
.
parse_text
sets options("keep.source")
to keep
(if they are different) before calling parse
and restores it
afterwards.
an expression representing the parsed text, see parse
for
details
The usual setting of option "keep.source" in interactive sessions is TRUE. However, in ‘R CMD check’ it is FALSE.
As a consequence, if the documentation of a package uses functions
that depend on option "keep.source" being TRUE
,
then some examples may run fine when copied and pasted in an R session
but (rightly) fail ‘R CMD check’.
The oposite may also happen, in that the documentation passes 'R CMD check' or Sweave files successfully build but some examples do not work when copied and pasted in an interactive session.
Georgi N. Boshnakov
Plot a probability denstity function with x-axis limits determined by quantiles of the distribution. Quantiles are computed using a quantile function or cumulative distribution function, whichever is supplied.
plotpdf(pdf, qdf, cdf, lq = 0.01, uq = 0.99, ...)
plotpdf(pdf, qdf, cdf, lq = 0.01, uq = 0.99, ...)
pdf |
probability density to be plotted, a function. |
qdf |
quantile function to be used for computation of quantiles, a function. |
cdf |
cumulative distribution function to be used for computation of quantiles,
a function. This argument is used if |
lq |
lower quantile, used in the computation of the left limit. |
uq |
upper quantile, used in the computation of the right limit. |
... |
additional arguments to be passed on to the |
The function plots pdf(x)
over the interval (xmin,xmax) where
xmin and xmax are the lq
th and uq
th quantiles,
respectively, of the distribution. The quantile function,
qdf
, is used, if supplied. Otherwise the quantiles are computed
numerically from the cdf.
Argument pdf
is not required to be a pdf, it may be any
function. For example, the same way of choosing the limits may be
appropriate for a plot of the cdf, see the examples.
Similarly, qdf
and cdf
need not be related to pdf
.
Georgi N. Boshnakov
pdf1 <- function(x) dnorm(x, mean = 100, sd = 5) qdf1 <- function(x) qnorm(x, mean = 100, sd = 5) cdf1 <- function(x) pnorm(x, mean = 100, sd = 5) plot(pdf1) # needs to specify 'from' and 'to' args for meaningful plot plotpdf(pdf1, qdf1) # using quantile function plotpdf(pdf1, cdf = cdf1) # using cdf plotpdf(pdf1, cdf = cdf1, lq = 0.001, uq = 0.999) # ... and non-default quantiles plotpdf(cdf1, cdf = cdf1, lq = 0.001, uq = 0.999) # plot a cdf ## a mixture distribution: pf1 <- function(x){ 0.25 * pnorm(x, mean = 3, sd = 0.2) + 0.75 * pnorm(x, mean = -1, sd = 0.5) } df1 <- function(x){ 0.25 * dnorm(x, mean = 3, sd = 0.2) + 0.75 * dnorm(x, mean = -1, sd = 0.5) } plotpdf(df1, cdf = pf1) # plot the pdf plotpdf(pf1, cdf = pf1) # plot the cdf c(cdf2quantile(0.05, pf1), cdf2quantile(0.95, pf1))
pdf1 <- function(x) dnorm(x, mean = 100, sd = 5) qdf1 <- function(x) qnorm(x, mean = 100, sd = 5) cdf1 <- function(x) pnorm(x, mean = 100, sd = 5) plot(pdf1) # needs to specify 'from' and 'to' args for meaningful plot plotpdf(pdf1, qdf1) # using quantile function plotpdf(pdf1, cdf = cdf1) # using cdf plotpdf(pdf1, cdf = cdf1, lq = 0.001, uq = 0.999) # ... and non-default quantiles plotpdf(cdf1, cdf = cdf1, lq = 0.001, uq = 0.999) # plot a cdf ## a mixture distribution: pf1 <- function(x){ 0.25 * pnorm(x, mean = 3, sd = 0.2) + 0.75 * pnorm(x, mean = -1, sd = 0.5) } df1 <- function(x){ 0.25 * dnorm(x, mean = 3, sd = 0.2) + 0.75 * dnorm(x, mean = -1, sd = 0.5) } plotpdf(df1, cdf = pf1) # plot the pdf plotpdf(pf1, cdf = pf1) # plot the cdf c(cdf2quantile(0.05, pf1), cdf2quantile(0.95, pf1))
Compute a pseudo-inverse matrix using singular value decomposition and setting very small singular values to zero.
pseudoInverse(a, tol = 1e-07)
pseudoInverse(a, tol = 1e-07)
a |
a matrix |
tol |
a number, the threshold for non-zero singular values. |
The singular value decomposition of a
is computed and singular
values smaller than tol
are set to zero. The result is formed
using the standard formula.
a matrix
##---- Should be DIRECTLY executable !! ----
##---- Should be DIRECTLY executable !! ----
Get the command history.
raw_history()
raw_history()
The command history is saved to a temporary file with
savehistory
and read back into a character vector.
a character vector
Georgi N. Boshnakov
## Not run: hist <- raw_history() length(hist) ## End(Not run)
## Not run: hist <- raw_history() length(hist) ## End(Not run)
Compute the coefficients of a polynomial with real coefficients, given
its real zeroes (roots) and one representative for each complex pair.
If complex numbers are given in polar form, there is an option to
specify the complex arguments as multiples of .
rpoly(x = numeric(0), arg = numeric(0), real = numeric(0), argpi = FALSE, monic = TRUE)
rpoly(x = numeric(0), arg = numeric(0), real = numeric(0), argpi = FALSE, monic = TRUE)
x |
if |
arg |
the complex arguments corresponding to the moduli in |
real |
the real roots of the polynomial. This argument is not needed when
|
argpi |
if |
monic |
if |
The complex zeroes of polynomials with real coefficients come in
complex conjugated pairs. Only one representative from each pair
should be supplied to rpoly
. The other is added
automatically. Of course, all real roots should be supplied, if any.
If x
is complex, it should contain all real roots and one
representative for each comple pair.
Otherise, if x
is not complex, it contains the moduli of the
numbers and arg
contains the complex arguments. The two should
be of equal length.
With the default FALSE
for argpi
, the k-th root of the
polynomial is x[k]*cos(arg[k]) + i*x[k]*sin(arg[k])
. If
argpi
is TRUE
it is x[k]*cos(pi*arg[k]) + i*x[k]*sin(pi*arg[k])
.
By default, a monic polinomial (the coefficient of the highest order
term is 1) is created but if monic
is FALSE
, the
constant term of the polynomial is set to 1 .
The options for argpi = TRUE
and/or monic = FALSE
are
convenient in some applications, e.g., time series analysis and
digital signal processing.
a real vector containing the coefficients of the polynomial.
When argpi
is TRUE
, is computed using
cospi(a)
. So this may differ slightly from the equivalent
result obtained with argpi = FALSE
and b = pi*a
, which
is computed as cos(b) = cos(pi*a)
, see the example.
Georgi N. Boshnakov
## z-1 rpoly(real = 1) ## roots 1, i, -i; p3(z) = (z-1)(z-i)(z+i) p3 <- rpoly(c(1, 1i)) p3 polyroot(p3) ## using polar for the complex roots (i = e^(i pi/2)) p3a <- rpoly(1, pi/2, real = 1) p3a ## mathematically, p3a is the same as p3 ## but the numerical calculation here gives a slight discrepancy p3a == p3 p3a - p3 ## using argpi = TRUE is somewhat more precise: p3b <- rpoly(1, 1/2, real = 1, argpi = TRUE) p3b p3b == p3 p3b - p3 ## indeed, in this case the results for p3b and p3 are identical: identical(p3b, p3) ## two ways to expand (z - 2*exp(i*pi/4))(z - 2*exp(-i*pi/4)) rpoly(2, pi/4) rpoly(2, 1/4, argpi = TRUE) ## set the constant term to 1; can be used, say, for AR models rpoly(2, pi/4, monic = FALSE) rpoly(2, 1/4, argpi = TRUE, monic = FALSE)
## z-1 rpoly(real = 1) ## roots 1, i, -i; p3(z) = (z-1)(z-i)(z+i) p3 <- rpoly(c(1, 1i)) p3 polyroot(p3) ## using polar for the complex roots (i = e^(i pi/2)) p3a <- rpoly(1, pi/2, real = 1) p3a ## mathematically, p3a is the same as p3 ## but the numerical calculation here gives a slight discrepancy p3a == p3 p3a - p3 ## using argpi = TRUE is somewhat more precise: p3b <- rpoly(1, 1/2, real = 1, argpi = TRUE) p3b p3b == p3 p3b - p3 ## indeed, in this case the results for p3b and p3 are identical: identical(p3b, p3) ## two ways to expand (z - 2*exp(i*pi/4))(z - 2*exp(-i*pi/4)) rpoly(2, pi/4) rpoly(2, 1/4, argpi = TRUE) ## set the constant term to 1; can be used, say, for AR models rpoly(2, pi/4, monic = FALSE) rpoly(2, 1/4, argpi = TRUE, monic = FALSE)
Simulate complex numbers with given distributions for the modulus and the argument and real numbers with given distributions for the absolute value and the sign. Some of the values may be partially or fully specified.
sim_complex(abs, arg, absgen = "runif", absarg = list(0, 1), arggen = runif, argarg = list(-pi, pi), ...) sim_real(abs, sign, signprob = 0.5, absgen = "runif", absarg = list(0, 1), ...)
sim_complex(abs, arg, absgen = "runif", absarg = list(0, 1), arggen = runif, argarg = list(-pi, pi), ...) sim_real(abs, sign, signprob = 0.5, absgen = "runif", absarg = list(0, 1), ...)
abs |
vector of absolute values. |
sign |
vector of signs (1 or -1). |
signprob |
probability for a positive sign. |
arg |
vector of arguments (of complex numbers). |
absgen |
generator for the absolute values, a function or a character string naming a function. |
absarg |
arguments for |
arggen |
generator for the arguments of the complex numbers, a function or a string naming a function. |
argarg |
arguments for |
... |
not used, simplifies the call from |
sim_real
simulates real numbers by simulating separately their
absolute values and signs. sim_complex
simulates complex
numbers by simulating separately their moduli and arguments.
Both functions replace NA
's in argument abs
with values
simulated by the function specified by absgen
. Arguments for
absgen
are specified by the (possibly named) list
absarg
.
Similarly, sim_complex
replaces NA
's in argument
arg
with values simulated according to arggen
and
argarg
.
Further, sim_real
replaces NA
's in argument sign
with a random sample of ones and minus ones, where the probability for
the positive value is signprob
.
Only NA
entries in abs
, arg
and sign
are
filled with simulated values, the remaining entries are left
unchanged. This means that some (and even all) values may be
specified partially or completely.
abs
is combined with arg
or sign
to create the
result. These arguments are expected to be of matching shape and
length but this is not enforced and the usual recycling rules will
apply if this is not the case (not recommended to rely on this).
The default range for the (complex) argument is (-pi,pi).
for sim_real
, a vector of real numbers
for sim_complex
, a vector of complex numbers
Currently the shape of the result for sim_real
is the same as
that of argument abs
. But sim_complex
always returns a
vector. Probably this inconsistency should be removed.
Georgi N. Boshnakov
sim_numbers
which offers more flexible interface to
these functions.
## x[1] is fixed to 1, x[2] is negative with random magnitude: x <- sim_real(c(1,NA,NA,NA), c(1, -1, NA, NA)) ## z[1] fixed to 1, the remaining elements of z ## have random magnitude and fixed arguments: z <- sim_complex(c(1,NA,NA,NA), c(0, pi/2, pi, -pi/2)) ## without restrictions sim_complex(rep(NA,4)) sim_real(rep(NA,4)) ## moduli unrestricted; arguments restricted sim_complex(rep(NA,4), c(0, pi/2, pi, -pi/2))
## x[1] is fixed to 1, x[2] is negative with random magnitude: x <- sim_real(c(1,NA,NA,NA), c(1, -1, NA, NA)) ## z[1] fixed to 1, the remaining elements of z ## have random magnitude and fixed arguments: z <- sim_complex(c(1,NA,NA,NA), c(0, pi/2, pi, -pi/2)) ## without restrictions sim_complex(rep(NA,4)) sim_real(rep(NA,4)) ## moduli unrestricted; arguments restricted sim_complex(rep(NA,4), c(0, pi/2, pi, -pi/2))
Simulate real and complex numbers from polar form specifications. The numbers may be partially or fully specified. The distributions of absolute values and arguments/signs are specified independently.
sim_numbers(type = rep(as.character(NA), length(abs)), abs = rep(as.numeric(NA), length(type)), sign = rep(as.numeric(NA), length(type)), values = NULL, ...)
sim_numbers(type = rep(as.character(NA), length(abs)), abs = rep(as.numeric(NA), length(type)), sign = rep(as.numeric(NA), length(type)), values = NULL, ...)
type |
character vector specifying the types of the eigenvalues, see Details. |
abs |
vector of absolute values (moduli). |
sign |
vector of signs (for reals) and arguments (for complex numbers), see Details for interpretation. |
values |
values, see details. |
... |
additional arguments to be passed to |
sim_numbers
simulates a vector of real and complex numbers with
given distributions of their polar parts. It is possible also to fix
some of the numbers or one of their polar parts.
The length of the simulated vector is inferred from the length of
type
or abs
, so one of them must be
provided. sim_numbers
is a flexible front-end for
sim_real
and sim_complex
.
sim_numbers
generates a vector of values with types specified
by argument type
and/or inferred from argument values
.
The recommended way to use sim_numbers
is to provide argument
type
.
type[i]
specifies the type of the i-th element of the result:
real (type[i]=="r"
), complex (type[i]=="c"
) or
representing a complex conjugate pair (type[i]=="cp"
). If
values
is provided, the imaginary parts of its non-NA elements
are used to fill NA
elements of type
("r" if zero, "cp"
otherwise).
Some (or even all) values may be fixed or partially fixed with the
help of arguments abs
, sign
and values
. A
non-missing value of values[i]
fixes the i-th element of the
result to that value. Simlarly abs[i]
fixes the modulus and
sign[i]
fixes the sign/argument of the i-th element. If
values[i]
is not NA
, then it takes precedence and
abs[i]
and sign[i]
are ignored.
For real numbers sign
is the sign with possible values 1
(positive) or -1 (negative). For complex numbers, sign
is the
argument and is in the interval (-pi,pi).
If values
is supplied, then NA
entries in type
are replaced by "r" or "cp" depending on whether or not the imaginary
parts of the corresponding entries in values
are equal to zero.
A check is done for consistency when both type[i]
and
values[i]
are non-missing. Generally, values
is meant to
be used for values that are fixed and available directly in Cartesian
form, to avoid having to fill the corresponding entries of abs
and sign
.
NA
entries of abs
and sign
are filled with
simulated values, the remaining entries are considered fixed and left
unchanged. The default generator is uniform (0,1) for abs
,
uniform (-pi,pi) for the argument of complex values, and 1 or -1 with
p=1/2 for the sign of real values.
To specify a different generator for the moduli and absolute values,
use argument absgen
, giving it a function or the name of a
function. The arguments for this function can be specified by
absarg
(as a list). Similarly, the generator for arguments of
complex numbers can be specified by arggen
and argarg
.
Finally, the probability for the real numbers to be positive is given
by signprob
. These arguments are not in the signature of the
function since they are passed on directly (via "..."
) to the
underlying sim_complex
and sim_real
, see their
documentation and the examples below for further details.
a list with components
values |
vector of values; it is of type |
type |
a character vector of the types as above |
Values of type "cp" (complex pairs) are represented by one element, the complex conjugate elements are NOT generated. (todo: maybe add an argument to control this)
The convention for the sign of a real eigenvalue is 1 and -1, not 0 and pi.
The checks for consistency between type
and values
are
not complete and only straightforward use is recommended.
The current defaults for the arguments, see the signature
above, require that at least one of type
and abs
is not
missing.
Georgi N. Boshnakov
## one real number and one complex conjugated pair ## (maybe to specify a cubic polynomial through its roots) sim_numbers(type = c("r", "cp")) ## here the real value is fixed to have modulus 1, leaving the sign unspecified sim_numbers(type = c("r", "cp"), abs = c(1, NA)) ## now the real value is fixed to 1, ## the complex pair has argument +-pi/2, and free modulus: sim_numbers(type = c("r", "cp"), abs = c(1, NA), sign = c(0, pi/2)) ## using argument 'values' to fix some values; ## here the the third value is fixed: sim_numbers(type = c("r", "cp", "r"), values = c(NA,NA,3)) # type[3] = "r" sim_numbers(type = c("r", "cp", "cp"), values = c(NA,NA,3i)) # type[3] = "cp" ## type[3] can be left NA since it can be inferred from values[3]: sim_numbers(type = c("r", "cp", NA), values = c(NA,NA,3)) # type[3] = "r" sim_numbers(type = c("r", "cp", NA), values = c(NA,NA,3i)) # type[3] = "cp" ## it is an error to have a mismatch between args `type' and value: ## Not run: sim_numbers(type = c("r", "cp", "cp"), values = c(NA,NA,3)) sim_numbers(type = c("r", "cp", "r"), values = c(NA,NA,3i)) ## End(Not run) ## simulate 10 reals with the default generators sim_numbers(rep("r", 10)) ## simulate modulus from Rayleigh distribution ## rR <- function(n, sigma = 1) sigma * sqrt(-2*log(runif(n))) sim_numbers(type = c("cp", "cp"), absgen = rR, absarg = list()) # test the the components are N(0,1) ## (not run to save time for CRAN check) ## \dontrun{ ## v <- sim_numbers(type = rep("cp", 10000), absgen = "rR", ## absarg = list(sigma = 1)) ## ks.test(Re(v$values), "pnorm") ## ks.test(Im(v$values), "pnorm") ## }
## one real number and one complex conjugated pair ## (maybe to specify a cubic polynomial through its roots) sim_numbers(type = c("r", "cp")) ## here the real value is fixed to have modulus 1, leaving the sign unspecified sim_numbers(type = c("r", "cp"), abs = c(1, NA)) ## now the real value is fixed to 1, ## the complex pair has argument +-pi/2, and free modulus: sim_numbers(type = c("r", "cp"), abs = c(1, NA), sign = c(0, pi/2)) ## using argument 'values' to fix some values; ## here the the third value is fixed: sim_numbers(type = c("r", "cp", "r"), values = c(NA,NA,3)) # type[3] = "r" sim_numbers(type = c("r", "cp", "cp"), values = c(NA,NA,3i)) # type[3] = "cp" ## type[3] can be left NA since it can be inferred from values[3]: sim_numbers(type = c("r", "cp", NA), values = c(NA,NA,3)) # type[3] = "r" sim_numbers(type = c("r", "cp", NA), values = c(NA,NA,3i)) # type[3] = "cp" ## it is an error to have a mismatch between args `type' and value: ## Not run: sim_numbers(type = c("r", "cp", "cp"), values = c(NA,NA,3)) sim_numbers(type = c("r", "cp", "r"), values = c(NA,NA,3i)) ## End(Not run) ## simulate 10 reals with the default generators sim_numbers(rep("r", 10)) ## simulate modulus from Rayleigh distribution ## rR <- function(n, sigma = 1) sigma * sqrt(-2*log(runif(n))) sim_numbers(type = c("cp", "cp"), absgen = rR, absarg = list()) # test the the components are N(0,1) ## (not run to save time for CRAN check) ## \dontrun{ ## v <- sim_numbers(type = rep("cp", 10000), absgen = "rR", ## absarg = list(sigma = 1)) ## ks.test(Re(v$values), "pnorm") ## ks.test(Im(v$values), "pnorm") ## }