행렬 0x05: 덧셈, 뺄셈, 스칼라곱

행렬의 덧셈, 뺄셈 개념

$A - B = A + (-B)$이기 때문에 덧셈이 가능하다면 뺄셈도 가능하다. 두 행렬의 덧셈을 하기 위해선 두 행렬의 행 과 열이 서로 같아야한다. $2 × 4$ 행렬은 $3 × 6$ 행렬과 덧셈이 불가능하다. 덧셈을 하는 방법은 각 행렬의 같은 위치의 요소끼리 더하면 된다.

즉 같은 크기의 두 행렬이 있을 때, 각 행렬의 같은 위치에 있는 원소끼리 더하는 연산이다.

\[A = \begin{pmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{pmatrix}\] \[B = \begin{pmatrix} b_{11} & b_{12} & b_{13} \\ b_{21} & b_{22} & b_{23} \\ b_{31} & b_{32} & b_{33} \end{pmatrix}\]

행렬 $ A $와 $ B $의 덧셈 $ C $는 다음과 같이 정의된다.

\[C = A + B\]

여기에서 행렬 $ C $는 행렬 $ A $와 행렬 $ B $의 각 위치의 요소를 더해 똑같은 크기의 행렬로 만들어주면 된다.

\[c_{ij} = a_{ij} + b_{ij}\] \[C = \begin{pmatrix} a_{11} + b_{11} & a_{12} + b_{12} & a_{13} + b_{13} \\ a_{21} + b_{21} & a_{22} + b_{22} & a_{23} + b_{23} \\ a_{31} + b_{31} & a_{32} + b_{32} & a_{33} + b_{33} \end{pmatrix}\]

행렬의 스칼라 곱

스칼라 곱은 행렬의 각 원소에 같은 스칼라 값을 곱하는 연산이다. 스칼라 $ k $와 행렬 $ A $ 있을 때, 스칼라 곱 $ kA $는 다음과 같이 정의된다.

\[kA = k \begin{pmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{pmatrix} = \begin{pmatrix} k \cdot a_{11} & k \cdot a_{12} & k \cdot a_{13} \\ k \cdot a_{21} & k \cdot a_{22} & k \cdot a_{23} \\ k \cdot a_{31} & k \cdot a_{32} & k \cdot a_{33} \end{pmatrix}\]

C++ 구현

template <class K, u64 N, u64 M>
struct Matrix
{
    K data[N * M];

    K& operator()(u64, u64);
    const K& operator()(u64, u64) const;

    void Add(const Matrix&);
    void Sub(const Matrix&);
    void Scl(const K&);
};


template <class K, u64 N, u64 M>
Matrix<K, N, M> operator+(const Matrix<K, N, M>&, const Matrix<K, N, M>&);
template <class K, u64 N, u64 M>
Matrix<K, N, M> operator-(const Matrix<K, N, M>&, const Matrix<K, N, M>&);
template <class K, u64 N, u64 M>
Matrix<K, N, M> operator*(const Matrix<K, N, M>&, const K&);
template <class K, u64 N, u64 M>
Matrix<K, N, M> operator*(const K&, const Matrix<K, N, M>&);
template<class K, u64 N, u64 M>
void Matrix<K, N, M>::Add(const Matrix& rhs)
{
    for (u64 i = 0; i < N * M; ++i)
    {
        data[i] += rhs.data[i];
    }
}

template<class K, u64 N, u64 M>
void Matrix<K, N, M>::Sub(const Matrix& rhs)
{
    for (u64 i = 0; i < N * M; ++i)
    {
        data[i] -= rhs.data[i];
    }
}

template<class K, u64 N, u64 M>
void Matrix<K, N, M>::Scl(const K& scalar)
{
    for (u64 i = 0; i < N * M; ++i)
    {
        data[i] *= scalar;
    }
}

template<class K, u64 N, u64 M>
Matrix<K, N, M> operator+(const Matrix<K, N, M>& left, const Matrix<K, N, M>& right)
{
    Matrix<K, N, M> res(left);
    res.Add(right);
    return res;
}

template<class K, u64 N, u64 M>
Matrix<K, N, M> operator-(const Matrix<K, N, M>& left, const Matrix<K, N, M>& right)
{
    Matrix<K, N, M> res(left);
    res.Sub(right);
    return res;
}

template<class K, u64 N, u64 M>
Matrix<K, N, M> operator*(const Matrix<K, N, M>& left, const K& scalar)
{
    Matrix<K, N, M> res(left);
    res.Scl(scalar);
    return res;
}

template<class K, u64 N, u64 M>
Matrix<K, N, M> operator*(const K& scalar, const Matrix<K, N, M>& right)
{
    Matrix<K, N, M> res(right);
    res.Scl(scalar);
    return res;
}

Categories:

Updated:

Leave a comment