- 前の記事の疎行列用クラスのラッパークラス(spinxform)のヘッダー定義と関数コードを眺めて、疎行列クラスがどのようになっているかを見てみる
- 疎行列クラスの基本
- nxm行列の要素を全部並べると大きすぎる。疎であることを利用して、「番地」と「値」の組だけにしたい
- 「番地」は整数ペア
- 「値」は複素数を取らせることにすると実数ペア
- これをc++、STLらしくイテレータを使って実装している
- ヘッダー定義を見よう
- その中でstd::pair, std::mapを使っているところを抜粋する
- 行列の(列、行)整数ペアをEntryIndexとし
- 行列のセルの複素数値をdoubleのペアとしてEntryValueとしている
- その上で、(行、列) -> (double,double)というmapを作りEntryMapとしている
- このままだとイテレータが使えないので、EntryMpaをイテレーションできるようにiterator, const_iteratorの2つを作っている。片方は変更可能に、もう片方は固定
- その2つのイテレータが使えるように、先頭と終端とが取れるように関数も定義してある
typedef std::pair<int,int> EntryIndex;
typedef std::pair<double,double> EntryValue;
typedef std::map<EntryIndex,EntryValue> EntryMap;
typedef EntryMap::iterator iterator;
typedef EntryMap::const_iterator const_iterator;
iterator begin( void );
const_iterator begin( void ) const;
iterator end( void );
const_iterator end( void ) const;
-
- その実用を、疎行列の転置処理関数で見てみる
- 転置後には、転置前と同じ数の番地ペアが必要なので、それ用にEntryMap transposedを作り、そこの番地(整数ペア)と値(実数ペア)を納めていく
- 転置前の疎行列のすべての要素をイテレーションするためにconst_iteratorを使っている
- dataは、Sparseクラスに持たせているcholmod_sparseクラスなので、その番地の始点・終点取り出しをしていることもわかる
- std::mapの要素取り出しは <,>と二重入れ子になっているので、first.firtsと言えば、最初のintが、first.secondと言えば二番目のintが、secondと言えば、というペアが取り出される
- 転置処理なので、int,intの前後をひっくり返して登録している
void Sparse :: transpose( void )
{
EntryMap transposed;
for( const_iterator e = data.begin(); e != data.end(); e++ )
{
int i = e->first.first;
int j = e->first.second;
transposed[ EntryIndex( j, i ) ] = e->second;
}
data = transposed;
swap( m, n );
}
#include <cholmod.h>
#include <map>
class Sparse
{
public:
Sparse( Common& common, int m = 0, int n = 0, int xtype = CHOLMOD_REAL );
~Sparse( void );
void resize( int m, int n );
cholmod_sparse* operator*( void );
int size( int dim ) const;
int length( void ) const;
void zero( double rVal = 0., double iVal = 0. );
void transpose( void );
void horzcat( const Sparse& A, const Sparse& B );
void vertcat( const Sparse& A, const Sparse& B );
double& operator()( int row, int col );
double operator()( int row, int col ) const;
double& r( int row, int col );
double r( int row, int col ) const;
double& i( int row, int col );
double i( int row, int col ) const;
typedef std::pair<int,int> EntryIndex;
typedef std::pair<double,double> EntryValue;
typedef std::map<EntryIndex,EntryValue> EntryMap;
typedef EntryMap::iterator iterator;
typedef EntryMap::const_iterator const_iterator;
iterator begin( void );
const_iterator begin( void ) const;
iterator end( void );
const_iterator end( void ) const;
protected:
Common& common;
int m, n;
int xtype, stype;
cholmod_sparse* A;
EntryMap data;
double& retrieveEntry( int row, int col, int c );
double retrieveEntry( int row, int col, int c ) const;
};