使用犰狳访问下三角元素的更有效方法
More efficient way to access lower triangular elements using Armadillo
是否有更有效的方法来创建包含矩阵下三角元素的向量?对于某些算法,将这些元素放在一个向量中是很有用的。
但是,当我更喜欢指针时,下面的代码显然会创建副本。考虑到元素位置的非连续性,这可能是不可能的。
我考虑过的一种替代方法是通过 find(trimatu(inmat)!=0)
左右创建索引矩阵,但我无法想象那样会更有效率。在双精度矩阵中找到精确的零通常不是很快,而且在我试图提取的三角形中也可能有实际的 0。
这里已经讨论了这些方面的内容(C++ Armadillo Access Triangular Matrix Elements),但是,这个问题已经有 5 年历史了,犰狳从那时起有了很大的改进。
vec trimat2vec(mat const& inmat){
int K = inmat.n_rows;
int p = K*(K-1)/2;
vec out(p);
int counter=0;
for(int i=0; i<K; i++){
for(int j=1; j<K; j++){
if(i<j){
out(counter)=inmat(j,i);
counter+=1;
}
}
}
return(out);
}
好的,有了新版本 Armadillo 9.870,现在有更好的方法来执行此操作。速度提高很小,尤其是在小矩阵上,但似乎是一致的。更重要的是,代码要短得多。
我调用新函数trimat2vec_new
。
vec trimat2vec_new(mat const& inmat){
return(inmat.elem(trimatl_ind(size(inmat),-1)));
}
R 中的简单基准测试:
a=matrix(1:900,30,30)
all(trimat2vec_new(a) == trimat2vec(a))
library(microbenchmark)
microbenchmark(trimat2vec_new(a),
trimat2vec(a),
times = 1000)
产量:
Unit: microseconds
expr min lq mean median uq max neval cld
trimat2vec_new(a) 3.026 3.4060 3.633960 3.557 3.727 20.549 1000 a
trimat2vec(a) 3.116 3.6515 3.955116 3.787 3.958 42.981 1000 b
我特别喜欢新 trimatl_ind
功能带来的便利。以及速度的小幅提升。
是否有更有效的方法来创建包含矩阵下三角元素的向量?对于某些算法,将这些元素放在一个向量中是很有用的。
但是,当我更喜欢指针时,下面的代码显然会创建副本。考虑到元素位置的非连续性,这可能是不可能的。
我考虑过的一种替代方法是通过 find(trimatu(inmat)!=0)
左右创建索引矩阵,但我无法想象那样会更有效率。在双精度矩阵中找到精确的零通常不是很快,而且在我试图提取的三角形中也可能有实际的 0。
这里已经讨论了这些方面的内容(C++ Armadillo Access Triangular Matrix Elements),但是,这个问题已经有 5 年历史了,犰狳从那时起有了很大的改进。
vec trimat2vec(mat const& inmat){
int K = inmat.n_rows;
int p = K*(K-1)/2;
vec out(p);
int counter=0;
for(int i=0; i<K; i++){
for(int j=1; j<K; j++){
if(i<j){
out(counter)=inmat(j,i);
counter+=1;
}
}
}
return(out);
}
好的,有了新版本 Armadillo 9.870,现在有更好的方法来执行此操作。速度提高很小,尤其是在小矩阵上,但似乎是一致的。更重要的是,代码要短得多。
我调用新函数trimat2vec_new
。
vec trimat2vec_new(mat const& inmat){
return(inmat.elem(trimatl_ind(size(inmat),-1)));
}
R 中的简单基准测试:
a=matrix(1:900,30,30)
all(trimat2vec_new(a) == trimat2vec(a))
library(microbenchmark)
microbenchmark(trimat2vec_new(a),
trimat2vec(a),
times = 1000)
产量:
Unit: microseconds
expr min lq mean median uq max neval cld
trimat2vec_new(a) 3.026 3.4060 3.633960 3.557 3.727 20.549 1000 a
trimat2vec(a) 3.116 3.6515 3.955116 3.787 3.958 42.981 1000 b
我特别喜欢新 trimatl_ind
功能带来的便利。以及速度的小幅提升。