gpt4 book ai didi

c - 了解如何在 R 中处理 .Internal C 函数

转载 作者:太空狗 更新时间:2023-10-29 16:20:28 26 4
gpt4 key购买 nike

我想知道是否有人可以向我说明 R 如何从控制台提示符下键入的 R 命令执行 C 调用。 R 对 a) 函数参数和 b) 函数调用本身的处理让我特别困惑。

让我们举个例子,在这个例子中是 set.seed()。想知道它是如何工作的我在提示符下输入名称,获取源代码(look here for more on that),看到最终有一个 .Internal(set.seed(seed, i.knd, normal.kind),所以尽职尽责地在/src/names.c.Internals部分查找相关的函数名,发现它叫做do_setseed和在 RNG.c 中,它引导我...

SEXP attribute_hidden do_setseed (SEXP call, SEXP op, SEXP args, SEXP env)
{
SEXP skind, nkind;
int seed;

checkArity(op, args);
if(!isNull(CAR(args))) {
seed = asInteger(CAR(args));
if (seed == NA_INTEGER)
error(_("supplied seed is not a valid integer"));
} else seed = TimeToSeed();
skind = CADR(args);
nkind = CADDR(args);
//...
//DO RNG here
//...
return R_NilValue;
}
  • 什么是CARCADRCADDR?我的研究使我相信它们是受 Lisp 影响的关于列表的构造,但除此之外我不明白这些函数的作用或为什么需要它们
  • checkArity() 做什么?
  • SEXP args 似乎不言自明,但这是一个列表在函数调用中传递的参数?
  • SEXP op 代表什么?我将其理解为运算符(如 + 等二元函数),但 SEXP 调用 的用途是什么?

有人能理解我打字时发生的事情吗

set.seed(1)

在 R 控制台提示符下,到定义 skindnkind 的那一点?我发现我无法很好地理解这个级别的源代码以及从解释器到 C 函数的路径。

最佳答案

CARCDR 是您访问配对列表对象的方式,如 section 2.1.11 of R Language Definition 中所述。 . CAR 包含第一个元素,CDR 包含其余元素。 section 5.10.2 of Writing R Extensions 中给出了示例:

#include <R.h>
#include <Rinternals.h>

SEXP convolveE(SEXP args)
{
int i, j, na, nb, nab;
double *xa, *xb, *xab;
SEXP a, b, ab;

a = PROTECT(coerceVector(CADR(args), REALSXP));
b = PROTECT(coerceVector(CADDR(args), REALSXP));
...
}
/* The macros: */
first = CADR(args);
second = CADDR(args);
third = CADDDR(args);
fourth = CAD4R(args);
/* provide convenient ways to access the first four arguments.
* More generally we can use the CDR and CAR macros as in: */
args = CDR(args); a = CAR(args);
args = CDR(args); b = CAR(args);

还有一个 TAG 宏来访问给实际参数的名称。

checkArity 确保传递给函数的参数数量是正确的。 args 是传递给函数的实际参数。 op 是“用于处理多个 R 函数的 C 函数”的偏移指针(引用自 src/main/names.c,其中还包含显示每个函数的偏移量和元数)。

例如,do_colsum 处理 col/rowSumscol/rowMeans

/* Table of  .Internal(.) and .Primitive(.)  R functions
* ===== ========= ==========
* Each entry is a line with
*
* printname c-entry offset eval arity pp-kind precedence rightassoc
* --------- ------- ------ ---- ----- ------- ---------- ----------
{"colSums", do_colsum, 0, 11, 4, {PP_FUNCALL, PREC_FN, 0}},
{"colMeans", do_colsum, 1, 11, 4, {PP_FUNCALL, PREC_FN, 0}},
{"rowSums", do_colsum, 2, 11, 4, {PP_FUNCALL, PREC_FN, 0}},
{"rowMeans", do_colsum, 3, 11, 4, {PP_FUNCALL, PREC_FN, 0}},

请注意,上表中的 arity 是 4,因为(尽管 rowSums 等只有 3 个参数)do_colsum 有 4,这你可以从 .Internal 调用 rowSums 中看到:

> rowSums
function (x, na.rm = FALSE, dims = 1L)
{
if (is.data.frame(x))
x <- as.matrix(x)
if (!is.array(x) || length(dn <- dim(x)) < 2L)
stop("'x' must be an array of at least two dimensions")
if (dims < 1L || dims > length(dn) - 1L)
stop("invalid 'dims'")
p <- prod(dn[-(1L:dims)])
dn <- dn[1L:dims]
z <- if (is.complex(x))
.Internal(rowSums(Re(x), prod(dn), p, na.rm)) + (0+1i) *
.Internal(rowSums(Im(x), prod(dn), p, na.rm))
else .Internal(rowSums(x, prod(dn), p, na.rm))
if (length(dn) > 1L) {
dim(z) <- dn
dimnames(z) <- dimnames(x)[1L:dims]
}
else names(z) <- dimnames(x)[[1L]]
z
}

关于c - 了解如何在 R 中处理 .Internal C 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19663704/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com