了解。内部C函数是如何R中处理 [英] Understanding how .Internal C functions are handled in R

查看:349
本文介绍了了解。内部C函数是如何R中处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道是否有人能说明我如何ř执行从控制台提示符下键入的R命令 C 电话。我特别研究's的)函数的参数处理和b)函数调用本身混淆。

I wonder if anyone can illustrate to me how R executes a C call from an R command typed at the console prompt. I am particularly confused by R's treatment of a) function arguments and b) the function call itself.

让我们看一个例子,在这种情况下, set.seed()。想知道它是如何工作我在提示符下键入名称,获取源( 看看这里的更多的是 ),看到有一个最终。内部(set.seed(种子,i.knd,normal.kind),这样尽职尽责地查找相关的函数名在 /src/names.c .Internals 部分中,找到它被称为 do_setseed ,并在 RNG.c 这使我...

Let's take an example, in this case set.seed(). Wondering how it works I type the name in at the prompt, get the source (look here for more on that), see there is eventually a .Internal(set.seed(seed, i.knd, normal.kind), so dutifully look up the relevant function name in the .Internals section of /src/names.c, find it is called do_setseed and is in RNG.c which leads me to...

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;
}


  • 什么是 CAR CADR CADDR ?我的研究使我相信他们就列出了 Lisp语言影响结构但除此之外,我不明白这些功能做或为什么他们需要

  • 这是什么 checkArity()吗?

  • SEXP ARGS 似乎言自明,但是这是的名单
    即在函数调用中传递的参数?

  • 这是什么 SEXP运重新present?我认为这意味着运营商(如二进制功能,如 + ),但是又是什么 SEXP通话的?

    • What are CAR, CADR, CADDR? My research leads me to believe they are a Lisp influenced construct concerning lists but beyond that I do not understand what these functions do or why they are needed.
    • What does checkArity() do?
    • SEXP args seems self explanatory, but is this a list of the arguments that is passed in the function call?
    • What does SEXP op represent? I take this to mean operator (like in binary functions such as +), but then what is the SEXP call for?
    • 是任何人都可以通过键入时会发生什么流程

      Is anyone able to flow through what happens when I type

      set.seed(1)
      

      在R控制台提示符下,到在哪个点 skind nkind 的定义?我发现我不能够很好的理解在这个级别和路径从内部preTER到C函数的源$ C ​​$ C。

      at the R console prompt, up to the point at which skind and nkind are defined? I find I am not able to well understand the source code at this level and path from interpreter to C function.

      推荐答案

      CAR CDR 是如何访问成对列表对象,如部分介绍的研究语言定义的2.1.11 CAR 中包含的第一个元素,而 CDR 包含剩余的元素。一个例子中的写作R附加的 5.10.2节

      CAR and CDR are how you access pairlist objects, as explained in section 2.1.11 of R Language Definition. CAR contains the first element, and CDR contains the remaining elements. An example is given in 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);
      

      还有一个标记宏来访问给予实际的参数的名字。

      There's also a TAG macro to access the names given to the actual arguments.

      checkArity 确保了传递给函数的参数个数是否正确。 ARGS 是传递给函数的实际参数。 是用于C函数,与一个以上的R函数处理(从的src / main / names.c ,其中也包含显示每个功能的偏移和元数表)。

      checkArity ensures that the number of arguments passed to the function is correct. args are the actual arguments passed to the function. op is offset pointer "used for C functions that deal with more than one R function" (quoted from src/main/names.c, which also contains the table showing the offset and arity for each function).

      例如, do_colsum 手柄 COL / rowSums COL / 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}},
      

      注意元数在上表是4,因为(即使 rowSums 等人只能有3个参数) do_colsum 有4个,你可以从 rowSums 。内部呼叫见C $ C>:

      Note that arity in the above table is 4 because (even though rowSums et al only have 3 arguments) do_colsum has 4, which you can see from the .Internal call in 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中处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆