<jupyter_start><jupyter_text>행렬 : 표준 기능Matrix : Standard library <NAME>, Advanced Engineering Mathematics, Jones and Bartlett Publishers, 2006.  정의Definition<jupyter_code>mat_A = [
    [9, 7, 0, 8],
    [0.5, -2, 6, 1],
    [0, 0, -1, 6],
    [5, 3**0.5, math.pi, -4]
]


mat_A


pprint.pprint(mat_A)<jupyter_output><empty_output><jupyter_text>shape<jupyter_code>def n_rows(mat):
    return len(mat)


n_rows(mat_A)


def n_columns(mat):
    result = len(mat[0])
    for k, row in enumerate(mat[1:]):
        assert len(row) == result, f"row {k+1} has length {len(row)}"
    return result


n_columns(mat_A)


def shape(mat):
    return (n_rows(mat), n_columns(mat))


shape(mat_A)<jupyter_output><empty_output><jupyter_text>비교Comparison<jupyter_code>mat_22_0 = [
    [1, 1],
    [1, 1]
]


mat_22_0


pprint.pprint(mat_22_0, width=10)


shape(mat_22_0)


mat_22_1 = [
    [1, 1],
    [1, 1]
]


mat_22_2 = [
    [1, 1],
    [1, 2]
]


mat_23 = [
    [1, 1, 1],
    [1, 1, 1]
]


shape(mat_23)


def equal(mat_A, mat_B):
    result = True
    
    if (shape(mat_A) != shape(mat_B)):
        result = False
    else:
        for row_A, row_B in zip(mat_A, mat_B):
            for col_A, col_B in zip(row_A, row_B):
                if (col_A != col_B):
                    result = False
                    break
            if not result:
                break

    return result


assert equal(mat_22_0, mat_22_1)


assert not equal(mat_22_0, mat_22_2)


assert not equal(mat_22_0, mat_23)<jupyter_output><empty_output><jupyter_text>리스트 컴프리핸션List comprehension<jupyter_code>def equal_list_comprehension(mat_A, mat_B):
    return (shape(mat_A) == shape(mat_B)) and all(
        [ all(
            [
               (col_A == col_B) for col_A, col_B in zip(row_A, row_B)
            ]
        ) for row_A, row_B in zip(mat_A, mat_B)
        ]
    )


assert equal_list_comprehension(mat_22_0, mat_22_1)


assert not equal_list_comprehension(mat_22_0, mat_22_2)


assert not equal_list_comprehension(mat_22_0, mat_23)<jupyter_output><empty_output><jupyter_text>`itertools.chain.from_iterable()`<jupyter_code>import itertools


def equal_itertools_chain_from_iterable(mat_A, mat_B):
    return (shape(mat_A) == shape(mat_B)) and all([
        a_ij == b_ij 
        for a_ij, b_ij in zip(
            itertools.chain.from_iterable(mat_A),
            itertools.chain.from_iterable(mat_B))
    ])


assert equal_itertools_chain_from_iterable(mat_22_0, mat_22_1)


assert not equal_itertools_chain_from_iterable(mat_22_0, mat_22_2)


assert not equal_itertools_chain_from_iterable(mat_22_0, mat_23)<jupyter_output><empty_output><jupyter_text>덧셈Addition<jupyter_code>def add_mat(mat_A, mat_B):
    assert shape(mat_A) == shape(mat_B), (
        f"shape(mat_A) = {shape(mat_A)}, "
        f"shape(mat_B) = {shape(mat_B)}"
    )

    result = []

    for row_A, row_B in zip(mat_A, mat_B):
        new_row = []

        for col_A, col_B in zip(row_A, row_B):
            new_row.append(col_A + col_B)

        result.append(new_row)

    return result


mat_A_33 = [
    [2, -1, 3],
    [0, 4, 6],
    [-6, 10, -5],
]


mat_B_33 = [
    [4, 7, -8],
    [9, 3, 5],
    [1, -1, 2],
]


pprint.pprint(add_mat(mat_A_33, mat_B_33), width=20)


try:
    pprint.pprint(add_mat(mat_A_33, mat_22_0), width=20)
except AssertionError as e:
    print(e)
else:
    assert True, "Raise expected"<jupyter_output><empty_output><jupyter_text>스칼라 곱Scalar mutiple<jupyter_code>def mul_scalar_mat(a, mat_A):
    result = []

    for row_A in mat_A:
        new_row = []

        for col_A in row_A:
            new_row.append(col_A * a)

        result.append(new_row)

    return result


mat_A = [
    [2, -3],
    [4, -1],
]


pprint.pprint(mul_scalar_mat(5, mat_A), width=15)<jupyter_output><empty_output><jupyter_text>Transpose<jupyter_code>def transpose(mat_A):
    n_row, n_col = shape(mat_A)

    result = []
    for j in range(n_col):
        new_row = []
        result.append(new_row)

        for i in range(n_row):
            new_row.append(mat_A[i][j])

    return result


pprint.pprint(transpose(mat_A), width=15)<jupyter_output><empty_output><jupyter_text>행렬 벡터 곱셈Matrix vector product<jupyter_code>def mul_mat_vec(mat_A, vec_x):
    n_row, n_col = shape(mat_A)
    
    assert n_col == len(vec_x), f"shape(mat_A) = {shape(mat_A)}, len(vec_x) = {len(vec_x)}"

    result = [0.0] * n_row

    for i in range(n_row):
        for k in range(n_col):
            result[i] += mat_A[i][k] * vec_x[k]

    return result


mat_A = [
    [4, 7],
    [3, 5],
]

vec_x = [9,
         6]

mul_mat_vec(mat_A, vec_x)<jupyter_output><empty_output><jupyter_text>실은 행렬의 각 행과 벡터의 내적을 모은 것이다.In fact, it is a collection of inner products of each row of the matrix and the vector. $$\begin{pmatrix}    a_{00} & a_{01} & a_{02} \\    \hline    a_{10} & a_{11} & a_{12} \\    \hline    a_{20} & a_{21} & a_{22} \\    \hline    a_{30} & a_{31} & a_{32} \\\end{pmatrix}\begin{pmatrix}    x_0 \\ x_1 \\ x_2\end{pmatrix} = \begin{pmatrix}    \mathbb{a}_0 \\ \mathbb{a}_1 \\ \mathbb{a}_2 \\ \mathbb{a}_3\end{pmatrix} \mathbb{x} =\begin{pmatrix}    \mathbb{a}_0 \cdot \mathbb{x} \\     \mathbb{a}_1 \cdot \mathbb{x} \\    \mathbb{a}_2 \cdot \mathbb{x} \\     \mathbb{a}_3 \cdot \mathbb{x}\end{pmatrix}$$[//]:  (horizontal lines : https://tex.stackexchange.com/questions/253739/vertical-and-horizontal-line-in-a-matrix)[//]:  (vertical lines : https://tex.stackexchange.com/questions/33519/vertical-line-in-matrix-using-latexit)[//]:  (markdown comments : https://alvinalexander.com/technology/markdown-comments-syntax-not-in-generated-output)[//]:  (markdown comments : https://stackoverflow.com/questions/4823468/comments-in-markdown)[//]:  (bold vector : https://de.overleaf.com/learn/latex/Mathematical_fonts)<jupyter_code>def dot(vec_a, vec_b):

    assert len(vec_a) == len(vec_b), f"len(vec_a) = {len(vec_a)}, len(vec_b) = {len(vec_b)}"

    return sum(ai * bi for ai, bi in zip(vec_a, vec_b))


def mul_mat_vec_dot(mat_A, vec_x):

    assert shape(mat_A)[1] == len(vec_x), f"shape(mat_A) = {shape(mat_A)}, len(vec_x) = {len(vec_x)}"

    return [dot(row, vec_x) for row in mat_A ]


mul_mat_vec_dot(mat_A, vec_x)


assert mul_mat_vec(mat_A, vec_x) == mul_mat_vec_dot(mat_A, vec_x)<jupyter_output><empty_output><jupyter_text>행렬 곱셈Matrix product 다음 비디오는 행렬 곱셈을 소개한다.The following video introduces the Matrix Multiplication. (00:43 ~ 6:17)[![MIT OCW 18.06 Lecture 2 Gauss Elimination](https://i.ytimg.com/vi/FX4C-JpTFgY/hqdefault.jpg)](https://www.youtube.com/watch?v=FX4C-JpTFgY&list=PL221E2BBF13BECF6C&index=9&start=43&end=377)<jupyter_code>def mul_mat(mat_A, mat_B):
    n_row_A, n_col_A = shape(mat_A)
    n_row_B, n_col_B = shape(mat_B)

    assert n_col_A == n_row_B, f"shape(mat_A) = {shape(mat_A)}, shape(mat_B) = {shape(mat_B)}"

    result = []

    for i in range(n_row_A):
        new_row = []

        for j in range(n_col_B):

            aij = 0
            for k in range(n_col_A):
                aij += mat_A[i][k] * mat_B[k][j]

            new_row.append(aij)

        result.append(new_row)

    return result


mat_A = [
    [4, 7],
    [3, 5],
]


mat_B = [
    [9, -2],
    [6, 8],
]


pprint.pprint(mul_mat(mat_A, mat_B), width=10)<jupyter_output><empty_output><jupyter_text>자세히 살펴보면 앞 행렬의 각 행 벡터와 뒤 행렬의 각 열 벡터의 내적을 모은 것임을 알 수 있다.Careful observation would reveal that the matrix product is a collection of inner products of each row vector of the multiplicand and each column vector of multiplier matrices. $$\begin{pmatrix}    a_{00} & a_{01} & a_{02} \\    \hline    a_{10} & a_{11} & a_{12} \\    \hline    a_{20} & a_{21} & a_{22} \\    \hline    a_{30} & a_{31} & a_{32} \\\end{pmatrix}\left(\begin{array}{c|c|c}    x_{00} & x_{01} & x_{02} \\     x_{10} & x_{11} & x_{12} \\     x_{20} & x_{21} & x_{22}\end{array} \right) \\ = \begin{pmatrix}    \mathbb{a}_0 \\ \mathbb{a}_1 \\ \mathbb{a}_2 \\ \mathbb{a}_3\end{pmatrix} \begin{pmatrix}    \mathbb{x}_0 & \mathbb{x}_1 & \mathbb{x}_2\end{pmatrix} \\ =\begin{pmatrix}    \mathbb{a}_0 \cdot \mathbb{x}_0 & \mathbb{a}_0 \cdot \mathbb{x}_1 & \mathbb{a}_0 \cdot \mathbb{x}_2 \\     \mathbb{a}_1 \cdot \mathbb{x}_0 & \mathbb{a}_1 \cdot \mathbb{x}_1 & \mathbb{a}_1 \cdot \mathbb{x}_2 \\    \mathbb{a}_2 \cdot \mathbb{x}_0 & \mathbb{a}_2 \cdot \mathbb{x}_1 & \mathbb{a}_2 \cdot \mathbb{x}_2 \\     \mathbb{a}_3 \cdot \mathbb{x}_0 & \mathbb{a}_3 \cdot \mathbb{x}_1 & \mathbb{a}_3 \cdot \mathbb{x}_2\end{pmatrix}$$[//]:  (horizontal lines : https://tex.stackexchange.com/questions/253739/vertical-and-horizontal-line-in-a-matrix)[//]:  (vertical lines : https://tex.stackexchange.com/questions/33519/vertical-line-in-matrix-using-latexit)[//]:  (markdown comments : https://alvinalexander.com/technology/markdown-comments-syntax-not-in-generated-output)[//]:  (markdown comments : https://stackoverflow.com/questions/4823468/comments-in-markdown)[//]:  (bold vector : https://de.overleaf.com/learn/latex/Mathematical_fonts)<jupyter_code>def mul_mat_dot(mat_A, mat_B):
    n_row_A, n_col_A = shape(mat_A)
    n_row_B, n_col_B = shape(mat_B)

    assert n_col_A == n_row_B, f"shape(mat_A) = {shape(mat_A)}, shape(mat_B) = {shape(mat_B)}"

    mat_B_T = transpose(mat_B)
    
    result = []

    for row_A in mat_A:
        new_row = []

        for col_B in mat_B_T:

            new_row.append(dot(row_A, col_B))

        result.append(new_row)

    return result


pprint.pprint(mul_mat_dot(mat_A, mat_B), width=10)<jupyter_output><empty_output><jupyter_text>리스트 줄여쓰기List comprehension<jupyter_code>def mul_mat_dot_list_comp(mat_A, mat_B):

    assert shape(mat_A)[1] == shape(mat_B)[0], f"shape(mat_A) = {shape(mat_A)}, shape(mat_B) = {shape(mat_B)}"

    return [
        [
            dot(row_A, col_B)
            for col_B in transpose(mat_B)
        ]
        for row_A in mat_A
    ]
    return result


pprint.pprint(mul_mat_dot_list_comp(mat_A, mat_B), width=10)


assert equal(mul_mat_dot(mat_A, mat_B), mul_mat_dot_list_comp(mat_A, mat_B))<jupyter_output><empty_output><jupyter_text>함수형Functional programming<jupyter_code>def mul_mat_dot_functional(mat_A, mat_B):

    assert shape(mat_A)[1] == shape(mat_B)[0], f"shape(mat_A) = {shape(mat_A)}, shape(mat_B) = {shape(mat_B)}"

    return list(map(lambda a: list(map(lambda b: dot(a, b), transpose(mat_B))), mat_A))


pprint.pprint(mul_mat_dot_functional(mat_A, mat_B), width=10)


assert equal(mul_mat_dot(mat_A, mat_B), mul_mat_dot_functional(mat_A, mat_B))<jupyter_output><empty_output><jupyter_text>Final Bell마지막 종<jupyter_code># stackoverfow.com/a/24634221
import os
os.system("printf '\a'");<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15580869892675578, 'fraction_numerical': 0.03502165317266052, 'mean_word_length': 3.402403646912557, 'pattern_counts': {'":': 0, '<': 62, '<?xml version=': 0, '>': 62, 'https://': 12, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '15', 'dir': 'jupyter-structured-clean-dedup', 'id': '324926', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 4799, 'n_tokens_neox': 4584, 'n_words': 778, 'path': '40_linear_algebra_1/40_matrix_and_vector.ipynb', 'repo_name': 'kangwonlee/2109eca-nmisp-template', 'size': '10629'}