在 Rcpp 中为 Galerkin 矩阵使用 Eigen c++ 库的问题
Problems using Eigen c++ library in Rcpp for Galerkin Matrix
我正在尝试在 RStudio 中编写以下 C++ 代码。
// [[Rcpp::depends(RcppEigen)]]
#include <RcppEigen.h>
using namespace Rcpp;
// [[Rcpp::export]]
#include <iostream>
#include <cmath>
using Eigen::Dense;
using Eigen::SparseLU;
using Eigen::Sparse;
using Eigen::SparseMatrix;
using namespace std;
Eigen::SparseMatrix<double> getGalMat(int N) {
// Note: N hast to bigger or equal to 5!!!
assert(N >= 5);
typedef Eigen::SparseMatrix<double>::Index index_t;
typedef Eigen::Triplet<double> triplet_t;
std::vector<triplet_t> triplets;
// reserve "minimal" vector size (the number of non-zero entries)
triplets.reserve(5*N - 6);
// N minus 1
int Nm = N - 1;
// set the (off-) diagonals
double diag_m2 = + 16;
double diag_m1 = - 64;
double diag = + 96;
double diag_p1 = - 64;
double diag_p2 = + 16;
// set first and last 2 rows by hand
// A(1 ,:)
triplets.push_back({0 ,0 ,diag }); // A(1,1)
triplets.push_back({0 ,1 ,diag_p1}); // A(1,2)
triplets.push_back({0 ,2 ,diag_p2}); // A(1,3)
// A(2 ,:)
triplets.push_back({1 ,0 ,diag_m1}); // A(2,1)
triplets.push_back({1 ,1 ,diag }); // A(2,2)
triplets.push_back({1 ,2 ,diag_p1}); // A(2,3)
triplets.push_back({1 ,3 ,diag_p2}); // A(2,4)
// A(N-1,:)
triplets.push_back({Nm-1,Nm-3,diag_m2}); // A(N-1,N-3)
triplets.push_back({Nm-1,Nm-2,diag_m1}); // A(N-1,N-2)
triplets.push_back({Nm-1,Nm-1,diag }); // A(N-1,N-1)
triplets.push_back({Nm-1,Nm ,diag_p1}); // A(N-1,N )
// A(N ,:)
triplets.push_back({Nm ,Nm-2,diag_m2}); // A(N,N-2)
triplets.push_back({Nm ,Nm-1,diag_m1}); // A(N,N-1)
triplets.push_back({Nm ,Nm ,diag }); // A(N,N )
// loop over remaining rows
for (int i = 2; i < Nm-1; i++) {
triplets.push_back({i,i-2,diag_m2}); // A(i,i-2)
triplets.push_back({i,i-1,diag_m1}); // A(i,i-1)
triplets.push_back({i,i ,diag }); // A(i,i )
triplets.push_back({i,i+1,diag_p1}); // A(i,i+1)
triplets.push_back({i,i+2,diag_p2}); // A(i,i+2)
}
// let EIGEN build the sparse matrix from our triplets
Eigen::SparseMatrix<double> spMat(N,N);
spMat.setFromTriplets(triplets.begin(), triplets.end());
// return
return spMat;
}
当运行时,我从第 41 行 onwords 得到一长串错误,对应于:
triplets.push_back({0 ,0 ,diag }); // A(1,1)
出现错误:'extended initializer lists only available with -std=c++0x or -std=gnu++0x [enabled by default]'
有人有什么建议吗?
在此先感谢您的帮助。
该脚本使用的语法要求比 c++98 更高的 C++ 标准。要解决此问题,有两种方法可以解决此问题。
启用 C++11,因为 R 支持使用 C++11 Rcpp 插件在 C++98 或 C++11 下进行编译。这是解决此问题的首选方法。将以下内容添加到您的 cpp 代码的顶部:
// [[Rcpp::plugins(cpp11)]]
此修复不可移植(不随代码文件移动)并且是基于会话的,因此必须在每个新会话中重复或在 .Rprofile
中设置.这设置了 ~/.R/Makevars
中常见的编译标志
Sys.setenv("PKG_CXXFLAGS"="-std=c++11")
由于您似乎无法启用 C++11,替代方法是使代码与 C++98 兼容。而不是:
triplets.push_back({0 ,0 ,diag }); // A(1,1)
显式使用构造函数:
triplets.push_back(triplet_t(0 ,0 ,diag )); // A(1,1)
我正在尝试在 RStudio 中编写以下 C++ 代码。
// [[Rcpp::depends(RcppEigen)]]
#include <RcppEigen.h>
using namespace Rcpp;
// [[Rcpp::export]]
#include <iostream>
#include <cmath>
using Eigen::Dense;
using Eigen::SparseLU;
using Eigen::Sparse;
using Eigen::SparseMatrix;
using namespace std;
Eigen::SparseMatrix<double> getGalMat(int N) {
// Note: N hast to bigger or equal to 5!!!
assert(N >= 5);
typedef Eigen::SparseMatrix<double>::Index index_t;
typedef Eigen::Triplet<double> triplet_t;
std::vector<triplet_t> triplets;
// reserve "minimal" vector size (the number of non-zero entries)
triplets.reserve(5*N - 6);
// N minus 1
int Nm = N - 1;
// set the (off-) diagonals
double diag_m2 = + 16;
double diag_m1 = - 64;
double diag = + 96;
double diag_p1 = - 64;
double diag_p2 = + 16;
// set first and last 2 rows by hand
// A(1 ,:)
triplets.push_back({0 ,0 ,diag }); // A(1,1)
triplets.push_back({0 ,1 ,diag_p1}); // A(1,2)
triplets.push_back({0 ,2 ,diag_p2}); // A(1,3)
// A(2 ,:)
triplets.push_back({1 ,0 ,diag_m1}); // A(2,1)
triplets.push_back({1 ,1 ,diag }); // A(2,2)
triplets.push_back({1 ,2 ,diag_p1}); // A(2,3)
triplets.push_back({1 ,3 ,diag_p2}); // A(2,4)
// A(N-1,:)
triplets.push_back({Nm-1,Nm-3,diag_m2}); // A(N-1,N-3)
triplets.push_back({Nm-1,Nm-2,diag_m1}); // A(N-1,N-2)
triplets.push_back({Nm-1,Nm-1,diag }); // A(N-1,N-1)
triplets.push_back({Nm-1,Nm ,diag_p1}); // A(N-1,N )
// A(N ,:)
triplets.push_back({Nm ,Nm-2,diag_m2}); // A(N,N-2)
triplets.push_back({Nm ,Nm-1,diag_m1}); // A(N,N-1)
triplets.push_back({Nm ,Nm ,diag }); // A(N,N )
// loop over remaining rows
for (int i = 2; i < Nm-1; i++) {
triplets.push_back({i,i-2,diag_m2}); // A(i,i-2)
triplets.push_back({i,i-1,diag_m1}); // A(i,i-1)
triplets.push_back({i,i ,diag }); // A(i,i )
triplets.push_back({i,i+1,diag_p1}); // A(i,i+1)
triplets.push_back({i,i+2,diag_p2}); // A(i,i+2)
}
// let EIGEN build the sparse matrix from our triplets
Eigen::SparseMatrix<double> spMat(N,N);
spMat.setFromTriplets(triplets.begin(), triplets.end());
// return
return spMat;
}
当运行时,我从第 41 行 onwords 得到一长串错误,对应于:
triplets.push_back({0 ,0 ,diag }); // A(1,1)
出现错误:'extended initializer lists only available with -std=c++0x or -std=gnu++0x [enabled by default]'
有人有什么建议吗?
在此先感谢您的帮助。
该脚本使用的语法要求比 c++98 更高的 C++ 标准。要解决此问题,有两种方法可以解决此问题。
启用 C++11,因为 R 支持使用 C++11 Rcpp 插件在 C++98 或 C++11 下进行编译。这是解决此问题的首选方法。将以下内容添加到您的 cpp 代码的顶部:
// [[Rcpp::plugins(cpp11)]]
此修复不可移植(不随代码文件移动)并且是基于会话的,因此必须在每个新会话中重复或在
中常见的编译标志.Rprofile
中设置.这设置了~/.R/Makevars
Sys.setenv("PKG_CXXFLAGS"="-std=c++11")
由于您似乎无法启用 C++11,替代方法是使代码与 C++98 兼容。而不是:
triplets.push_back({0 ,0 ,diag }); // A(1,1)
显式使用构造函数:
triplets.push_back(triplet_t(0 ,0 ,diag )); // A(1,1)