何故自作するか
画像処理100本ノックに挑戦中です。全体の1/4くらいが終わったあたりでそろそろ行列演算が出来た方がよい予感がします。
普段はEigenというライブラリを使っているのですが、これを使うと負けた気がします。せっかくなので自作してみることにします。Eigenのインターフェースを参考にしていますが、100本ノックを乗り切る範囲での実装なのでクオリティは低いです。エラー処理も実装しません。
コード
必要に応じて修正予定です(まだ引き算もない・・・)。
class Matrix
{
int N, M;
std::vector<std::vector<double>> a;
public:
Matrix(int M, int N=1) : N{ N }, M{ M }, a(M, std::vector < double >(N) )
{
}
void set(std::initializer_list<double> list)
{
int m = 0, n = 0;
for ( auto&& v : list)
{
a[m][n++] = v;
if (n == N)
{
n = 0, m++;
}
}
}
double& operator()(int i, int j)
{
return a[i][j];
}
void print()
{
for(int i=0; i<M; i++)
for (int j = 0; j < N; j++)
{
std::cout << a[i][j];
if (j == N - 1) std::cout << std::endl;
else std::cout << " ";
}
}
Matrix operator+(Matrix& mat) const
{
Matrix ret(M,N);
for(int i=0; i<M; i++)
for (int j = 0; j < N; j++)
{
ret(i, j) = a[i][j] + mat(i, j);
}
return ret;
}
Matrix operator*(double val) const
{
Matrix ret(M, N);
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
{
ret(i, j) *= val;
}
return ret;
}
Matrix operator*(Matrix& mat) const
{
Matrix ret(M, mat.Get_MN().second);
for (int i = 0; i < M; i++)
for (int j = 0; j < mat.Get_MN().second; j++)
{
ret(i, j) = 0;
for (int k = 0; k < N; k++) ret(i, j) += a[i][k] * mat(k, j);
}
return ret;
}
std::pair<int, int> Get_MN() const
{
return std::pair<int, int>(M, N);
}
};
使い方
int main()
{
Matrix mat(2, 2);//2x2行列
mat.set(
{1, 2,
3, 4});//値をセット
Matrix v(2);//2x1行列
v.set(
{
3,
4
});
( mat * v).print();//積をとって結果を表示
}