事項
対称行列を連続して格納する行列クラスがあります。これらの行列は (対角線でのミラーリングに関して) 軸対称であるという優れた特性を持っているため、ストレージを最適化して上三角行列または下三角行列にすることができます。
次のスキームは、上三角行列として格納された 6x6 対称行列の格納スキームを示しています。
r\c 0 1 2 3 4 5 -------------------------------------- 0 | 0 | 1 | 2 | 3 | 4 | 5 | -------------------------------------- 1 | | | 6 | 7 | 8 | 9 | 10 | -------------------------------------- 2 | | | | | 11 | 12 | 13 | 14 | -------------------------------------- 3 | | | | | | | 15 | 16 | 17 | -------------------------------------- 4 | | | | | | | | | 18 | 19 | -------------------------------------- 5 | | | | | | | | | | | 20 | --------------------------------------
次に、その行列の行と列の反復子を設計したいと思います。実際の行と列を反復するのではなく、実質的に完全な対称行列の行と列を反復します。
例:
for (the_iterator i=matrix.row(2).begin(); i!=matrix.row(2).end(); ++i)
{
cout << *i << " ";
}
これにより、要素の内容が出力されます
2 7 11 12 13 14
(上記のように、行列が 6x6 三角行列の場合)。
幸いなことに、対称行列の場合、行のシーケンスは列のシーケンスとi
同じであるi
ため、必要なイテレータ タイプは 1 つだけです。
行列クラスは、行と列のインデックスに従って要素にアクセスするメソッドを提供します
reference operator() (size_type const r, size_type const c) { /*...*/ }
イテレータの設計方法について 2 つのアイデアが浮かびました。数学をある点から別の点に切り替える。
1. 行列参照によるイテレータの簡単な進め方
一方では、マトリックスへの参照、目的の行/列の番号、およびこの行/列の現在の要素を格納できます。
matrix_type & m;
size_type fixed;
size_type free;
これにより、operator()
逆参照のためのマトリックス クラスの使用と、簡単なイテレータの進行が可能になります。
class the_iterator
// ...
{
// ...
reference operator* () const _NOEXCEPT
{
return *m(fixed, free);
}
// ...
this_type & operator++ (void) _NOEXCEPT
{ // increment then return
++free;
return *this;
}
// ...
};
これには明らかな欠点が 1 つあります。 を呼び出すたびにoperator()
、行インデックスと列インデックスを使用して計算される基になるメモリ内の連続したインデックスが必要です。
2. 要素へのポインタによる簡単な逆参照
一方で、p
イテレーターの進行を制御するためのポインター (matrix value_type 要素ポインター) といくつかの制御値を持つことも可能です。垂直部分 (2 -> 7 -> 11; 上記の例を参照) では、ポインターを 5+4 進める必要があり、水平部分 (11 -> 12 -> 13 -> 14) では、ポインターをpointer
1 ずつ変更する必要があります。 +1+1。これは自明ではありませんが、それほど難しくもなく、反復なしで代数的に解くことができます。
*p
逆参照/要素アクセスは、使用できるようになったため、どの計算にも関連付けられなくなりました。これが私が現在行っている方法です。
質問:
「計算作業」はどこで行う必要があり、どちらに進みますか (そしてその理由)?
私はどちらかを持つことができます
- シンプルで高速な反復子の進行ですが、要素へのアクセスが必要です。
- 高度化が要求されますが、要素へのアクセスはシンプルかつ高速です。
イテレータは (ループ内で) サイクルごとに 1 回だけ進む可能性が高いため、私は 2 番目の傾向がありますが、複数回逆参照される可能性があります。