Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ RcppArmadillo expmat挂起4x4矩阵_C++_R_Matrix_Rcpp_Armadillo - Fatal编程技术网

C++ RcppArmadillo expmat挂起4x4矩阵

C++ RcppArmadillo expmat挂起4x4矩阵,c++,r,matrix,rcpp,armadillo,C++,R,Matrix,Rcpp,Armadillo,我有一个病态的4x4矩阵,它使犰狳中的expmat函数挂起。病理基质为: a<-matrix(c(-2.5654e+060,4.6979e-018,2.5654e+060,7.2765e-035 ,2.8913e+000, -3.6633e+001,3.3731e+001,1.0003e-002 ,1.0656e-009,1.9037e-002, -1.9732e-001,1.7828e-001 , 0e+000, 0

我有一个病态的4x4矩阵,它使犰狳中的expmat函数挂起。病理基质为:

a<-matrix(c(-2.5654e+060,4.6979e-018,2.5654e+060,7.2765e-035
            ,2.8913e+000, -3.6633e+001,3.3731e+001,1.0003e-002
            ,1.0656e-009,1.9037e-002, -1.9732e-001,1.7828e-001
            , 0e+000, 0e+000, 0e+000, 0e+000), nrow=4, byrow=T)
我知道这个矩阵的条件很差,但R包expm中的expm函数可以使用默认算法毫无问题地处理它。在RcppArmadillo中有没有解决这个问题的方法?至少我想通过处理警告信息来避免绞刑

有一个类似的问题,但我不认为我的问题是一个复制品,因为我刚刚更新了Rcpp和RcppArmadillo在发布之前。另一个线程中的问题应该是由犰狳解决的,因此这里似乎还有其他问题。

快速观察 几点注意:

中提供的expmat算法不同于arma::expmat算法

据推测,从链接后,这是固定在4.550.4。该更改似乎已经包括在内,因为文件源3与armadillo源相同,尽管RcppArmadillo似乎跳过了点版本,例如

在编写本文时提供的实际实现是,看起来无符号int已经被修复

调试arma::expmat命令

这句话,让我们用一些调试语句快速查看幕后的内容。注意:根据API文档,我选择T作为双精度

在短调试程序上:

# include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
void run_exp_mat_routine(const arma::mat& x) {

  const double norm_val = norm(x, "inf");

  Rcpp::Rcout << "norm:" << norm_val << std::endl;

  Rcpp::Rcout << "Value of T(0):" << (double(0)) << std::endl;
  Rcpp::Rcout << "Inequality:" << (norm_val > double(0)) << std::endl;

  Rcpp::Rcout << "log2: " << std::log2(norm_val) << std::endl;

  int exponent = int(0); std::frexp(std::log2(norm_val), &exponent);

  Rcpp::Rcout << "exponent: " << exponent << std::endl;

  const arma::uword s = arma::uword( (std::max)(int(0), exponent + int(1)) );

  Rcpp::Rcout << "s: " << s << std::endl;

  const arma::mat AA = x / std::pow(2.0,s);

  Rcpp::Rcout << "AA: " <<  std::endl << AA << std::endl;

  double c = 0.5;

  arma::mat E(AA.n_rows, AA.n_rows, arma::fill::eye);  
  Rcpp::Rcout << "Init E:" << std::endl << E << std::endl; 

  E += c * AA;

  Rcpp::Rcout << "Mod E:" << std::endl <<  E << std::endl; 

  arma::mat D(AA.n_rows, AA.n_rows, arma::fill::eye); 

  Rcpp::Rcout << "Init D:" << std::endl << D << std::endl; 

  D -= c * AA;

  Rcpp::Rcout << "Mod D:" << std::endl <<  D << std::endl; 

  arma::mat X = AA;

  bool positive = true;

  const arma::uword N = 6;

  for(arma::uword i = 2; i<=N; ++i){
    c = c * double(N - i + 1) / double(i * (2*N - i + 1));

    X = AA * X;

    E += c * X;

    if(positive)  { D += c * X; }  else  { D -= c * X; }

    positive = (positive) ? false : true;

    Rcpp::Rcout << "Loop: " << i << ", c: " << c << ", positive:" << positive << std::endl;

    Rcpp::Rcout << "X: " << std::endl << X << std::endl << "E: " << std::endl << E << std::endl;
  }

  //arma::mat out = solve(D,E);

  // Rcpp::Rcout << "out:" << std::endl << out << std::endl;
  // 
  // for(arma::uword i = 0; i < s; ++i){
  //   out = out*out;
  // }


  // Rcpp::Rcout << "out: " << out <<std::endl;
}

/*** R

   a <- matrix(c(-2.5654e+060,4.6979e-018,2.5654e+060,7.2765e-035
    ,2.8913e+000, -3.6633e+001,3.3731e+001,1.0003e-002
   ,1.0656e-009,1.9037e-002, -1.9732e-001,1.7828e-001
   , 0e+000, 0e+000, 0e+000, 0e+000), nrow=4, byrow=T)


   run_exp_mat_routine(a)

 */
现在,循环部分似乎在最后一次迭代中触发了错误,例如i=6,因为数字太大,无法在双结构中表示

Loop: 2, c: 0.113636, positive:0
X: 
  2.5106e+115   1.8630e+53 -2.5106e+115   1.7447e+54
  -2.8295e+55   5.1217e-03   2.8295e+55   2.1542e-05
  -1.0428e+46  -2.6746e-06   1.0428e+46  -1.3347e-07
            0            0            0            0

E: 
  2.8529e+114   2.1170e+52 -2.8529e+114   1.9826e+53
  -3.2153e+54   9.6481e-01   3.2153e+54   1.2217e-05
  -1.1850e+45   1.8287e-05   1.1850e+45   1.7409e-04
            0            0            0   1.0000e+00

Loop: 3, c: 0.0151515, positive:1
X: 
 -1.2579e+173 -9.3347e+110  1.2579e+173 -8.7418e+111
  1.4177e+113   1.0521e+51 -1.4177e+113   9.8524e+51
  5.2251e+103   3.8774e+41 -5.2251e+103   3.6311e+42
            0            0            0            0

E: 
 -1.9059e+171 -1.4143e+109  1.9059e+171 -1.3245e+110
  2.1481e+111   1.5940e+49 -2.1481e+111   1.4928e+50
  7.9168e+101   5.8748e+39 -7.9168e+101   5.5017e+40
            0            0            0   1.0000e+00

Loop: 4, c: 0.00126263, positive:0
X: 
  6.3029e+230  4.6772e+168 -6.3029e+230  4.3801e+169
 -7.1036e+170 -5.2714e+108  7.1036e+170 -4.9366e+109
 -2.6181e+161  -1.9428e+99  2.6181e+161 -1.8194e+100
            0            0            0            0

E: 
  7.9582e+227  5.9055e+165 -7.9582e+227  5.5305e+166
 -8.9692e+167 -6.6557e+105  8.9692e+167 -6.2331e+106
 -3.3056e+158  -2.4530e+96  3.3056e+158  -2.2972e+97
            0            0            0   1.0000e+00

Loop: 5, c: 6.31313e-05, positive:1
X: 
 -3.1581e+288 -2.3435e+226  3.1581e+288 -2.1947e+227
  3.5593e+228  2.6412e+166 -3.5593e+228  2.4735e+167
  1.3118e+219  9.7344e+156 -1.3118e+219  9.1162e+157
            0            0            0            0

E: 
 -1.9937e+284 -1.4795e+222  1.9937e+284 -1.3855e+223
  2.2470e+224  1.6674e+162 -2.2470e+224  1.5616e+163
  8.2815e+214  6.1454e+152 -8.2815e+214  5.7552e+153
            0            0            0   1.0000e+00

Loop: 6, c: 1.50313e-06, positive:0
X: 
          inf  1.1742e+284         -inf  1.0997e+285
 -1.7834e+286 -1.3234e+224  1.7834e+286 -1.2394e+225
 -6.5728e+276 -4.8775e+214  6.5728e+276 -4.5677e+215
            0            0            0            0

E: 
          inf  1.7650e+278         -inf  1.6529e+279
 -2.6807e+280 -1.9892e+218  2.6807e+280 -1.8629e+219
 -9.8797e+270 -7.3314e+208  9.8797e+270 -6.8658e+209
            0            0            0   1.0000e+00
因此,无穷大符号被传递给solve参数,这将中断程序

除了运行一个单独的函数来检查矩阵是否为无穷大之外,我不确定还有其他方法,因为与其他方法相比,该算法似乎更合理。不过,我会让更有经验的人来评论这一点

编辑

使用expm::expma验证R中的输出 R中例程的快速示例:

# install.packages("expm")
library("expm")

a <- matrix(c(-2.5654e+060,4.6979e-018,2.5654e+060,7.2765e-035
              ,2.8913e+000, -3.6633e+001,3.3731e+001,1.0003e-002
              ,1.0656e-009,1.9037e-002, -1.9732e-001,1.7828e-001
              , 0e+000, 0e+000, 0e+000, 0e+000), nrow=4, byrow=T)
用MATLAB验证输出 由于这个函数应该提供类似的输出到MATLAB根据作者在链接后,让我们做快速运行

A = [-2.5654e+060,4.6979e-018,2.5654e+060,7.2765e-035;
      2.8913e+000, -3.6633e+001,3.3731e+001,1.0003e-002;
      1.0656e-009,1.9037e-002, -1.9732e-001,1.7828e-001;
      0e+000, 0e+000, 0e+000, 0e+000]
A在MATLAB中的表示形式为: A=

为了获得不是按元素指数的指数矩阵,我们使用MATLAB的:

要旨
因此,R和MATLAB版本是一致的。因此,为armadillo中的矩阵分解选择的实现可能并不理想。

更新rcpparmadillo并不等于更新armadillo,后者包含实际的算法。您使用的是哪一版本的armadillo?我如何检查armadillo的版本?我只能看到R中RcppArmadillo的版本是0.7.100.3.0。@MarcusMüller:这并不是说的那样,因为每个RcppArmadillo版本都倾向于隐藏相应的Armadillo版本——我们的0.7.100.3.*是基于Conrad的7.100.3。谢谢所有的细节。我们是否得出结论,这基本上是另一个“浮点数学”和有限精度问题?我认为这种情况下的错误肯定与浮点问题有关,因为获得了inf表示。然而,我认为它也基于犰狳中使用的指数矩阵算法,与MATLAB或R的等效算法相比,它的性能还差。感谢您进行了非常详细的调试。在算法进入无限循环之前,除了破解expmat的源代码之外,还有什么方法可以捕捉到这一点吗?在本例中,expmat抛出的警告不是运行时错误,因此我无法使用try catch截获它。或者我可以?或者只是使用expm from R.它导出函数;我在我的一个GitHub回购协议中使用它,而不是在CRAN上;还有针对它的单元测试。根据电子邮件线程,Armadillo的下一个版本提供了一个失败标志,该标志应指示“expmat”是否会由于其条件而失败
Loop: 2, c: 0.113636, positive:0
X: 
  2.5106e+115   1.8630e+53 -2.5106e+115   1.7447e+54
  -2.8295e+55   5.1217e-03   2.8295e+55   2.1542e-05
  -1.0428e+46  -2.6746e-06   1.0428e+46  -1.3347e-07
            0            0            0            0

E: 
  2.8529e+114   2.1170e+52 -2.8529e+114   1.9826e+53
  -3.2153e+54   9.6481e-01   3.2153e+54   1.2217e-05
  -1.1850e+45   1.8287e-05   1.1850e+45   1.7409e-04
            0            0            0   1.0000e+00

Loop: 3, c: 0.0151515, positive:1
X: 
 -1.2579e+173 -9.3347e+110  1.2579e+173 -8.7418e+111
  1.4177e+113   1.0521e+51 -1.4177e+113   9.8524e+51
  5.2251e+103   3.8774e+41 -5.2251e+103   3.6311e+42
            0            0            0            0

E: 
 -1.9059e+171 -1.4143e+109  1.9059e+171 -1.3245e+110
  2.1481e+111   1.5940e+49 -2.1481e+111   1.4928e+50
  7.9168e+101   5.8748e+39 -7.9168e+101   5.5017e+40
            0            0            0   1.0000e+00

Loop: 4, c: 0.00126263, positive:0
X: 
  6.3029e+230  4.6772e+168 -6.3029e+230  4.3801e+169
 -7.1036e+170 -5.2714e+108  7.1036e+170 -4.9366e+109
 -2.6181e+161  -1.9428e+99  2.6181e+161 -1.8194e+100
            0            0            0            0

E: 
  7.9582e+227  5.9055e+165 -7.9582e+227  5.5305e+166
 -8.9692e+167 -6.6557e+105  8.9692e+167 -6.2331e+106
 -3.3056e+158  -2.4530e+96  3.3056e+158  -2.2972e+97
            0            0            0   1.0000e+00

Loop: 5, c: 6.31313e-05, positive:1
X: 
 -3.1581e+288 -2.3435e+226  3.1581e+288 -2.1947e+227
  3.5593e+228  2.6412e+166 -3.5593e+228  2.4735e+167
  1.3118e+219  9.7344e+156 -1.3118e+219  9.1162e+157
            0            0            0            0

E: 
 -1.9937e+284 -1.4795e+222  1.9937e+284 -1.3855e+223
  2.2470e+224  1.6674e+162 -2.2470e+224  1.5616e+163
  8.2815e+214  6.1454e+152 -8.2815e+214  5.7552e+153
            0            0            0   1.0000e+00

Loop: 6, c: 1.50313e-06, positive:0
X: 
          inf  1.1742e+284         -inf  1.0997e+285
 -1.7834e+286 -1.3234e+224  1.7834e+286 -1.2394e+225
 -6.5728e+276 -4.8775e+214  6.5728e+276 -4.5677e+215
            0            0            0            0

E: 
          inf  1.7650e+278         -inf  1.6529e+279
 -2.6807e+280 -1.9892e+218  2.6807e+280 -1.8629e+219
 -9.8797e+270 -7.3314e+208  9.8797e+270 -6.8658e+209
            0            0            0   1.0000e+00
# install.packages("expm")
library("expm")

a <- matrix(c(-2.5654e+060,4.6979e-018,2.5654e+060,7.2765e-035
              ,2.8913e+000, -3.6633e+001,3.3731e+001,1.0003e-002
              ,1.0656e-009,1.9037e-002, -1.9732e-001,1.7828e-001
              , 0e+000, 0e+000, 0e+000, 0e+000), nrow=4, byrow=T)
             [,1]       [,2]      [,3]      [,4]
[1,] 2.403680e-62 0.02132743  1.369318 0.1998306
[2,] 1.543272e-60 1.36931834 41.028506 3.4698436
[3,] 2.403680e-62 0.02132743  1.369318 0.1998306
[4,] 0.000000e+00 0.00000000  0.000000 1.0000000
A = [-2.5654e+060,4.6979e-018,2.5654e+060,7.2765e-035;
      2.8913e+000, -3.6633e+001,3.3731e+001,1.0003e-002;
      1.0656e-009,1.9037e-002, -1.9732e-001,1.7828e-001;
      0e+000, 0e+000, 0e+000, 0e+000]
   1.0e+60 *

   -2.5654    0.0000    2.5654    0.0000
    0.0000   -0.0000    0.0000    0.0000
    0.0000    0.0000   -0.0000    0.0000
         0         0         0         0
ans =

    0.0000    0.0213    1.3693    0.1998
    0.0000    1.3693   41.0285    3.4698
    0.0000    0.0213    1.3693    0.1998
         0         0         0    1.0000