Generate a tape of a boundary weight function, which is useful for specifying the boundary of manifolds in score matching.
Use tape_bdryw()
to specify a custom function using C++
code much like TMB::compile()
.
Use tape_bdryw_inbuilt()
for tapes of inbuilt functions implemented in this package.
tape_bdryw_inbuilt(name, x, acut)tape_bdryw(fileORcode = "", x, Cppopt = NULL)
A list of three objects
fun
a function that evaluates the function directly
tape
a tape of the function
file
the temporary file storing the final source code passed to Rcpp::sourceCpp()
Name of an inbuilt function. See details.
Vector giving location in the manifold.
The \(a_c\) threshold used by the "minsq" and "prodsq" built-in functions. See details.
A character string giving the path name of a file containing the unnormalised log-density definition OR code. fileORcode
will be treated as a file name if fileORcode
contains no new line characters ('\n' or '\r\n') and has a file extension detected by tools::file_ext()
.
List of named options passed to Rcpp::sourceCpp()
The code (possibly in the file pointed to by fileORcode
) must be C++
that uses only CppAD
and Eigen
, which makes it very similar to the requirements of the input to TMB::compile()
(which also uses CppAD
and Eigen
).
The start of code
should always be "a1type fname(const veca1 &x){
" where fname
is your chosen name of the function, x
represents a point in the manifold. This specifies that the function will a single two vector argument (of type veca1
) and will return a single numeric value (a1type
).
The type a1type
is a double with special ability for being taped by CppAD
. The veca1
type is a vector of a1type
elements, with the vector wrapping supplied by the Eigen
C++ package (that is an Eigen
matrix with 1 column and dynamic number of rows).
In place operations like +=
on a1type
, veca1
and similar have not worked for me (compile errors); fortunately the efficiency of in place operations is irrelevant for taping operations.
The body of the function must use operations from Eigen and/or CppAD, prefixed by Eigen::
and CppAD::
respectively.
There are no easy instructions for writing these as it is genuine C++
code, which can be very opaque to those unfamiliar with C++
.
However, recently ChatGPT and claude.ai have been able to very quickly translating R
functions to C++
functions (KLH has been telling these A.I. to use Eigen and CppAD, and giving the definitions of a1type
and veca1
).
I've found the quick reference pages for for Eigen
useful. Limited unary and binary operations are available directly from CppAD
without Eigen
.
Non-smooth functions should be used with care, but can be specified using CppAD
's CondExp functions.
For tape_bdryw_inbuilt()
, currently available functions are:
The function "ones" applies no weights and should be used whenever the manifold does not have a boundary. $$h(x)^2 = 1.$$
The function "minsq" is the minima-based boundary weight function @Equation 12, @scealy2023scscorematchingad $$h(x)^2 = \min(x_1^2, x_2^2, ..., x_p^2, a_c^2).$$ where \(x_j\) is the jth component of x.
The function "prodsq" is the product-based @Equation 9, @scealy2023scscorematchingad $$h(x)^2 = \min(\prod_{j=1}^{p} x_j^2, a_c^2).$$ where \(x_j\) is the jth component of x.
The "minsq" and "prodsq" functions are useful when the manifold is the positive orthant, the p-dimensional unit sphere restricted to the positive orthant, or the unit simplex. @scealy2023scscorematchingad prove that both "minsq" and "prodsq" can be used for score matching the PPI model on the simplex or positive orthant of the sphere.
The function tape_bdryw()
uses Rcpp::sourceCpp()
to generate a tape of a function defined in C++.
The result result is NOT safe to save or pass to other CPUs in a parallel operation.
Other tape builders:
avgrange()
,
fixdynamic()
,
fixindependent()
,
keeprange()
,
tape_Hessian()
,
tape_Jacobian()
,
tape_gradoffset()
,
tape_logJacdet()
,
tape_smd()
,
tape_swap()
,
tape_uld()
if (FALSE) {
out <- tape_bdrw(
"a1type myminsq(const veca1 &x){
veca1 xsq = x.array().square();
a1type minval(0.1 * 0.1);
for(size_t i=0;i
Run the code above in your browser using DataLab