（正方）行列の足し算・引き算をプログラムで実装（Python）

# 行列とは

行列とは線形代数で学ぶベクトルの応用、高専では2年生で初めて学習するものです。

```math
\begin{align*}
  \begin{pmatrix}
    a_{11} & a_{12}\\
    a_{21} & a_{22}
  \end{pmatrix}
\end{align*}
```

このような( )で挟んで成分を書き表したものが行列です。横向きが行、縦向きが列であり、このような行と列の大きさが等しい行列を<INS>正方行列</INS>と呼びます。
ここで行列$A$と行列$B$があるとき、**足し算をする場合は$A+B$,$B+A$のどちらで計算しても結果は変わりません。**
ということでまずは足し算の仕方を紹介します。

## 行列の足し算
行列の足し算はベクトルと同じく各成分同士を合計します。 また、<INS>足し合わせる行列の行と列の数は一致している必要があります。</INS> 今回は、

```math
\begin{align*}
  A = 
  \begin{pmatrix}
    a_{11} & a_{12}\\
    a_{21} & a_{22}
  \end{pmatrix}
  ,\; B =
  \begin{pmatrix}
    b_{11} & b_{12}\\
    b_{21} & b_{22}
  \end{pmatrix}
\end{align*}
```

とします。このとき行列$A, B$の足し算は次のようになります。

```math
\begin{align*}
  A + B = B + A = 
  \begin{pmatrix}
    a_{11} & a_{12}\\
    a_{21} & a_{22}
  \end{pmatrix}
  +
  \begin{pmatrix}
    b_{11} & b_{12}\\
    b_{21} & b_{22}
  \end{pmatrix}
  =
  \begin{pmatrix}
    a_{11}+b_{11} & a_{12}+b_{12}\\
    a_{21}+b_{21} & a_{22}+b_{22}
  \end{pmatrix}
\end{align*}
```

これで行列の足し算は終了です。続いて行列の引き算を紹介します。


## 行列の引き算
行列の足し算の仕方が理解できれば引き算も簡単です。ただし**引き算の場合は$A-B$と$B-A$では計算結果が異なるのでそこは注意しなければいけません！！**

```math
\begin{align*}
  A - B &=
  \begin{pmatrix}
    a_{11} & a_{12}\\
    a_{21} & a_{22}
  \end{pmatrix}
  -
  \begin{pmatrix}
    b_{11} & b_{12}\\
    b_{21} & b_{22}
  \end{pmatrix}\\
  &=
  \begin{pmatrix}
    a_{11} & a_{12}\\
    a_{21} & a_{22}
  \end{pmatrix}
  +
  \begin{pmatrix}
    -b_{11} & -b_{12}\\
    -b_{21} & -b_{22}
  \end{pmatrix}\\
  &=
  \begin{pmatrix}
    a_{11}-b_{11} & a_{12}-b_{12}\\
    a_{21}-b_{21} & a_{22}-b_{22}
  \end{pmatrix}
\end{align*}
```

ここで引き算の計算方法より補足をします。
例えば、$cA$ ($c$は定数)のように行列の前に定数が掛かっている場合は次のように変形できます。

```math
\begin{align*}
  c
  \begin{pmatrix}
    a_{11} & a_{12}\\
    a_{21} & a_{22}
  \end{pmatrix}
  =
  \begin{pmatrix}
    ca_{11} & ca_{12}\\
    ca_{21} & ca_{22}
  \end{pmatrix}
\end{align*}
```

それでは行列の基礎を学習したところで、これをPythonで実装してみましょう！

# Pythonで実装
今回は行列$A,B$を正方行列とするときの足し算、引き算を求めるプログラムを作成します。
行列$A,B$があるとき、足し算、引き算を求めるには3パターンを考慮する必要があります。

1. $A+B$
1. $A-B$
1. $B-A$

ここで、「**<font color="red">$B+A$が無いじゃないか！</font>**」という意見がある人もいるかもしれません。
先ほど説明したように、足し算は順序を入れ替えても結果が変わらないので今回は1つだけで大丈夫です。

では実際にPythonでこれらの行列演算を行えるようにしてみましょう。

```python:pMatrix.py
import numpy as np

def func1():
    n = int(input("n x nのnを入力 > "))

    # n x n正方行列の生成
    A = np.array([[0 for _ in range(n)] for _ in range(n)])
    B = np.array([[0 for _ in range(n)] for _ in range(n)])

    # 確認用
    #print(A)
    #print(B)

    for i in range(n):
        for j in range(n):
            A[i][j] = int(input(f"行列Aの{i}行{j}列目を入力 > "))

    print("\nA = ")
    for i in range(n):
        for j in range(n):
            print(f"{A[i][j]}", end="\t")
        print()
    
    print()
    for i in range(n):
        for j in range(n):
            B[i][j] = int(input(f"行列Bの{i}行{j}列目を入力 > "))
    
    print("\nB = ")
    for i in range(n):
        for j in range(n):
            print(f"{B[i][j]}", end="\t")
        print()

    #確認用
    #print(f"行列A\n{A}")
    #print(f"行列B\n{B}")

    # A + B
    C = A + B
    print("\nA+B = ")
    for i in range(n):
        for j in range(n):
            print(f"{C[i][j]}", end="\t")
        print()

def func2():
    n = int(input("n x nのnを入力 > "))

    # n x n正方行列の生成
    A = np.array([[0 for _ in range(n)] for _ in range(n)])
    B = np.array([[0 for _ in range(n)] for _ in range(n)])

    # 確認用
    #print(A)
    #print(B)

    for i in range(n):
        for j in range(n):
            A[i][j] = int(input(f"行列Aの{i}行{j}列目を入力 > "))
    
    print("\nA = ")
    for i in range(n):
        for j in range(n):
            print(f"{A[i][j]}", end="\t")
        print()
    
    print()

    for i in range(n):
        for j in range(n):
            B[i][j] = int(input(f"行列Bの{i}行{j}列目を入力 > "))

    print("\nB = ")
    for i in range(n):
        for j in range(n):
            print(f"{B[i][j]}", end="\t")
        print()

    #確認用
    #print(f"行列A\n{A}")
    #print(f"行列B\n{B}")

    # A - B
    C = A - B
    print("\nA-B = ")
    for i in range(n):
        for j in range(n):
            print(f"{C[i][j]}", end="\t")
        print()

def func3():
    n = int(input("n x nのnを入力 > "))

    # n x n正方行列の生成
    A = np.array([[0 for _ in range(n)] for _ in range(n)])
    B = np.array([[0 for _ in range(n)] for _ in range(n)])

    # 確認用
    #print(A)
    #print(B)

    for i in range(n):
        for j in range(n):
            A[i][j] = int(input(f"行列Aの{i}行{j}列目を入力 > "))
    
    print("\nA = ")
    for i in range(n):
        for j in range(n):
            print(f"{A[i][j]}", end="\t")
        print()
    
    print()

    for i in range(n):
        for j in range(n):
            B[i][j] = int(input(f"行列Bの{i}行{j}列目を入力 > "))

    print("\nB = ")
    for i in range(n):
        for j in range(n):
            print(f"{B[i][j]}", end="\t")
        print()

    #確認用
    #print(f"行列A\n{A}")
    #print(f"行列B\n{B}")

    # B - A
    C = B - A
    print("\nB-A = ")
    for i in range(n):
        for j in range(n):
            print(f"{C[i][j]}", end="\t")
        print()

#メイン関数
print("正方行列を計算します。")
qus = int(input("何を求めたいですか？ - 1.A+B, 2.A-B, 3.B-A > "))

if qus == 1:
    func1()
elif qus == 2:
    func2()
elif qus == 3:
    func3()
else:
    exit()
```

最初にどの内容の演算を行いたいか選択します。このとき、選択肢にない番号や文字を入力するとプログラムが終了するようになっています。
次に$n\times n$行列の$n$を入力して行列のサイズを定めます。

また、今回は「import numpy」とあるように、行列演算を簡単に行えるようにしています。

実行すると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925398/51ec3c53-0563-82ad-213f-d3a0240fd312.png)

このように表示されます。
便利ですよね！！

<font color="red">**「えっ、Excelの方が簡単だって？ちょっとこっちへ来い...」**</font>