我有这个代码在for循环中调用java中的c ++方法:
JNIEXPORT void JNICALL Java_com_jp_algi_CoreC_MMload(JNIEnv *env3, jobject clazz3, jdoubleArray inputv, jintArray inputi, jint poc, jint pozic)
{
jdouble* fltv2 ;
jint* fltind2;
jsize sizedat = env3->GetArrayLength(inputi);
fltv2 = new jdouble[sizedat];
fltind2 = new jint[sizedat];
jint i;
jint jm;
env3->GetIntArrayRegion(inputi,0,sizedat,fltind2);
env3->GetDoubleArrayRegion(inputv,0,sizedat,fltv2);
// default is column major
matA.reserve(VectorXi::Constant(1,sizedat));
for ( jm = 0; jm < sizedat; jm++) {
//matA.insert(fltind2[jm],pozic) = fltv2[jm]; // alternative: mat.coeffRef(i,j) += v_ij;
matA.insert(fltind2[jm],pozic)= fltv2[jm];
//matA.insertBack(fltind2[jm],pozic)= fltv2[jm];
//matA.ins
//matA.insertBackUncompressed();
//matA.coeffRef(fltind2[jm],pozic) += fltv2[jm];
// optional
}
matA.makeCompressed();
//k++; //blbe zayklenji!!!
env3->SetIntArrayRegion(inputi,0,sizedat,fltind2);
env3->SetDoubleArrayRegion(inputv,0,sizedat,fltv2);
delete[] fltv2;
delete[] fltind2;
}
其中inputv是matA列的值。和inputi是这些值的索引。
我在docs中读到了特征,插入函数是最快的,当非零系数的数量大约是5000时就可以了。但是当我有25000时,每列需要5秒!
我试过后退,但值是一样的吗?这个命令到底是做什么的?有没有办法改进这段代码?
一旦有利(也许):每列中的值和索引按从最高到最低的值排序......
答案 0 :(得分:3)
如果稀疏矩阵很大,则必须在填充之前为matA分配足够的空间。否则,需要很长时间才能一次又一次地分配空间和复制数据。
您需要做的第一件事是了解矩阵的稀疏模式。稀疏模式的意思是每列的非零元素的数量(假设您的稀疏矩阵在列专业中)。如果我们将这些值存储在类型VectorXi
的变量V中,则调用matA.reserve(V)
将分配足够的内存空间。
按照上述步骤,我可以使用普通笔记本电脑在30秒内填充47236x677399稀疏矩阵(#non-zeros:49556258)。如果我不这样做,那就需要永远......
答案 1 :(得分:2)
Eigen Sparse Matrix Tutorial的重点:
1: SparseMatrix<double> mat(rows,cols); // default is column major
2: mat.reserve(VectorXi::Constant(cols,x));
3: for each i,j such that v_ij != 0
4: mat.insert(i,j) = v_ij; // alternative: mat.coeffRef(i,j) += v_ij;
5: mat.makeCompressed(); // optional
这里的关键因素是第2行,我们为每列保留x非零的空间。在许多情况下,可以容易地预先知道每列或每行的非零数。如果每个内部向量的变化很大,那么可以通过提供一个带有operator [](int j)的向量对象来为每个内向量指定一个保留大小,返回第j个内向量的保留大小(例如,通过VectorXi或std :: vector)。如果只能粗略估计每个内向量的非零数,则强烈建议高估它而不是相反。如果省略此行,则第一次插入新元素将为每个内部向量保留2个元素的空间。
第4行对Column major case执行排序插入。对于速度,当填充第j列时,现有的非零应该具有小于i的行索引。然后,这个操作归结为平凡的O(1)操作。
第5行抑制剩余的空白空间并将矩阵转换为压缩列存储。