programing

방법을 이해합니다.내부 C 함수는 R에서 처리됩니다.

cafebook 2023. 7. 22. 10:25
반응형

방법을 이해합니다.내부 C 함수는 R에서 처리됩니다.

R이 어떻게 실행되는지 설명할 수 있는 사람이 있는지 궁금합니다.C콘솔 프롬프트에 입력된 R 명령에서 호출합니다.나는 특히 혼란스럽습니다.Ra) 함수 인수 및 b) 함수 호출 자체에 대한 처리.

예를 들어, 이 경우에set.seed()어떻게 작동하는지 궁금하면 프롬프트에 이름을 입력하고 출처를 확인합니다(자세한 내용여기를 참조하십시오). 결국에는 다음이 있습니다..Internal(set.seed(seed, i.knd, normal.kind)그래서 의무적으로 관련 기능 이름을 찾습니다..Internals의 일부./src/names.c라는 것을 알게 됩니다.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;
}
  • 무엇이CAR,CADR,CADDR제 연구를 통해 그들이Lisp목록과 관련된 구조에 영향을 미쳤지만 그 이상으로 저는 이러한 기능이 무엇을 하는지 또는필요한지 이해하지 못합니다.
  • 무엇인가.checkArity()하십니까?
  • SEXP args자체적으로 설명하는 것처럼 보이지만, 함수 호출에서 전달되는 인수의 목록입니까?
  • 무엇인가.SEXP op대표?나는 이것을 연산자를 의미한다(예: 2진수 함수에서).+), 하지만 그렇다면 무엇입니까?SEXP call왜요?

내가 입력할 때 발생하는 일을 누구나 이해할 수 있습니까?

set.seed(1)

R 콘솔 프롬프트에서 다음 시점까지skind그리고.nkind정의되었습니까?저는 이 수준에서 소스 코드를 잘 이해할 수 없고 인터프리터에서 C 함수로의 경로를 찾을 수 없습니다.

CAR그리고.CDRR 언어 정의의 섹션 2.1.11에서 설명한 대로 쌍 목록 개체에 액세스하는 방법입니다.CAR첫 번째 요소를 포함합니다.CDR나머지 요소를 포함합니다.예제는 쓰기 R 확장섹션 5.10.2에 나와 있습니다.

#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/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}},

참고:arity위의 표에서 4는 다음과 같은 이유로rowSums등에는 인수가 3개만 있습니다.)do_colsum4개를 가지고 있는데, 당신은 그것을 볼 수 있습니다..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-수준 쌍 리스트 추출 함수는 다음과 같습니다.CAR그리고.CDR(쌍 목록은 목록과 매우 유사하지만 링크된 목록으로 구현되며 내부적으로 인수 목록에 사용됩니다.)R 등가물을 있습니다: 이은단한순을참조 R등물십시오하가들오.x[[1]]그리고.x[-1]R은 또한 다음과 같은 두 가지의 많은 조합을 제공합니다.

  • CAAR(x) = CAR(CAR(x))는 와동한등에 합니다.x[[1]][[1]]
  • CADR(x) = CAR(CDR(x))는 와동한등에 합니다.x[-1][[1]]를 들어, 예를 들어, 예를 들어,x[[2]]
  • CADDR(x) = CAR(CDR(CDR(x))는 와동합다니등다에 합니다.x[-1][-1][[1]]를 들어, 예를 들어, 예를 들어,x[[3]]
  • 등등

에 액세스하는 은 쌍목번의액하는것스은입니다.O(n)조작, 목록의 n번째 요소에 접근하는 것과 달리.O(1)이것이 쌍 목록의 n번째 요소에 액세스하기 위한 더 좋은 기능이 없는 이유입니다.

내부/원시 함수는 이름으로 일치하지 않고 위치 일치만 사용하므로 인수를 추출하는 데 이 간단한 시스템을 사용할 수 있습니다.

다음으로 C 함수에 대한 인수가 무엇인지 이해해야 합니다.이 문서가 어디에 문서화되어 있는지 잘 모르기 때문에 구조에 대해 완전히 정확하지는 않을 수 있지만 일반적인 내용은 다음과 같습니다.

  • call에 의해 포착될 수 있는 완전한 통화.match.call()

  • op에서 입니다.R에서 내부 함수가 호출되었습니다.한 이유는 1의 다대1 입니다.C 함수에 대한 내부 함수.(예:do_summarysum, mean, min, max 및 prod)가 있습니다. 번호는 는다세번항다니목입째음의의 세 입니다.names.c의 경 항 입 상 니 0 다 우 다 ▁for ▁0 입 ▁it 니' ▁always 0 sdo_setseed 안 써요.

  • args함수에 제공된 인수 쌍 목록입니다.

  • env함수가 호출된 환경입니다.

checkArity는 를호는매니다입크로하출▁which를 부르는 입니다.Rf_checkArityCall기본적으로 인수의 수를 검색합니다(의 다섯 번째 열).names.c입력한 숫자가 일치하는지 확인합니다.무슨 일이 일어나고 있는지 보려면 C에서 꽤 많은 매크로와 기능을 따라야 합니다. 당신이 훑어볼 수 있는 R-소스의 로컬 복사본을 갖는 것은 매우 유용합니다.

언급URL : https://stackoverflow.com/questions/19663704/understanding-how-internal-c-functions-are-handled-in-r

반응형