1

私は数学の学生であり、C++ はまったく初めてで、学習を支援するために行列クラスを作成したいと考えています (ライブラリ クラスは使用したくありません)。私は何かをすることを考えていました

int iRows = 5;
int iColumns = 6;
double** pMatrix = new double*[iRows];
for (int i = 0; i < iRows; ++i) {
    pMatrix[i] = new double[iColumns];
}

(これが正しい構文かどうかはわかりません-試す前にここでアドバイスを得たいと思いました)しかし、ここStackoverflowで、shared_ptrのようではないポインターを使用することはお勧めできません。vector<vector<double>>メモリーの削除を気にせずに使えるようにした方がいいですか?長さは push_back で変更でき、マトリックスのサイズを固定したいので、ベクトルは良い選択ではないのではないかと心配しています。使えない

double dMatrix[iRows][iColumns];

次元が一定ではないからです。私が使用するのに最適な選択は何ですか?

4

3 に答える 3

5

おそらく

std::vector<double> matrix(rows * columns); // ditch the prefixes
// indexing: matrix[row * columns + column];

とにかく、各行には同じ数の列があります。

于 2012-08-13T18:00:49.323 に答える
2

私は最初に自問します:あなたは何を達成しようとしていますか?学習演習として何かを作成したいですか、それとも適切なマトリックス実装が必要ですか?

これを学習演習として実行したい場合は、MxN 要素を内部で使用する double の 1d ベクトルのみを使用することをお勧めします。これを内部に保存するが、呼び出し元から実装を隠すクラスを作成します。呼び出し元は、それがどのように保存されているかを知ったり気にしたりしてはなりません。インターフェイスの一部として、通常は演算子 (m,n) を介してアクセスする必要があります。

double& MyMatrix::operator()(int m, int n) {
  return m_Array[m*numColumns + n];
} 

足し算や掛け算など、もっと面白いことをしようとするとすぐに、算術演算子をオーバーロードする必要があることに気付くでしょう。,だけでなくoperator+operator-演算子 *、/、*=、+=、-= /=、++、-- も使用できます。乗算を実装すると、多くの冗長なコピーを作成しているため、実装が遅すぎて役に立たないことがあります。YMMV

したがって、高速な行列ライブラリが必要な場合は、Boost のBasic Linear Algebra ライブラリなど、内部で BLAS を使用するライブラリが必要になります。

おそらく、最初に自分で試してみて、良いデザインを得る際の問題点を理解してから、ブーストを調べてください。それを研究することで多くのことを学ぶことができます.

于 2012-08-13T18:21:27.443 に答える
1

いいえ、絶対に違います。ない

vector<vector<double>> matrix;

または

double** matrix;

マトリックス クラスに適したレイアウトです。あなたのクラスはプログラミングに慣れるためにはうまくいくかもしれませんが、そのような行列クラスのパフォーマンスは劣ります。問題は、データの局所性が失われることです。コードを検討してください

for (int i = 0; i < iRows; ++i) {
    pMatrix[i] = new double[iColumns];
}

行列とベクトルの乗算を効率的に行うには、できるだけ多くの行列値をキャッシュに保持する必要があります。そうしないと、メモリ転送に時間がかかりすぎます。行ごとに 1 つのメモリ ブロックを取得しているため、これらのデータ ジャンクがメモリ内で近接していることを保証するものは何もありません。単純な行列とベクトルの乗算の場合、これはそれほど悪くないかもしれません。なぜなら、行要素は引き続き連続して格納され、ある行から次の行への「ジャンプのみ」がキャッシュ ミスにつながるからです。

ただし、列に沿った値がメモリ内のどこにでも格納される可能性があり、キャッシュのプリフェッチに使用できる要素間のストライドを決定する合理的な方法がないため、転置行列の操作は実際には問題です。

したがって、他の著者が示唆しているように、行列には​​ 1 つの大きなメモリ ブロックを使用してください。これにはあなたの側でもう少し努力が必要ですが、あなたのマトリックスクラスのユーザーには報われます。

于 2012-08-17T17:18:28.950 に答える