我一直在研究一种从大型稀疏(ish)矩阵中去除非零元素的算法,作为一种减少数值解的计算时间到大型耦合ODE系统的方法。 logistic equation。
基本思想是,每T个时间步,您可以评估状态矩阵B中的哪些元素大于某个阈值。对于那些被认为无关紧要(即低于阈值)的人,你在稀疏交互矩阵A中删除(设置为零)相关的行/列,这样AxB的计算将需要更少的触发器。(注意,对角线保持非零,所以状态矩阵的相关元素不会爆炸)
算法如下:
通过B向量扫描少于阈值和记录位置的元素
迭代A矩阵的非零元素,对应于1中记录的位置并记录位置
我需要分离步骤2.和3.因为如果将稀疏矩阵(arma :: sp_mat)的非零元素设置为零,则会破坏迭代器,因此无法实现结果单程。
有人可以就如何改进此算法提出任何建议吗?
(注意我不是计算机科学家,所以我可能没有明显的改进.MMMM很感谢你的尝试!)
#include <iostream>
#include <armadillo>
using namespace std;
using namespace arma;
int main() {
mat A = {{1, 0.2, 0, 0.2, 0, 0, 0.2, 0, 0.2, 0},
{0, 1, 0.2, 0, 0.2, 0, 0, 0.2, 0 , 0},
{0, 0, 1, 0.2, 0, 0, 0.2, 0, 0, 0.2},
{0.2, 0, 0, 1, 0.2, 0, 0.2, 0.2, 0, 0.2},
{0, 0.2, 0, 0.2, 1, 0.2, 0, 0, 0, 0.2},
{0, 0, 0.2, 0, 0.2, 1, 0, 0.2, 0, 0},
{0.2, 0, 0, 0.2, 0.2, 0, 1, 0, 0, 0.2},
{0, 0.2, 0, 0.2, 0, 0, 0, 1, 0.2, 0},
{0, 0, 0.2, 0, 0.2, 0.2, 0, 0, 1, 0},
{0, 0, 0, 0.2, 0, 0.2, 0, 0, 0.2, 1}};
sp_mat Asp(A); // Interaction matrix in sparse representation
vec B = {1, 1, 0.1, 1, 0.1, 1, 1, 0.1, 1, 1};
double thresh = 0.2;
vec index(Asp.n_rows); // obj for storing locations of insignificant elements b
int count = 0;
for (int i=0; i<B.n_rows; i++) {
if (B(i) < thresh) {
index(count) = i;
count ++;
}
}
index.resize(count);
sp_mat tmp = Asp; // temp copy of interaction matrix
for (int i=0; i<index.n_rows; i++) {
// iterate through non-zero elements in col corresponding to each element of index
sp_mat::iterator bc = tmp.begin_col(index(i));
sp_mat::iterator ec = tmp.end_col(index(i));
// iterate through non-zero elements in row corresponding to each element of index
sp_mat::row_iterator br = tmp.begin_row(index(i));
sp_mat::row_iterator er = tmp.end_row(index(i));
// mat for storing locations of non-zero elements to be removed
mat loc(2, 2 * tmp.n_cols);
int count2 = 0;
for (auto j = bc; j != ec; j++) {
loc(0, count2) = j.row();
loc(1, count2) = j.col();
count2++;
}
for (auto j = br; j != er; j++) {
loc(0, count2) = j.row();
loc(1, count2) = j.col();
count2++;
}
loc.resize(2, count2);
for (int j = 0; j < loc.n_cols; j++) {
tmp(loc(0, j), loc(1, j)) = 0.0;
}
}
tmp.diag().ones();
cout << "Number of non-zero terms interaction matrix = " << Asp.n_nonzero << endl;
cout << "Number of non-zero terms reduced matrix = " << tmp.n_nonzero << endl;
}
输出:
Number of non-zero terms interaction matrix = 45
Number of non-zero terms reduced matrix = 24