r - 检测和“分离”二进制表达式的 C 方法
问题描述
我的代码在表达式中遇到瓶颈,例如any(x >= b | x == y)
大型x
.
我想避免分配x >= b | x == y
。我发现为特定情况编写函数很容易。
SEXP eval_any_or2(SEXP x, SEXP b, SEXP y) {
R_xlen_t N = xlength(x);
if (xlength(y) != N || xlength(b) != 1) {
error("Wrong lengths.");
}
const int *xp = INTEGER(x);
const int *yp = INTEGER(y);
const int *bp = INTEGER(b);
bool o = false;
for (R_xlen_t i = 0; i < N; ++i) {
if (xp[i] >= bp[0] || xp[i] == yp[i]) {
o = true;
break;
}
}
SEXP ans = PROTECT(allocVector(LGLSXP, 1));
LOGICAL(ans)[0] = o ? TRUE : FALSE;
UNPROTECT(1);
return ans;
}
但是,为了清楚起见,我想尽可能多地保留自然语法,例如any_or(x >= b, x == y)
. 所以我希望能够检测一个调用是否是标准二元运算符之一的形式<vector> <operator> <vector>
,<operator>
并且每个<vector>
都是等长向量长度 1。像这样:
any_or2 <- function(expr1, expr2) {
sexp1 <- substitute(expr1)
sexp2 <- substitute(expr2)
if (!is_binary_sexp(sexp1) || !is_binary_sexp(sexp2) {
# fall through to just basic R
return(any(expr1 | expr2))
}
# In C
eval_any_or2(...) # either the substituted expression or x,y,b
}
我尝试了以下 C 函数来检测替换的表达式/调用是否是二进制表达式,但是(a)我无法检测运算符是否是二进制运算符,并且(b)从表达式(x
,y
,b
在示例中)以供稍后使用(在同一个 C 函数中或传递给与上述 C 函数类似的 C 函数)。
#define return_false SEXP ans = PROTECT(allocVector(LGLSXP, 1)); \
LOGICAL(ans)[0] = FALSE; \
UNPROTECT(1); \
return ans; \
SEXP is_binary_sexp(SEXP sx) {
if (TYPEOF(sx) != LANGSXP) {
return_false
}
// does it have three elements?
int len = 0;
SEXP el, nxt;
for (nxt = sx; nxt != R_NilValue || len > 4; el = CAR(nxt), nxt = CDR(nxt)) {
len++;
}
if (len != 3) {
return_false;
}
if (TYPEOF(CAR(sx)) != SYMSXP) {
return_false;
}
SEXP ans = PROTECT(allocVector(LGLSXP, 1));
LOGICAL(ans)[0] = TRUE;
UNPROTECT(1);
return ans;
}
在 RI 中会写如下内容:
is_binary_sexp_R <- function(sexprA) {
# sexprA is the result of substitute()
is.call(sexprA) &&
length(sexprA) == 3L &&
match(as.character(sexprA[[1]]), c("!=", "==", "<=", ">=", "<", ">"), nomatch = 0L) &&
is.name(lhs <- sexprA[[2L]])
}
但我想在 C 中尽可能多地做。
解决方案
推荐阅读
- c# - 启动另一个后台应用程序的后台应用程序
- python-3.x - 使用网格我如何不让框架相互推开
- sql - 如何将本地路径中的 JSON 文件数据保存到 SQL 表中?
- python - 列出项目并在这些项目中输入信息
- html - 背景色调覆盖不会在滚动时扩展
- sorting - 合并第二列时对第一列进行排序
- square-connect - Sqaure 支付网关结帐 API CORS 问题
- blockchain - 如何在私有恒星区块链网络中进行交易?
- javascript - 从选择框调用 JS 函数
- java - NoClassDefFound - org/apache/kafka/clients/producer/KafkaProducer