我有这段代码,它在 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;
}
Run Code Online (Sandbox Code Playgroud)
其中 inputv 是 matA 的列的值。和 inputi 是这些值的索引。
我在 eigen 的文档中读到插入函数是最快的,当非零系数的数量约为 5000 时就可以了。但是当我有 25000 时,每列需要 5 秒!
我试过insrtback,但值是一样的?这个命令到底是做什么的?有什么方法可以改进这段代码吗?
曾经的优势(也许):每列中的值和索引按值从高到低排序......
小智 4
如果您的稀疏矩阵很大,则必须在填充之前为 matA 分配足够的空间。否则,会需要很长很长的时间来一遍又一遍地分配空间和复制数据。
您需要做的第一件事是了解矩阵的稀疏模式。我所说的稀疏模式是指每列的非零元素的数量(假设您的稀疏矩阵位于主列)。如果我们将这些值存储在 类型的变量 V 中VectorXi,调用matA.reserve(V)就是分配足够的内存空间。
按照上述过程,我可以使用普通笔记本电脑在 30 秒内填充 47236x677399 稀疏矩阵 (#non-zeros:49556258)。如果我不这样做的话,这将需要永远......