【问题标题】:Problems using Eigen c++ library in Rcpp for Galerkin Matrix在 Rcpp 中为 Galerkin 矩阵使用 Eigen c++ 库的问题
【发布时间】:2016-03-22 16:48:11
【问题描述】:

我正在尝试在 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 行开始有一长串错误,对应于:

triplets.push_back({0   ,0   ,diag   }); // A(1,1)

得到错误:'扩展初始化列表仅适用于 -std=c++0x 或 -std=gnu++0x [默认启用]'

有人有建议吗?

提前感谢您的帮助。

【问题讨论】:

    标签: c++ rcpp eigen pde


    【解决方案1】:

    脚本使用的语法要求比 c++98 更高的 C++ 标准。要解决此问题,有两种方法可以解决此问题。

    1. 启用 C++11,因为 R 支持在 C++98 下编译或使用 C++11 Rcpp 插件在 C++11 下编译。这是解决此问题的首选方法。将以下内容添加到您的 cpp 代码的顶部:

      // [[Rcpp::plugins(cpp11)]]
      
    2. 此修复是不可移植的(不随代码文件一起移动)并且是基于会话的,因此必须在每个新会话中重复或在.Rprofile 中设置。这会设置一个在~/.R/Makevars 中常见的编译标志

      Sys.setenv("PKG_CXXFLAGS"="-std=c++11")
      

    【讨论】:

    • 正确,但不是“和”——它是“或”。任何一种方法都可以,第二种方法更可取,因为它与代码保持一致。
    • 非常感谢您的提示。它有效,但我仍然有另一个错误消息。不幸的是,我仍然无法在 RStudio 中编译我的代码。我有以下错误:“log4cplus:ERROR file is not open”和“cc1plus.exe: error: unrecognized command line option '-std=c++11'”
    • 编译器缺乏 C++11 支持。如果在 Windows 上,您使用的是最新的 Rtools 吗?
    • 不幸的是,我只有旧版本的 Rtools,无法安装新版本。有没有其他选择?顺便说一句,我需要使用 Rcpp11 包吗?
    • 不,Rcpp11包与此无关。
    【解决方案2】:

    由于您似乎无法启用 C++11,因此另一种方法是使代码与 C++98 兼容。而不是:

    triplets.push_back({0   ,0   ,diag   }); // A(1,1)
    

    显式使用构造函数:

    triplets.push_back(triplet_t(0   ,0   ,diag   )); // A(1,1)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多