matlab でゼロ行または列を削除するのは簡単ですが、現在の C コードでは、ソルバーをより高速にするためにすべてのゼロ行と列を削除する必要があるという問題に悩まされています。簡単な方法が見つかりませんでした。何か便利な方法で私を助けてくれませんか?
2 に答える
先頭と末尾の行と列のみを削除する場合
これらの操作をかなり効率的にする方法でマトリックスを実装できます。
あたかも 2D 配列 ( [][]
) であるかのように最大量のデータを保持するために大きなブロックを割り当て、
typedef struct {
size_t aJ; /* Allocated row length. Needed for computing positions */
size_t uI, uJ; /* Number of row/cols in use currently. For range checking */
size_t oI, oJ; /* Offset to the start of the first used row/col */
double *matrixA /* the storage */
} MatrixT;
初期化とクリーンアップのルーチンを作成する必要があります。古い c の専門家は、ここで配列のトリック (または気の利いた新しい可変長メンバー機能) を使用できることに気付くでしょう。
要素 (i,j) へのアクセスは次のようになります
double* element(MatrixT*this, size_t i, size_t j) {
double* base = this->matrixA + oI*aJ + oJ;
/* range checking if desired */
return (base + i*aJ + j);
}
これは、通常の 2D 配列から要素にアクセスする場合の約 2 倍の複雑さを持ち、1 行に簡略化できますが、わかりやすさが少し犠牲になります (ただし、コンパイラがそれを行う場合があります)。
行と列の削除には、適切な「使用値」と、前から取得している場合は適切な「オフセット」値の減少が含まれます。
構造はより複雑であり、単純な古い 2D 配列よりも多くの簿記が必要になるため、すべての操作を関数でラップする必要があります。
古い Fortran77 プログラマーは、これを「連続したサブ配列を関数に渡す」イディオムの再実装として認識する場合があり ます。
簡単な方法は、行ごとにトラバースしてから列ごとにトラバースし、ゼロをチェックし、真の場合はその行/列を最後の行/列に置き換え、最後の行/列を削除します(動的でm--またはn--の場合はfree())静的な場合)