首页 > 解决方案 > Rcpp:检索和替换方阵的非对角线值

问题描述

使用 Rcpp/Armadillo,如何有效地提取/替换方阵的非对角线值?在 R 中,它可以使用:old_values = A[row(A) == (col(A) - k)]; A[row(A) == (col(A) - k)] = new_values. 使用 Armadillo,可以使用 for 循环(见下文)来实现此目标。但是有没有更简单的方法来编写代码?由于我需要对所有k大矩阵(> 10000 行,> 10000 列)执行此操作,因此最好考虑效率。这是一个可重现的示例:

A = matrix(1:25, 5, 5) 

A[row(A) == (col(A) - 3)] # extract the 3rd off-diagnal values
A[row(A) == (col(A) - 2)] = -5 of # replace the 2nd off-diagnal values with -5

使用 for 循环的 cpp 代码:

arma::vec retrieve_off_diag_values( arma::mat A, unsigned k )
    {
        unsigned n_cols = A.n_cols;
        arma::vec off_diag_values(n_cols - k);
        for( unsigned i=0; i <(n_cols - k); i++ )
        {
            off_diag_values(i) = A(i, i+k);
        } 
        return off_diag_values;
    } 

标签: rrcpparmadillo

解决方案


要将指定对角线中的值提取到向量中,其中 k < 0 表示次对角线,k = 0 表示主对角线,k > 0 表示超对角线:

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

// [[Rcpp::export]]
arma::vec diag_get(const arma::mat& X, int k)   // note the 'const' and '&'
{
    return X.diag(k);
}

要将对角线上的值设置为特定值:

// [[Rcpp::export]]
void diag_fill(arma::mat& X, int k, double value)   // note the '&' character
{
    X.diag(k).fill(value);
}

要将对角线上的特定值的实例更改为另一个值:

// [[Rcpp::export]]
void diag_change(arma::mat& X, int k, double old_value, double new_value)
{
    X.diag(k).replace(old_value, new_value);
}

推荐阅读