このプロジェクトはシンプルな実装かつ軽量な行列操作を可能とするライブラリの開発を目的としています。
Note
コンパイラはMSVC2022 Cpp14 or 17とします。
開発に協力してくださる方は以下の方法でお願いします。
- リポジトリをフォークします。
- 新しいブランチを作成します (
git checkout -b feature/userName
). - 変更をコミットします (
git commit -m 'comment'
). - ブランチにプッシュします (
git push origin feature/userName
). - プルリクエストを作成します。
template
を用いてint
やdouble
型の行列を生成します。
template<typename Type>
class Matrix{
// member
}
Matrix<int> mint;
Matrix<double> mdouble;
- データの格納
データは
std::vector<std::vector<Type>>
で格納し処理します。 将来的にCUDA
などGPU上での処理を行わせる予定ですので一次元配列へ展開するメソッドを定義します。 - 型エイリアス
std::vector<std::vector<Type>>
は実装する際に少し長いため以下のコードにより型エイリアスRowType
,RowInitType
,MatrixType
,MatrixInitType
を定義します。 またクラス外部でも使用できるようpublic
にしておきます。
template<typename Type>
class matrix{
public:
template<typename rowType > using RowType = std::vector<rowType>;
template<typename rowInitType> using RowInitType = std::initializer_list<rowInitType>;
template<typename matrixType = Type> using MatrixType = std::vector <RowType<matrixType>>;
template<typename matrixType = Type> using MatrixInitType = std::initializer_list<RowInitType<matrixType>>;
}
このプロジェクトのライブラリは保守性向上のため定義ファイル
と実装ファイル
に分ける事とします。
- 定義ファイル
- クラスの宣言
- 関数のプロトタイプ宣言
- マクロの定義など
- 実装ファイル
- 関数の実装
- メンバ関数の実装
インクルードガードの命名はMATRIXCPP_ファイル名_拡張子
とします。
// test.hppの場合
#ifndef MATRIXCPP_TEST_HPP
#define MATRIXCPP_TEST_HPP
// proc...
#endif
.h
は定義ファイル、.hpp
は実装ファイルを意味します。
- matrix matrix.h matrixCalc.hppなどすべてのファイルをインクルードします。
- matrix.h matrixクラスの定義,メンバ関数のプロトタイプ宣言などメンバの定義を行います。
- matrixCtor.hpp コンストラクタを定義します。
- matrixCalc.hpp 加算,減算,アダマール積など計算を行います。
- matrixOp.hpp 演算子関数の実装を行います。
- matrixDec.hpp LU分解など行列分解を行います。逆行列も含む。
- matrixUtils.hpp 行入れ替えなど行列の操作を行います。
matrix ---- matrix.h
|-- matrixCtor.hpp
|-- matrixCalc.hpp
|-- matrixOp.hpp
|-- matrixDec.hpp
|__ matrixUtils.hpp
- メンバ名は
camelCase
で記述します。 - クラス名は
PascalCase
で記述します。 - プライベートメンバ
プライベートメンバ名(
camelCase
)の後に_
をつけます。 - プロトタイプ宣言
返り値型 メンバ名(引数型1,引数型2,...);
template<typename Type, typename DcmpType = double> // Type:演算時に使用する型、DcmpType:分解時に保持する行列の型
class Matrix{
private:
// プライベートメンバ
// 変数メンバ
Type testValuePrivate_ = 0; // コメント
// 函数メンバ(プロトタイプ宣言)
Type testFuncPrivate_(const Matrix&,const Matrix&); // コメント
public:
// パブリックメンバ
// 変数メンバ
Type testValuePublic = 0; // コメント
// 函数メンバ(プロトタイプ宣言)
Type testFuncPublic(const Matrix&,const Matrix&); // コメント
}
// コメント
template<typename Type>
Type Matrix<Type>::testFuncPrivate_(const Matrix& a,const Matrix& b){
return Type();
}
// コメント
template<typename Type>
Type Matrix<Type>::testFuncPublic(const Matrix& a,const Matrix& b){
return Type();
}
-
Matrix() = default;
デフォルトコンストラクタ -
Matrix(const MatrixInitType<>&);
初期化用のパラメータ付きコンストラクタusing Type = int; Matrix<Type> mat = { {1,2,3}, {4,5,6}, {7,8,9} };
-
Matrix(const MatrixType<>&);
コピーコンストラクタ -
Matrix(const std::pair<size_t, size_t>&);
サイズ指定のパラメータ付きコンストラクタusing Type = int; Matrix<int> mat({2,3}); // {rowCount,colCount}
-
Matrix(const Matrix<Type, DcmpType>&);
コピーコンストラクタ -
Matrix(Matrix<Type>&&) noexcept;
ムーブコンストラクタ
-
Matrix<Type>& operator=(const MatrixInitType<Type>&);
代入演算子 -
Matrix<Type>& operator=(const Matrix<Type>&);
代入演算子 -
Matrix<Type>& operator<<(const MatrixInitType<Type>&);
ストリーム挿入演算子 -
Matrix<Type>& operator<<(const Matrix<Type>&);
ストリーム挿入演算子 -
Matrix<Type>& operator=(Matrix<Type>&&);
ムーブ代入演算子 -
Matrix<Type>& operator<<(Matrix<Type>&&);
ムーブストリーム挿入演算子 -
RowType<Type>& operator[](const size_t&);
行アクセスusing Type = int; Matrix<Type> mat = {{1,2,3},{4,5,6},{7,8,9}}; std::cout << mat[1] << std::endl;
Matrix<Type>& operator+=(const Matrix<Type>&);
加算using Type = int; Matrix<Type> mat1 = {{1,2,3},{4,5,6},{7,8,9}}; Matrix<Type> mat2 = {{9,8,7},{6,5,4},{3,2,1}}; mat1 += mat2; // mat1 = {{10,10,10},{10,10,10},{10,10,10}}
Matrix<Type>& operator-=(const Matrix<Type>&);
減算using Type = int; Matrix<Type> mat1 = {{1,2,3},{4,5,6},{7,8,9}}; Matrix<Type> mat2 = {{9,8,7},{6,5,4},{3,2,1}}; mat1 -= mat2; // mat1 = {{-8,-6,-4},{-2,0,2},{4,6,8}}
Matrix<Type>& operator*=(const Matrix<Type>&);
乗算using Type = int; Matrix<Type> mat1 = {{1,2,3},{4,5,6},{7,8,9}}; Matrix<Type> mat2 = {{9,8,7},{6,5,4},{3,2,1}}; mat1 *= mat2; // mat1 = {{30,24,18},{84,69,54},{138,114,90}}
Matrix<Type>& operator^=(const Matrix<Type>&);
アダマール積using Type = int; Matrix<Type> mat1 = {{1,2,3},{4,5,6},{7,8,9}}; Matrix<Type> mat2 = {{9,8,7},{6,5,4},{3,2,1}}; mat1 ^= mat2; // mat1 = {{9,16,21},{24,25,24},{21,16,9}}
Matrix<Type>& operator/=(const Matrix<Type>&);
アダマール除算using Type = int; Matrix<Type> mat1 = {{1,2,3},{4,5,6},{7,8,9}}; Matrix<Type> mat2 = {{9,8,7},{6,5,4},{3,2,1}}; mat1 /= mat2; // mat1 = {{0.111111,0.25,0.428571},{0.666667,1.0,1.5},{2.33333,4.0,9.0}}
Matrix<Type>& operator*=(const Type&);
スカラ乗算using Type = int; Matrix<Type> mat = {{1,2,3},{4,5,6},{7,8,9}}; mat *= 2; // mat = {{2,4,6},{8,10,12},{14,16,18}}
-
Matrix<Type> operator+(const Matrix<Type>&);
加算 -
Matrix<Type> operator-(const Matrix<Type>&);
減算 -
Matrix<Type> operator*(const Matrix<Type>&);
乗算 -
Matrix<Type> operator^(const Matrix<Type>&);
アダマール積 -
Matrix<Type> operator/(const Matrix<Type>&);
アダマール除算 -
Matrix<Type> operator*(const Type&);
スカラ乗算 -
template<typename Type_>
explicit operator Matrix<Type_>();
型変換
Matrix<Type>& add(const Matrix<Type>&);
加算
Matrix<Type>& sub(const Matrix<Type>&);
減算
Matrix<Type>& mul(const Matrix<Type>&);
乗算
Matrix<Type>& scalarMul(const Type&);
スカラ乗算
Matrix<Type>& hadamardMul(const Matrix<Type>&);
アダマール積
Matrix<Type>& hadamardDiv(const Matrix<Type>&);
アダマール除算
template<typename calcType>
Matrix<Type>& scalarCalc(const Matrix<Type>&);
スカラ計算
std::vector<Matrix<DcmpType>> luDec(DcmpType epsilon = 1e-9);
LU分解
-
Matrix<DcmpType> inverse(DcmpType epsilon = 1e-9);
逆行列 -
DcmpType det(DcmpType epsilon = 1e-9);
行列式
Matrix<Type> transpose();
転置
-
Matrix<Type>& swapRow(const size_t&, const size_t&);
行の入れ替え -
Matrix<Type>& swapCol(const size_t&, const size_t&);
列の入れ替え -
Matrix<Type>& resize(const size_t&, const size_t&);
サイズ変更 -
const size_t rows() const;
行数の取得 -
const size_t cols() const;
列数の取得 -
std::vector<std::reference_wrapper<Type>> rowRef(const size_t&);
行参照 -
std::vector<std::reference_wrapper<Type>> colRef(const size_t&);
列参照 -
Matrix<Type>& forEach(std::function<Type()>);
各要素への操作 -
Matrix<Type>& forEach(std::function<Type(size_t, size_t, Type&)>);
各要素への操作(行、列、そのポイントの値) -
template<typename Type_ = Type>
static Matrix<Type_> identity(const size_t&);
単位行列生成
-
template<typename CharT, typename Traits, typename MatrixType = double>
std::basic_ostream<CharT, Traits>& operator <<(std::basic_ostream<CharT, Traits>&, Matrix<MatrixType>);
行列の出力オーバーロード -
template<typename CharT, typename Traits, typename MatrixType = double>
std::basic_ostream<CharT, Traits>& operator <<(std::basic_ostream<CharT, Traits>&, std::vector<std::vector<MatrixType>>);
2次元ベクトルの出力オーバーロード
Note
他の分解法は追加予定QR分解
,コレスキー分解
,固有値分解
,SVD分解
,ジョルダン標準形