Agent-almanac add-rcpp-integration
install
source · Clone the upstream repo
git clone https://github.com/pjt222/agent-almanac
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/pjt222/agent-almanac "$T" && mkdir -p ~/.claude/skills && cp -r "$T/i18n/wenyan-ultra/skills/add-rcpp-integration" ~/.claude/skills/pjt222-agent-almanac-add-rcpp-integration-265f00 && rm -rf "$T"
manifest:
i18n/wenyan-ultra/skills/add-rcpp-integration/SKILL.mdsource content
接 Rcpp
入 C++ 於 R 包以速關行。
用
- R 函慢、剖證瓶→用
- 接既有 C/C++ 庫→用
- 算(環、遞)益於編→用
- 增 RcppArmadillo 為線代→用
入
- 必:既存 R 包
- 必:欲代或補之 R 函
- 可:欲接之外 C++ 庫
- 可:用 RcppArmadillo 否(默純 Rcpp)
行
一:設 Rcpp 基
usethis::use_rcpp()
此:
- 建
src/ - 入
於 LinkingTo 與 ImportsRcpp - 建
含R/packagename-package.R
與@useDynLib@importFrom Rcpp sourceCpp - 更
避編檔.gitignore
RcppArmadillo:
usethis::use_rcpp_armadillo()
得:
src/ 已建,DESCRIPTION 含 Rcpp 於 LinkingTo 與 Imports,R/packagename-package.R 含 @useDynLib。
敗:
usethis::use_rcpp() 敗→手建 src/、入 LinkingTo: Rcpp 與 Imports: Rcpp 於 DESCRIPTION,入 #' @useDynLib packagename, .registration = TRUE 與 #' @importFrom Rcpp sourceCpp 於包級文。
二:書 C++ 函
建
src/my_function.cpp:
#include <Rcpp.h> using namespace Rcpp; //' Compute cumulative sum efficiently //' //' @param x A numeric vector //' @return A numeric vector of cumulative sums //' @export // [[Rcpp::export]] NumericVector cumsum_cpp(NumericVector x) { int n = x.size(); NumericVector out(n); out[0] = x[0]; for (int i = 1; i < n; i++) { out[i] = out[i - 1] + x[i]; } return out; }
RcppArmadillo:
#include <RcppArmadillo.h> // [[Rcpp::depends(RcppArmadillo)]] //' Matrix multiplication using Armadillo //' //' @param A A numeric matrix //' @param B A numeric matrix //' @return The matrix product A * B //' @export // [[Rcpp::export]] arma::mat mat_mult(const arma::mat& A, const arma::mat& B) { return A * B; }
得:C++ 源於
src/my_function.cpp,含有效 // [[Rcpp::export]] 與 //' 註。
敗:驗檔用
#include <Rcpp.h>(Armadillo 用 <RcppArmadillo.h>),出註於函簽前獨行,返型映 Rcpp 有效型。
三:生 RcppExports
Rcpp::compileAttributes() devtools::document()
得:
R/RcppExports.R 與 src/RcppExports.cpp 自生。
敗:察 C++ 語誤。確
// [[Rcpp::export]] 標於各出函上。
四:驗編
devtools::load_all()
得:包編、載而無誤。
敗:察編出。常症:缺系頭→裝開發庫;語誤→C++ 編訊指行;缺
Rcpp::depends 屬於 RcppArmadillo。
五:書測編
test_that("cumsum_cpp matches base R", { x <- c(1, 2, 3, 4, 5) expect_equal(cumsum_cpp(x), cumsum(x)) }) test_that("cumsum_cpp handles edge cases", { expect_equal(cumsum_cpp(numeric(0)), numeric(0)) expect_equal(cumsum_cpp(c(NA_real_, 1)), c(NA_real_, NA_real_)) })
得:測過,證 C++ 函果同 R 等且妥處邊例(空向、NA)。
敗:NA 測敗→於 C++ 加
NumericVector::is_na() 之檢。空入測敗→於函首加零長守。
六:增清腳
建
src/Makevars:
PKG_CXXFLAGS = -O2
建
cleanup 於包根(為 CRAN):
#!/bin/sh rm -f src/*.o src/*.so src/*.dll
可行:
chmod +x cleanup
得:
src/Makevars 設編旗,cleanup 去編對。皆於包根。
敗:驗
cleanup 有可行權(chmod +x cleanup),Makevars 用製表(非空)若加 Makefile 規。
七:更 .Rbuildignore
確編產妥處:
^src/.*\.o$ ^src/.*\.so$ ^src/.*\.dll$
得:
.Rbuildignore 紋阻編對檔入包包,存源檔與 Makevars。
敗:行
devtools::check() 察 NOTE 關 src/ 中意外檔。調紋唯排 .o、.so、.dll。
驗
-
編無警devtools::load_all() - 編函出正果
- 邊例(NA、空、巨)測過
-
過無編警R CMD check - RcppExports 已生且提
- 性能改以基準證
忌
- 忘
:改 C++ 後須重生 RcppExportscompileAttributes() - 整溢:大數用
非doubleint - 記理:Rcpp 自理 Rcpp 型;勿手
delete - NA 處:C++ 不知 R 之 NA。用
檢Rcpp::NumericVector::is_na() - 跨台:避台專 C++ 特。測於 Windows、macOS、Linux
- 缺
:包級文須含@useDynLib@useDynLib packagename, .registration = TRUE
參
— 增 Rcpp 前包設create-r-package
— 測編函write-testthat-tests
— CI 須有 C++ 工setup-github-actions-ci
— 編包需 CRAN 加察submit-to-cran