5

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 は、これらの値のインデックスです。

eigen のドキュメントで、挿入関数が最速であると読みました。ゼロ以外の係数の数が約 5000 の場合は問題ありません。しかし、25000 の場合、列ごとに 5 秒かかります。

insrtback を試しましたが、値は同じですか? このコマンドは正確に何をしますか? このコードを改善する方法はありますか?

かつての利点(おそらく):すべての列の値とインデックスは、最高から最低までの値でソートされます...

4

2 に答える 2

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

ここで重要な要素は、列ごとにゼロ以外の x 個のスペースを確保する 2 行目です。多くの場合、列または行ごとの非ゼロの数は事前に簡単に知ることができます。内部ベクトルごとに大きく異なる場合は、j 番目の内部ベクトルの予約サイズを返す operator[](int j) をベクトル オブジェクトに提供することで、各内部ベクトルの予約サイズを指定できます (たとえば、 VectorXi または std::vector 経由)。内部ベクトルごとの非ゼロの数の大まかな見積もりしか得られない場合は、逆ではなく過大評価することを強くお勧めします。この行が省略された場合、新しい要素の最初の挿入は、内部ベクトルごとに 2 つの要素のためのスペースを確保します。

4 行目は、列の主要なケースに対してソートされた挿入を実行します。速度のために、j 番目の列を埋めるとき、既存のゼロ以外の行インデックスは i より小さい必要があります。次に、この操作は簡単な O(1) 操作に要約されます。

行 5 は、残りの空きスペースを抑制し、行列を圧縮された列ストレージに変換します。

于 2015-04-30T12:08:15.973 に答える