SparseMat
有限要素法で使う疎行列用ライブラリです。 本ライブラリのstaticライブラリファイルは 「SparseMat.lib」 です。
EigenのEigen::SparseMatrixをベースとして作成されており、Eigenの疎行列ラッパーとして機能します。 double型、complex型の両方に対応し、疎行列の四則演算なども用意されています。 ソルバとしては、オリジナルの加速係数つきICCGソルバが用意されています。 その他、Eigenが用意しているICCGとBiCGstabのラッパも用意しています。
内部のintは、slv_intとして別の型として定義しています。
・using slv_int = int; (SparseMatTMPL.hppの冒頭)
基本はこのままでいいと思いますが、超大規模にしたい場合はunsingedやlong intに書き換えてください
SparseMatクラス
実数用の疎行列クラスです。 基本的には、まず初期化した後、add関数で行列要素を追加していきます。 追加が完了したら、fixメソッドで疎行列を確定させてください。 確定後にメソッドや四則演算が行えます。fix前に各種操作を行うとエラーになる恐れがあるので注意してください。 「SparseMat/SparseMat.hpp」をインクルードして使ってください。
* 基本操作
SparseMat();
コンストラクタ:疎行列を初期化します。インスタンスが作成されるだけで内部は何も初期化されません。 この状態でaddをしてもエラーになります。
SparseMat(slv_int x);
コンストラクタ:疎行列を初期化します。行数サイズをxで初期化します。 (内部でtempInitializeを呼び、初期化します)
SparseMat(const SparseMat& mat);
コンストラクタ:別の疎行列を代入して初期化します。本方法で初期化すると最初からfix状態になります。
bool isFixed()
呼び出し元インスタンスが確定済み(fixを呼び出した後か)かどうかを返します。
bool isEmpty() const
行列の中身が空かどうかを返します。
void tempInitialize()
疎行列の状況を初期化し、fixされていない状態にします。
void fix()
疎行列を確定させます。
void resetMat()
fix済みの疎行列の0にします。 (疎行列の位置はそのまま、値だけゼロにします)
void add(slv_int gyo, slv_int retu, double val)
疎行列の指定の位置に値を加えます。行の位置をgyoで、列の位置をretuで指定し、そこにValを加えます。 fix前の場合は任意の位置にaddできます。 fix後は、すでに値のある位置以外を指定するとエラーになります。
slv_int isInclude(slv_int gyo, slv_int target_r)const
疎行列のi行目に、target_r列があるかどうかを判定します。あったらそのindexを返します。
void getTargetRowVal(slv_int target, std::vector<slv_int>& row_pos, std::vector& row_val)const
指定した列の非ゼロの行位置と値をvector「row_val」にコピーします。
void getTargetColVal(slv_int target, std::vector<slv_int>& col_pos, std::vector& col_val)const
指定した行の非ゼロの列位置と値をvector「col_val」にコピーします。
void printMat(const std::string& str="Mat.csv")
疎行列の内容をstrで指定したファイルに書き出します。
void print()
疎行列をコンソールに表示します。
* オペレータ群
double* operator*(const double* vec) const;
dcomplex* operator*(const dcomplex* vec) const;
疎行列に列ベクトルvecを掛けて、結果ベクトルを返します。 列ベクトルはC++のデフォルトの配列で渡します。 (vecは実数、複素数どちらでも対応)
Eigen::VectorXd operator*(const Eigen::VectorXd& vec) const;
Eigen::VectorXcd operator*(const Eigen::VectorXcd& vec) const;
疎行列に列ベクトルvecを掛けて、結果ベクトルを返します。 列ベクトルはEigenのVectorで渡します。 (vecは実数、複素数どちらでも対応)
void operator*=(const double x)
自身の全要素にxを掛けます。
SparseMat operator*(const double x) const;
SparseMatC operator*(const dcomplex x) const;
自身の全要素にxを掛けた後の疎行列を返します。 (実数、複素数どちらでも対応)
SparseMat operator*(const SparseMat& mat) const;
SparseMatC operator*(const SparseMatC& mat) const;
自身と行列matの行列積を行い、結果の疎行列を返します。
SparseMat operator+(const SparseMat& mat) const;
SparseMatC operator+(const SparseMatC& mat) const;
自身と行列matを足し、結果の疎行列を返します。
* その他の行列オペレータ群
SparseMat trans() const
自身の転置行列を返します。
SparseMat makeSubMat(slv_int range1a, slv_int range1b, slv_int range2a, slv_int range2b)
範囲[r1a, r1b]×[r2a, r2b]の部分を抜き出して部分行列を作り、得られた部分行列を返します。
void MatDiv(SparseMat& matK11, SparseMat& matK12, slv_int rangeA, slv_int rangeB)
列rangeBを境に、行列を2つに分け、行rangeAより下は削除します。
SparseMat getMatLower() const;
下三角行列を作成して返します。
SparseMat getMatUpper() const
上三角行列を作成して返します。
SparseMat inv() const
逆行列(密アルゴリズム・大行列でやるとメモリが吹き飛ぶ!)
void round()
行列の要素を四捨五入して丸めます。
SparseMatCクラス
複素数用の疎行列クラスです。 基本的な操作は全て実数用のSparseMatと同じです。 「SparseMat/SparseMatC.hpp」をインクルードして使ってください。
SparseMatOperatorsクラス
複数の疎行列の操作を行うstaticなメソッドを管理するクラスです。 「SparseMat/SparseMatOperators.hpp」をインクルードして使ってください。
static SparseMat plusShift(const SparseMat& mat1, const SparseMat& mat2, const double a1, const double a2, const slv_int pos1, const slv_int pos2)
static SparseMatC plusShift(const SparseMatC& mat1, const SparseMatC& mat2, const double a1, const double a2, const slv_int pos1, const slv_int pos2)
(a1mat1 + a2mat2)を計算して、結果の疎行列を返します。 mat2に足す位置をpos1,pos2でずらすことが可能です。
static double* dotVecMat2(const SparseMat& mat1, const SparseMat& mat2, const double* vec1);
static dcomplex* dotVecMat2(const SparseMat& mat1, const SparseMatC& mat2, const double* vec1);
static dcomplex* dotVecMat2(const SparseMatC& mat1, const SparseMat& mat2, const double* vec1);
static dcomplex* dotVecMat2(const SparseMatC& mat1, const SparseMatC& mat2, const double* vec1);
static dcomplex* dotVecMat2(const SparseMat& mat1, const SparseMat& mat2, const dcomplex* vec1);
static dcomplex* dotVecMat2(const SparseMat& mat1, const SparseMatC& mat2, const dcomplex* vec1);
static dcomplex* dotVecMat2(const SparseMatC& mat1, const SparseMat& mat2, const dcomplex* vec1);
static dcomplex* dotVecMat2(const SparseMatC& mat1, const SparseMatC& mat2, const dcomplex* vec1);
(mat1 + mat2)*vecBを計算し、得られたベクトルを返します。
static SparseMat dotMats(const SparseMat& matA, const SparseMat& matB, const SparseMat& matC);
static SparseMatC dotMats(const SparseMat& matA, const SparseMat& matB, const SparseMatC& matC);
static SparseMatC dotMats(const SparseMat& matA, const SparseMatC& matB, const SparseMatC& matC);
static SparseMatC dotMats(const SparseMatC& matA, const SparseMatC& matB, const SparseMatC& matC);
疎行列AとBとCをかけて結果を返します。
static void plusFix(SparseMat& matAB, const SparseMat& matA, const SparseMat& matB, double a1=1.0, double a2=1.0, slv_int pos1=0, slv_int pos2=0);
static void plusFix(SparseMatC& matAB, const SparseMat& matA, const SparseMatC& matB, double a1=1.0, double a2=1.0, slv_int pos1=0, slv_int pos2=0);
static void plusFix(SparseMatC& matAB, const SparseMatC& matA, const SparseMatC& matB, double a1=1.0, double a2=1.0, slv_int pos1=0, slv_int pos2=0);
fix済みの行列matABCに、(a1matA+a2matB)の結果を代入します。 matBの開始位置はposだけずらすことが可能です。
static void plusFix(SparseMat& matABC, const SparseMat& matA, const SparseMat& matB, const SparseMat& matC, double a1=1.0, double a2=1.0, double a3=1.0);
static void plusFix(SparseMatC& matABC, const SparseMatC& matA, const SparseMatC& matB, const SparseMatC& matC, double a1=1.0, double a2=1.0, double a3=1.0);
fix済みの行列matABCに、(a1A+a2B+a3*C)の結果を代入します。
static void dotFix(SparseMat& matAB, const SparseMat& matA, const SparseMat& matB);
static void dotFix(SparseMatC& matAB, const SparseMat& matA, const SparseMatC& matB);
static void dotFix(SparseMatC& matAB, const SparseMatC& matA, const SparseMatC& matB);
fix済みの行列matABCに、AとBの行列積の結果を代入します。
static void dotFix(SparseMat& matAB, const SparseMat& matA, const SparseMat& matB, const SparseMat& matC);
static void dotFix(SparseMatC& matAB, const SparseMat& matA, const SparseMat& matB, const SparseMatC& matC);
static void dotFix(SparseMatC& matAB, const SparseMat& matA, const SparseMatC& matB, const SparseMatC& matC);
static void dotFix(SparseMatC& matAB, const SparseMatC& matA, const SparseMatC& matB, const SparseMatC& matC);
fix済みの行列matABCに、AとBとCの行列積の結果を代入します。
MatSolversクラス
疎行列用のソルバを提供するクラスです。全てstaticメソッドです。 「SparseMat/MatSolvers.hpp」をインクルードして使ってください。
static SparseMat plusShift(const SparseMat& mat1, const SparseMat& mat2, const double a1, const double a2, const slv_int pos1, const slv_int pos2)
static SparseMatC plusShift(const SparseMatC& mat1, const SparseMatC& mat2, const double a1, const double a2, const slv_int pos1, const slv_int pos2)
(a1mat1 + a2mat2)を計算して、結果の疎行列を返します。 mat2に足す位置をpos1,pos2でずらすことが可能です。
static bool solveICCG(const slv_int size0, const double conv_cri, const int max_ite, const double accera, const SparseMat& matA, const double *vecB, double *results, bool init=false)
static bool solveICCG(const slv_int size0, const double conv_cri, const int max_ite, const double accera, const double normB, const SparseMat& matA, const double *vecB, double *results, bool init=false)
static bool solveICCG(const slv_int size0, const double conv_cri, const int max_ite, const double accera, const SparseMat& matA, const Eigen::VectorXd& vecB, double *results, bool init=false)
自作のICCG法です。右辺をC++配列、Eigen::VectorXdで与えるかで2パターンあります。 また、引く数normBは、右辺bのノルムを事前に与えるか、内部で計算するかです。 (normBは、収束判定で使います。"r/normB < conv_cri"となると収束とします。)
size0:行列の行数です。 conv_cri:収束判定値です。10^-6など。 max_ite:最大反復数です。 accera:加速係数です。 matA:Ax=bのAです。対称行列としてください。 vecB:Ax=bのbです。size0のベクトルです。 results:解ベクトルです(Ax=bのx)。メモリは事前にsize0だけ確保しておいてください。 init:解ベクトルxをこの処理の前にゼロ初期化するかです。過去の値がxに入っていて流用したい場合はfalseにしてください。それ以外はtrueにすれば内部でゼロ初期化してから始めます。
static bool solveICCG(slv_int size0, const double conv_cri, const int max_ite, const double accera, const SparseMatC& matA, const dcomplex *vecB, dcomplex *results, bool init=false);
static bool solveICCG(slv_int size0, const double conv_cri, const int max_ite, const double accera, const double normB, const SparseMatC& matA, const dcomplex *vecB, dcomplex *results, bool init=false);
static bool solveICCG(slv_int size0, const double conv_cri, const int max_ite, const double accera, const SparseMatC& matA, const Eigen::VectorXcd& vecB, dcomplex *results, bool init=false);
上記ICCG法の複素数版です。使い方は同じです。 ただしmatAは対称行列にのみ対応しています(エルミートなどは未対応)
static bool solveEigenICCG(const slv_int size0, const double conv_cri, const int max_ite, const SparseMat& matA, const Eigen::VectorXd& vecB, Eigen::VectorXd& results, bool init=false);
static bool solveEigenICCG(const slv_int size0, const double conv_cri, const int max_ite, const SparseMat& matA, const double* vecB, double* results, bool init=true);
static bool solveEigenBiCGstab(const slv_int size0, const double conv_cri, const int max_ite, const SparseMat& matA, const Eigen::VectorXd& vecB, Eigen::VectorXd& results, bool init=false);
static bool solveEigenBiCGstab(const slv_int size0, const double conv_cri, const int max_ite, const SparseMat& matA, const double* vecB, double* results, bool init=true);
static bool solveEigenICCG(const slv_int size0, const double conv_cri, const int max_ite, const SparseMatC& matA, const Eigen::VectorXcd& vecB, Eigen::VectorXcd& results, bool init=false);
static bool solveEigenICCG(const slv_int size0, const double conv_cri, const int max_ite, const SparseMatC& matA, const dcomplex* vecB, dcomplex* results, bool init=true);
static bool solveEigenBiCGstab(const slv_int size0, const double conv_cri, const int max_ite, const SparseMatC& matA, const Eigen::VectorXcd& vecB, Eigen::VectorXcd& results, bool init=false);
static bool solveEigenBiCGstab(const slv_int size0, const double conv_cri, const int max_ite, const SparseMatC& matA, const dcomplex* vecB, dcomplex* results, bool init=false);
Eigenに付属している疎行列ソルバのラッパーです。 使い方は上記ICCG法の引数と同じです。