🦄

[C#]行列計算のクラスライブラリMatrixSharpを作成しました。

2023/01/15に公開

はじめに

これまで行列積の計算速度を向上するために、いくつかの手法を試してみました。
学んできたことを昇華するにはアウトプットすることが大事なので、クラスライブラリを作成してGitHubに上げました。

https://github.com/Tremendous1192/MatrixSharp

Nugetにも登録しました

この記事では、私が作成したライブラリを紹介します。

クラス構造

2次元配列double[,]を行列Matrixに、1次元配列double[]を列ベクトルColumnVectorや行ベクトルRowVectorに変換して使用できるパッケージです。
列ベクトルと行ベクトルとを明示的に分けている理由は、手計算に近い感覚で使用するためです。

バージョン管理

ver 0.0.10

Modified the connection between public multiply method and internal function.

変更履歴

ver 0.0.9

Modified the algorithm to solve homogeneous equation.

Don't worry any user does NOT need to modify your code.

ver 0.0.8

Modify README

ver 0.0.7

Append internal function of faster matrix subtract.
If your matrix element number (row x column) is multiples of 2, 3, or 4, 5, your calculation will be faster than usual.

ver 0.0.6

Modify Clone Method of Matrix and Vector classes.

ver.0.0.5

Append internal function faster matrix addition. If your matrix element number (row x column) is multiples of 2, 3, or 4, 5, you are able to calculate matrix addition quickly.

ver.0.0.4 2023年1月21日

NugetのReadMeが文字化けしてしまったので、英語に直しました。
文字化け対策がまとまった後に、日本語も書きたいと思います。

ver.0.0.3 2023年1月21日

配列を返すToArrayメソッドを追加しました。
入出力の基本的な機能が揃いました。

ver.0.0.2 2023年1月15日

①ファイル名の変更(Userには影響なし)
②一部のコンストラクタのアクセス修飾子をinternalに変更
③線形回帰の予測メソッドの追加

ver.0.0.1 2023年1月12日

初版を発行しました。

クラス設計の概要

行列やベクトルの計算を行う基本クラスと、線形回帰などの応用クラスの2分類で設計しました。
管理が大変なので、今のところ名前空間はTremendous1192.SelfEmployed.MatrixSharpだけにしています。

基本クラス(Basic)

行列やベクトルのクラスと、いくつかのinterfaceを基本クラスとしました。

名前空間 クラス名 説明
Tremendous1192.SelfEmployed.MatrixSharp Matrix 行列計算のクラス
ColumnVector 列ベクトルのクラス
RowVector 行ベクトルのクラス
Vector (アクセス修飾子internal)行ベクトルと列ベクトルの内部関数
IRandomNumber 乱数を生成するinterface
IKernel カーネル法のカーネルを計算するinteface
IGraphLaplacian グラフラプラシアンを計算するinterface

応用クラス(Applied)

応用クラスは、線形回帰などの応用数学を行うクラスで構成されています。

名前空間 クラス名 説明
Tremendous1192.SelfEmployed.MatrixSharp DesignMatrix 計画行列
GaussianProcessRegression ガウス過程回帰
LinearRegression 線形回帰
LogisticRegression ロジスティック回帰
Preprocessing 前処理
PrincipalComponentAnalysis 主成分分析
SpectralClustering スペクトルクラスタリング
KMeansClustering k-平均法

基本クラス(Basic)の説明

Matrix

行列のクラスです。できるだけ数学の手計算に寄せてみました。

コンストラクタ

2次元配列を行列に変換します。

2次元配列を引数とするコンストラクタ
public Matrix(in double[,] array)

また、行数、列数を指定して零行列を作成できます。

行数と列数を指定するコンストラクタ
public Matrix(int row, int column)

特に、正方行列の場合は引数は1つだけで大丈夫です。

正方行列のコンストラク
public Matrix(int rowandColumn)

プロパティ

行列の要素の取得と上書きを行えます。

行列の要素
public double this[int i, int j]

行列の行数と列数のプロパティは読み取り専用です。

行数
public int Row
列数
public int Column

メソッド

ファイル名順に紹介します。

Add
行列の足し算を演算子のオーバーロードとして定義しました。

足し算
public static Matrix operator +(in Matrix left, in Matrix right)

Clone
行列を複製する

複製
public Matrix Clone()

EigenValues
固有値を計算します。orderByAbsTrueのときに絶対値の降順に返します。

固有値
public double[] EigenValues(int numberOfEigenValues, bool orderByAbs)

EigenVectors
固有ベクトルを計算します。orderByAbsTrueのときに、固有値の絶対値の降順に対応する固有ベクトルの集合を返します。

固有ベクトル
public List<ColumnVector> EigenVectors(int numberOfEigenValues, bool orderByAbs)

HadamardProduct
行列のアダマール積\circを計算します。

アダマール積
public Matrix HadamardProduct(in Matrix right)

Inverse
逆行列を計算する。

逆行列
public Matrix Inverse()

Multiply
行列の掛け算を演算子のオーバーロードとして定義しました。

掛け算
public static Matrix operator *(in Matrix left, in Matrix right)

PickUpColumnVector
列ベクトルを取得する。

列ベクトルの取得
public ColumnVector PickUpColumnVector(int column)

PickUpRowVector
行ベクトルを取得する。

行ベクトルの取得
public RowVector PickUpRowVector(int row)

Subtract
行列の引き算を演算子のオーバーロードとして定義しました。

引き算
public static Matrix operator -(in Matrix left, in Matrix right)

Transpose
転置行列を計算します。

転置
public Matrix Transpose() 

ColumnVector

コンストラクタ

1次元配列を行列に変換します。

1次元配列を引数とするコンストラクタ
public ColumnVector(double[] array)

また、ベクトルの次元を指定して零ベクトルを作成できます。

ベクトルの次元を指定するコンストラクタ
public ColumnVector(int dimension)

プロパティ

ベクトルの要素の取得と上書きを行えます。

ベクトルの要素の要素
public double this[int i]

ベクトルの次元のプロパティは読み取り専用です。

ベクトルの次元
public int Dimension

メソッド

ファイル名順に紹介します。

Add
行列の足し算を演算子のオーバーロードとして定義しました。

足し算
public static ColumnVector operator +(in ColumnVector left, in ColumnVector right)

Clone
オブジェクトを複製します。

複製
public ColumnVector Clone()

DotProduct
ベクトルの内積を計算します。

ベクトルの内積
public double DotProduct(in ColumnVector right)

HadamardProduct
ベクトルール積\circを計算します。

アダマール積
public ColumnVector HadamardProduct(in ColumnVector right)

Subtract
ベクトルの引き算を演算子のオーバーロードとして定義しました。

引き算
public static ColumnVector operator -(in ColumnVector left, in ColumnVector right)

Transpose
ベクトルの転置を計算します。

転置
public RowVector Transpose()

UnitVector
単位ベクトルを計算します。

転置
public ColumnVector UnitVector()

RowVector

コンストラクタ

1次元配列を行列に変換します。

1次元配列を引数とするコンストラクタ
public RowVector(double[] array)

また、ベクトルの次元を指定して零ベクトルを作成できます。

ベクトルの次元を指定するコンストラクタ
public RowVector(int dimension)

プロパティ

ベクトルの要素の取得と上書きを行えます。

ベクトルの要素の要素
public double this[int i]

ベクトルの次元のプロパティは読み取り専用です。

ベクトルの次元
public int Dimension

メソッド

ファイル名順に紹介します。

Add
行列の足し算を演算子のオーバーロードとして定義しました。

足し算
public static RowVector operator +(in RowVector left, in RowVector right)

Clone
オブジェクトを複製します。

複製
public RowVector Clone()

DotProduct
ベクトルの内積を計算します。

ベクトルの内積
public double DotProduct(in RowVector right)

HadamardProduct
ベクトルール積\circを計算します。

アダマール積
public RowVector HadamardProduct(in RowVector right)

Subtract
ベクトルの引き算を演算子のオーバーロードとして定義しました。

引き算
public static RowVector operator -(in RowVector left, in RowVector right)

Transpose
ベクトルの転置を計算します。

転置
public ColumnVector Transpose()

UnitVector
単位ベクトルを計算します。

転置
public RowVector UnitVector()

行列とベクトルの積

行列と列ベクトルの積A \vec{x}や、行ベクトルと行列の積\vec{x}^T Aなどの演算子やメソッドを紹介します。

列ベクトルと行ベクトルの積(演算子)

列ベクトルと行ベクトルの積
public static Matrix operator *(in ColumnVector columnVectorMultiplicand, in RowVector rowVectorMultiplier)

行列と列ベクトルの積(演算子)

行列と列ベクトルの積
public static ColumnVector operator *(in Matrix matrixMultiplicand, in ColumnVector columnVectorMultiplier)

行ベクトルと列ベクトルの積(演算子)

行ベクトルと列ベクトルの積
public static double operator *(in RowVector rowVectorMultiplicand, in ColumnVector columnVectorMultiplier)

列ベクトルのスカラー倍(演算子)

列ベクトルのスカラー倍
public static ColumnVector operator *(double scalar, ColumnVector vector)
列ベクトルのスカラー倍
public static ColumnVector operator *(ColumnVector vector, double scalar)

行列のスカラー倍(演算子)

行列のスカラー倍
public static Matrix operator *(double scalar, Matrix matrix)
行列のスカラー倍
public static Matrix operator *(Matrix matrix, double scalar)

行ベクトルのスカラー倍(演算子)

行ベクトルのスカラー倍
public static RowVector operator *(double scalar, RowVector vector)
行ベクトルのスカラー倍
public static RowVector operator *(RowVector vector, double scalar)

IRandomNumber

疑似乱数を生成するインターフェースです。
周期2^19937-1個のメルセンヌツイスターに基づいて乱数を生成しているので、インスタンス化した後に同じ乱数列が出てくる心配はなくなるでしょう。

共通メソッド

乱数の種の上書きと読み取りメソッド。

乱数の種を設定する。
void SetSeeds(uint[] setSeeds);
乱数の種を取得する
uint[] GetSeeds();

パラメータの上書きと読み取りはメソッドにしました。
プロパティで配列を読み取ると、上書きされてしまう危険性があるらしいので、メソッドにしました。

パラメータを設定する。
void SetSeeds(uint[] setSeeds);
パラメータを取得する
uint[] GetSeeds();

乱数を生成するメソッドです。
変数1個だけの場合と、配列で返す場合の3種類用意しました。

乱数を生成する
double NextDouble();
乱数列を生成する
double[] NextDoubles(int length);
乱数列を生成する
double[,] NextDoubles(int length0, int length1);

派生クラス

コーシー分布のクラス
CauchyDistribution

指数分布のクラス
ExponentialDistribution

対数正規分布のクラス
LogNormalDistribution

正規分布のクラス
NormalDistribution

一様分布のクラス
UniformDistribution

IKernel

サポートベクトルマシンやガウス過程回帰で使用するためのカーネル関数のインターフェースです。

共通メソッド

ハイパーパラメータの設定と読み取りメソッドです。

ハイパーパラメータの設定
void SetHyperParameters(double[] hyperParameter);
ハイパーパラメータの次元の読み取り
int HyperParameterDimension();

カーネル関数を計算するメソッドを用途別に用意しました。
基本的には下記の関数を使用してください。

カーネル関数を計算する
double Kernel(RowVector vector01, RowVector vector02);

自分自身とのカーネル関数は計算量が少ない場合が多いので、別の関数として定義しました。

自分自身とのカーネル関数を計算する
double KernelOneself(RowVector vector01);
自分自身とのカーネル関数を計算する
ColumnVector KernelOneself(Matrix designMatrixTest);

訓練データのグラム行列を計算する。

訓練データのグラム行列
Matrix GramMatrixTrain(Matrix designMatrixTrain);

テストデータのグラム行列を計算する。

テストデータのグラム行列
Matrix GramMatrixTest(Matrix designMatrixTest, Matrix designMatrixTrain);
テストデータのグラム行ベクトル
RowVector GramVectorTest(RowVector rowVectorTest, Matrix designMatrixTrain);

派生クラス

今のところガウシアンカーネルのみ定義しています。
GaussianKernel

IGraphLaplacian

スペクトルクラスタリングで使用するグラフラプラシアンのインターフェースです。

共通メソッド

ハイパーパラメータの設定と読み取りメソッドです。

ハイパーパラメータの設定
void SetHyperParameters(double[] hyperParameter);
ハイパーパラメータの次元の読み取り
int HyperParameterDimension();

グラフラプラシアンに用いる3種類の行列のメソッドを書きました。

隣接行列
Matrix AdjacencyMatrix(Matrix designMatrix);
次数行列
Matrix DegreeMatrix(Matrix designMatrix);
ラプラシアン行列
Matrix LaplacianMatrix(Matrix designMatrix);

派生クラス

今のところガウシアンのみ定義しています。
GaussianGraphLaplacian

応用クラス(Applied)の説明

DesignMatrix

計画行列の計算を行う静的クラスです。

メソッド

相関係数行列
public static Matrix CorelationMatrix(Matrix designMatrix)
分散・共分散行列の逆行列
public static Matrix InverseVarianceCovarianceMatrix(Matrix designMatrix)
計画行列の平均ベクトル
public static RowVector Mean(Matrix designMatrix)
測定値(列ベクトル)の平均値
ublic static double Mean(ColumnVector measuredVariables)
各成分の標準偏差
public static RowVector StandardDeviation(Matrix designMatrix)
測定値の標準偏差
public static double StandardDeviation(ColumnVector measuredVariables)
分散・共分散行列
public static Matrix VarianceCovarianceMatrix(Matrix designMatrix)

GaussianProcessRegression

ガウス過程回帰の計算を行う静的クラスです。

メソッド

グラム行列の逆行列
public static Matrix Learn(Matrix trainingDesignMatrix, IKernel iKernel, double[] hyperParameters, double noiseLambda = 0)
期待値[0]と分散[1]
public static List<double> Predict(Matrix trainingDesignMatrix, IKernel iKernel, double[] hyperParameters, ColumnVector trainingMeasuredVariables, Matrix gramMatrixInverse, RowVector testRowVector)

LinearRegression

線形回帰の計算を行う静的クラスです。

メソッド

線形回帰の係数ベクトル
public static ColumnVector Learn(Matrix trainingDesignMatrix, ColumnVector trainingMeasuredVariables)
主成分回帰
public static ColumnVector LearnPCR(Matrix trainingDsignMatrix, ColumnVector trainingMeasuredVariables, int numberLatentVariables)
部分的最小二乗法
public static ColumnVector LearnPLS1(Matrix trainingDsignMatrix, ColumnVector trainingMeasuredVariables, int numberLatentVariables)
Ridge回帰の係数ベクトル
public static ColumnVector LearnRidge(Matrix trainingDsignMatrix, ColumnVector trainingMeasuredVariables, double lambda)
予測
public static ColumnVector Predict(Matrix testDesignMatrix, ColumnVector coefficientW)

LogisticRegression

ロジスティック回帰の静的クラスです。

メソッド

学習
public static ColumnVector Learn(Matrix trainingDsignMatrix, ColumnVector trainingMeasuredVariables, int iterationCount = 100)
予測
public static ColumnVector Predict(Matrix testDesignMatrix, ColumnVector coefficientW)
予測
public static double Predict(RowVector testRowVector, ColumnVector coefficientW)

Preprocessing

前処理の静的クラスです。

メソッド

線形回帰用に定数項を加える
public static RowVector AddConstant(RowVector rowVector)
線形回帰用に定数項を加える
public static Matrix AddConstant(Matrix designMatrix)
Centroidを原点とする相対位置行ベクトル
public static RowVector RelativePosition(RowVector rowVector, RowVector centroid)
Centroidを原点とする相対位置計画行列
public static Matrix RelativePosition(Matrix designMatrix, RowVector centroid)
Centroidを原点とする相対位置列ベクトルを計算する
public static ColumnVector RelativePosition(ColumnVector measuredVariables, double centroid)
Centroidを原点とする相対位置を計算する
public static double RelativePosition(double measuredVariable, double centroid)
説明変数の行ベクトルを標準化する
public static RowVector ZScoreNormarization(RowVector rowVector, RowVector average, RowVector standardDeviation)
計画行列を標準化する.
public static Matrix ZScoreNormarization(Matrix designMatrix, RowVector average, RowVector standardDeviation)
目的変数の列ベクトルを標準化する.
public static ColumnVector ZScoreNormarization(ColumnVector measuredVariables, double average, double standardDeviation)
目的変数を標準化する.
public static double ZScoreNormarization(double measuredVariable, double average, double standardDeviation)
標準化した説明変数の行ベクトルを元に戻す.
public static RowVector ZScoreNormarizationInverse(RowVector rowVector, RowVector average, RowVector standardDeviation)
標準化した計画行列を元に戻す
public static Matrix ZScoreNormarizationInverse(Matrix designMatrix, RowVector average, RowVector standardDeviation)
標準化した説明変数を元に戻す
public static ColumnVector ZScoreNormarizationInverse(ColumnVector measuredVariables, double average, double standardDeviation)
標準化した説明変数を元に戻す
public static double ZScoreNormarizationInverse(double measuredVariable, double average, double standardDeviation)

PrincipalComponentAnalysis

主成分分析を行う静的クラスです。

メソッド

計画行列の積和行列から、主成分得点を計算する
public static List<ColumnVector> PrincipalComponentScores(Matrix designMatrix)
計画行列の積和行列から、主成分得点を計算する
public static List<ColumnVector> PrincipalComponentScores(Matrix designMatrix, int numberLatentVariables)
計画行列の積和行列から、主成分を計算する
public static List<ColumnVector> PrincipalComponents(Matrix designMatrix)
計画行列の積和行列から、主成分を計算する
public static List<ColumnVector> PrincipalComponents(Matrix designMatrix, int numberLatentVariables)

SpectralClustering

スペクトルクラスタリングを行う静的クラスです。

メソッド

クラスタリング
public static int[] Labeling(Matrix designMatrix, int numberOfClass, IGraphLaplacian iGraphLaplacian, double[] hyperparameters)

KMeansClustering

k-平均法を行う静的クラスです。

メソッド

クラスタリング
public static int[] Labeling(Matrix designMatrix, int numberOfClass)

終わりに

ReadMeが微妙なライブラリは使いたくないですが、いざ自分が作るとなると手を抜きたくなりますね。

Discussion