From 177c6fc121b98df28b0bffe6a5168fe653391870 Mon Sep 17 00:00:00 2001 From: "Kangwon Lee (Education)" Date: Mon, 13 May 2024 13:07:04 +0900 Subject: [PATCH] 40 / 20 : add b x a --- .../20_vector_dot_cross_product.ipynb | 1660 +++++++++-------- 1 file changed, 920 insertions(+), 740 deletions(-) diff --git a/40_linear_algebra_1/20_vector_dot_cross_product.ipynb b/40_linear_algebra_1/20_vector_dot_cross_product.ipynb index d385ef5c..d7e5f78b 100644 --- a/40_linear_algebra_1/20_vector_dot_cross_product.ipynb +++ b/40_linear_algebra_1/20_vector_dot_cross_product.ipynb @@ -1,742 +1,922 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "view-in-github", - "colab_type": "text" - }, - "source": [ - "\"Open\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 그래프, 수학 기능 추가\n", - "# Add graph and math features\n", - "import pylab as py\n", - "import numpy as np\n", - "import numpy.linalg as nl\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 벡터의 내적과 외적
Inner and Cross Products of Vectors\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 벡터의 내적
Inner Product of Vectors\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### `numpy`\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "벡터의 내적에 관해 아래 비디오 링크를 참고할 수 있다. (9:09) (내적 주요 설명 1:54 ~ 4:40)
\n", - "Regarding the vector inner product, you can check the following link. (9:09) (Inner product explanation 1:54 ~ 4:40)
\n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[![Vector dot product and vector length 벡터 내적과 벡터의 길이](https://i.ytimg.com/vi/WNuIhXo39_k/hqdefault.jpg)](https://www.youtube.com/watch?v=WNuIhXo39_k)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "예를 들어 2차원 벡터를 생각해 보자.
\n", - "For example, let's think about two-dimensional vectors (2D vectors).\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "* Feel free to modify the vector definitions below and re-run the cells to explore how different vectors behave under inner and cross product operations.
\n", - "아래 정의한 벡터는 가능한 예 가운데 하나이므로, 자신의 벡터를 입력하고 해당 노트북을 재실행하여 어떻게 달라지는지 관찰해 보기 바람\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# ref : https://www.youtube.com/watch?v=8QihetGj3pg\n", - "b = np.array((2, 5))\n", - "c = np.array((7, 1))\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "b\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "위 2차원 벡터를 한번 그려 보자
\n", - "Let's plot the 2D vectors above.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def draw_2dvec(x, y, x0=0, y0=0, color='k', name=None):\n", - " py.quiver(x0, y0, x, y, color=color, angles='xy', scale_units='xy', scale=1)\n", - " py.plot((x0, x0+x), (y0, y0+y), alpha=0)\n", - " if name is not None:\n", - " if not name.startswith('$'):\n", - " vec_str = '$\\\\vec{%s}$' % name\n", - " else:\n", - " vec_str = name\n", - " py.text(0.5 * x + x0, 0.5 * y + y0, vec_str)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "draw_2dvec(b[0], b[1], name='b')\n", - "draw_2dvec(c[0], c[1], name='c')\n", - "\n", - "py.axis('equal')\n", - "py.grid(True)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "이 두 벡터의 내적을 계산해 보자
Let's calculate the inner product of these two vectors.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "py.dot(b, c)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "확인해 보자.
Let's verify.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "b[0]*c[0] + b[1]*c[1]\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "다른 방법도 있다.
Other methods are available.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# https://docs.scipy.org/doc/numpy/reference/generated/numpy.inner.html\n", - "py.inner(b, c)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# https://docs.scipy.org/doc/numpy/reference/generated/numpy.inner.html\n", - "sum(b[:] * c[:])\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Python 3.5, Numpy 1.10 이상**에서는 **`@` 연산자**를 내적의 의미로 사용할 수 있다.
\n", - "For **Python 3.5 or higher and Numpy 1.10 or higher**, we can use **`@` operator** as inner product.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "b @ c\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "theta_a_deg = 30\n", - "theta_a_rad = np.deg2rad(theta_a_deg)\n", - "theta_b_deg = 120\n", - "theta_b_rad = np.deg2rad(theta_b_deg)\n", - "\n", - "a_row_array = np.array([np.cos(theta_a_rad), np.sin(theta_a_rad)])\n", - "b_row_array = np.array([np.cos(theta_b_rad), np.sin(theta_b_rad)])\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "draw_2dvec(a_row_array[0], a_row_array[1], name='a_{array}')\n", - "draw_2dvec(b_row_array[0], b_row_array[1], name='b_{array}')\n", - "\n", - "py.axis('equal')\n", - "py.grid(True)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print('a dot b (array) =', np.dot(a_row_array, b_row_array))\n", - "print('a_row_array @ b_row_array =', a_row_array @ b_row_array)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "* What happens to the inner product if you change the angle between the vectors?
벡터 사잇각이 달라지면 내적에는 어떤 영향을 미치는가?\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 표준 기능
Standard library\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "b_list = [2, 5]\n", - "c_list = [7, 1]\n", - "print(f\"b_list = {b_list}\")\n", - "print(f\"c_list = {c_list}\")\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def dot_product_list_comprehension(x_list, y_list):\n", - " assert len(x_list) == len(y_list)\n", - " return sum(xi*yi for xi, yi in zip(x_list, y_list))\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def dot_product_map(x_list, y_list):\n", - " assert len(x_list) == len(y_list)\n", - " return sum(map(lambda x_y:x_y[0] * x_y[1],zip(x_list, y_list)))\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def dot_product_list_for(x_list, y_list):\n", - " assert len(x_list) == len(y_list)\n", - " s = 0\n", - " for xi, yi in zip(x_list, y_list):\n", - " s += (xi * yi)\n", - " return s\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def dot_product_list_for_index(x_list, y_list):\n", - " assert len(x_list) == len(y_list)\n", - " s = 0\n", - " n = len(x_list)\n", - " for i in range(n):\n", - " s += (x_list[i] * y_list[i])\n", - " return s\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(f\"dot_product_list_comprehension(b_list, c_list) = {dot_product_list_comprehension(b_list, c_list)}\")\n", - "print(f\"dot_product_map(b_list, c_list) = {dot_product_map(b_list, c_list)}\")\n", - "print(f\"dot_product_list_for(b_list, c_list) = {dot_product_list_for(b_list, c_list)}\")\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "assert (\n", - " dot_product_list_comprehension(b_list, c_list) \n", - " == dot_product_map(b_list, c_list)\n", - " == dot_product_list_for(b_list, c_list)\n", - ")\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 벡터의 외적
Cross Product of Vectors\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "아래 비디오 링크를 참고할 수 있다. (15:46)
\n", - "Regarding the vector inner product, you can check the following link. (15:46)
\n", - "
\n", - "[![칸 아카데미 | 벡터와 벡터 공간 | 외적 소개
Khan Academy | Linear Algebra | Vectors and spaces | Cross product introduction](https://i.ytimg.com/vi/pJzmiywagfY/hqdefault.jpg)](https://www.youtube.com/watch?v=pJzmiywagfY)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "열벡터의 잇점은 무엇이라고 생각하는가?
\n", - "What do you think is the advantage of the column vector form?\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### `numpy`\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "다음과 같은 두 벡터를 생각해 보자.
Let's think about following two vectors.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "a = py.array((1, -7, 1))\n", - "b = py.array((5, 2, 4))\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "외적을 계산해 보자.
Let's calculate the cross product.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "a_cross_b = py.cross(a, b)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "a_cross_b\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "확인 해 보자.
Let's verify.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "py.dot(a, a_cross_b)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "py.dot(b, a_cross_b)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "외적의 결과가 $\\vec{a}$, $\\vec{b}$ 와 수직임을 알 수 있다.
We can see that the cross product is orthogonal to $\\vec{a}$ and $\\vec{b}$.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "from mpl_toolkits.mplot3d import Axes3D\n", - "import numpy as np\n", - "\n", - "\n", - "def plot_3dvec(ax, xyz, name=None):\n", - " ax.quiver(\n", - " *[0, 0, 0], *xyz,\n", - " )\n", - "\n", - " ax.plot3D(\n", - " (0, xyz[0]),\n", - " (0, xyz[1]),\n", - " (0, xyz[2]),\n", - " alpha=0\n", - " )\n", - "\n", - " if name is not None:\n", - " ax.text3D(*xyz, name)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig = plt.figure()\n", - "ax = fig.add_subplot(projection='3d')\n", - "\n", - "plot_3dvec(ax, a, r'$\\vec{a}$')\n", - "plot_3dvec(ax, b, r'$\\vec{b}$')\n", - "plot_3dvec(ax, a_cross_b, r'$\\vec{cross}$')\n", - "\n", - "ax.grid(True)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "* How does the cross product change if you reverse the order of the vectors?
외적의 순서를 바꾸면 결과에 어떤 영향이 있는가?\n", - "* Can you find two vectors whose cross product is the zero vector? What does this mean geometrically?
외적을 영벡터로 만드는 두 벡터를 찾을 수 있는가? 기하학적으로는 어떤 의미인가?\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 표준기능
Standard library\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "a_list = (1, -7, 1)\n", - "b_list = (5, 2, 4)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def cross_product_list(x_list, y_list):\n", - " assert 3 == len(x_list)\n", - " assert 3 == len(y_list)\n", - " return [\n", - " x_list[1]*y_list[2] - x_list[2]*y_list[1],\n", - " x_list[0]*y_list[2] - x_list[2]*y_list[0],\n", - " x_list[0]*y_list[1] - x_list[1]*y_list[0],\n", - " ]\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "a_cross_b_stdlib = cross_product_list(a_list, b_list)\n", - "print(f\"cross_product_list(a_list, b_list) = {a_cross_b_stdlib}\")\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig = plt.figure()\n", - "ax = fig.add_subplot(projection='3d')\n", - "\n", - "plot_3dvec(ax, a_list, r'$\\vec{a}$')\n", - "plot_3dvec(ax, b_list, r'$\\vec{b}$')\n", - "plot_3dvec(ax, a_cross_b_stdlib, r'$\\vec{cross}$')\n", - "\n", - "ax.grid(True)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 연습 문제
Exercise\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Try This 1: Given a force vector $\\vec{f}=(10, 10)$, find its components along the directions of the vectors $\\vec{x'}, \\vec{y'}$ directions.
힘 벡터 (10, 10) 의 $\\vec{x'}$ and $\\vec{y'}$ 방향 성분을 각각 구하시오.\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "$$\n", - "\\begin{align}\n", - " \\vec{x'}&=\\left(0.8, 0.6\\right) \\\\\n", - " \\vec{y'}&=\\left(-0.6, 0.8\\right)\n", - "\\end{align}\n", - "$$\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Try This 2: Find the magnitude and direction of the moment produced by a force vector \n", - "$\\vec{f}=(-1, 1, -1)$ acting at the point $\\vec{r}= (1, 1, 1)$ on the origin.
힘의 작용점 $\\vec{r}= (1, 1, 1)$인 힘 벡터 $\\vec{f}=(-1, 1, -1)$가 원점에 작용하는 모멘트의 크기와 방향을 구하시오\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Final Bell
마지막 종\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# stackoverfow.com/a/24634221\n", - "import os\n", - "os.system(\"printf '\\a'\");\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "colab": { - "include_colab_link": true, - "provenance": [] - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.0" - } - }, - "nbformat": 4, - "nbformat_minor": 4 + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Aj2lSYkS500L" + }, + "outputs": [], + "source": [ + "# 그래프, 수학 기능 추가\n", + "# Add graph and math features\n", + "import pylab as py\n", + "import numpy as np\n", + "import numpy.linalg as nl\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iF6em7B9500P" + }, + "source": [ + "# 벡터의 내적과 외적
Inner and Cross Products of Vectors\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gmd27txO500R" + }, + "source": [ + "## 벡터의 내적
Inner Product of Vectors\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VhkkOlyO500R" + }, + "source": [ + "### `numpy`\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F4AF7Xxl500S" + }, + "source": [ + "벡터의 내적에 관해 아래 비디오 링크를 참고할 수 있다. (9:09) (내적 주요 설명 1:54 ~ 4:40)
\n", + "Regarding the vector inner product, you can check the following link. (9:09) (Inner product explanation 1:54 ~ 4:40)
\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vMMKHNWe500S" + }, + "source": [ + "[![Vector dot product and vector length 벡터 내적과 벡터의 길이](https://i.ytimg.com/vi/WNuIhXo39_k/hqdefault.jpg)](https://www.youtube.com/watch?v=WNuIhXo39_k)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gTvSAAfF500T" + }, + "source": [ + "예를 들어 2차원 벡터를 생각해 보자.
\n", + "For example, let's think about two-dimensional vectors (2D vectors).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VwzvVaZx500T" + }, + "source": [ + "* Feel free to modify the vector definitions below and re-run the cells to explore how different vectors behave under inner and cross product operations.
\n", + "아래 정의한 벡터는 가능한 예 가운데 하나이므로, 자신의 벡터를 입력하고 해당 노트북을 재실행하여 어떻게 달라지는지 관찰해 보기 바람\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "p3QTTZFe500U" + }, + "outputs": [], + "source": [ + "# ref : https://www.youtube.com/watch?v=8QihetGj3pg\n", + "b = np.array((2, 5))\n", + "c = np.array((7, 1))\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "LWtftjpq500U" + }, + "outputs": [], + "source": [ + "b\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "O63Ziuph500U" + }, + "outputs": [], + "source": [ + "c\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yLhNGDdh500V" + }, + "source": [ + "위 2차원 벡터를 한번 그려 보자
\n", + "Let's plot the 2D vectors above.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "NBDsiTnl500V" + }, + "outputs": [], + "source": [ + "def draw_2dvec(x, y, x0=0, y0=0, color='k', name=None):\n", + " py.quiver(x0, y0, x, y, color=color, angles='xy', scale_units='xy', scale=1)\n", + " py.plot((x0, x0+x), (y0, y0+y), alpha=0)\n", + " if name is not None:\n", + " if not name.startswith('$'):\n", + " vec_str = '$\\\\vec{%s}$' % name\n", + " else:\n", + " vec_str = name\n", + " py.text(0.5 * x + x0, 0.5 * y + y0, vec_str)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true, + "id": "1cINeIrW500V" + }, + "outputs": [], + "source": [ + "draw_2dvec(b[0], b[1], name='b')\n", + "draw_2dvec(c[0], c[1], name='c')\n", + "\n", + "py.axis('equal')\n", + "py.grid(True)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9tVwWnAy500V" + }, + "source": [ + "이 두 벡터의 내적을 계산해 보자
Let's calculate the inner product of these two vectors.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true, + "id": "i42hzJ2t500W" + }, + "outputs": [], + "source": [ + "py.dot(b, c)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "d66QgCaa500W" + }, + "source": [ + "확인해 보자.
Let's verify.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "UMCB8LXu500W" + }, + "outputs": [], + "source": [ + "b[0]*c[0] + b[1]*c[1]\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_nLgBB89500W" + }, + "source": [ + "다른 방법도 있다.
Other methods are available.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "4khKjpcn500W" + }, + "outputs": [], + "source": [ + "# https://docs.scipy.org/doc/numpy/reference/generated/numpy.inner.html\n", + "py.inner(b, c)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "gO_2eFpP500W" + }, + "outputs": [], + "source": [ + "# https://docs.scipy.org/doc/numpy/reference/generated/numpy.inner.html\n", + "sum(b[:] * c[:])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eBhAZH5F500W" + }, + "source": [ + "**Python 3.5, Numpy 1.10 이상**에서는 **`@` 연산자**를 내적의 의미로 사용할 수 있다.
\n", + "For **Python 3.5 or higher and Numpy 1.10 or higher**, we can use **`@` operator** as inner product.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "2Gl2eKJX500W" + }, + "outputs": [], + "source": [ + "b @ c\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "rCssHIta500X" + }, + "outputs": [], + "source": [ + "theta_a_deg = 30\n", + "theta_a_rad = np.deg2rad(theta_a_deg)\n", + "theta_b_deg = 120\n", + "theta_b_rad = np.deg2rad(theta_b_deg)\n", + "\n", + "a_row_array = np.array([np.cos(theta_a_rad), np.sin(theta_a_rad)])\n", + "b_row_array = np.array([np.cos(theta_b_rad), np.sin(theta_b_rad)])\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "VkLyv6tC500X" + }, + "outputs": [], + "source": [ + "draw_2dvec(a_row_array[0], a_row_array[1], name='a_{array}')\n", + "draw_2dvec(b_row_array[0], b_row_array[1], name='b_{array}')\n", + "\n", + "py.axis('equal')\n", + "py.grid(True)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "VfI3mxAm500X" + }, + "outputs": [], + "source": [ + "print('a dot b (array) =', np.dot(a_row_array, b_row_array))\n", + "print('a_row_array @ b_row_array =', a_row_array @ b_row_array)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dOdn8BZa500X" + }, + "source": [ + "* What happens to the inner product if you change the angle between the vectors?
벡터 사잇각이 달라지면 내적에는 어떤 영향을 미치는가?\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8JxJYmNy500X" + }, + "source": [ + "### 표준 기능
Standard library\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Rmlj6P1o500X" + }, + "outputs": [], + "source": [ + "b_list = [2, 5]\n", + "c_list = [7, 1]\n", + "print(f\"b_list = {b_list}\")\n", + "print(f\"c_list = {c_list}\")\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Y2eQBR2U500X" + }, + "outputs": [], + "source": [ + "def dot_product_list_comprehension(x_list, y_list):\n", + " assert len(x_list) == len(y_list)\n", + " return sum(xi*yi for xi, yi in zip(x_list, y_list))\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "YDt4f84E500X" + }, + "outputs": [], + "source": [ + "def dot_product_map(x_list, y_list):\n", + " assert len(x_list) == len(y_list)\n", + " return sum(map(lambda x_y:x_y[0] * x_y[1],zip(x_list, y_list)))\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "_wJXNMGD500X" + }, + "outputs": [], + "source": [ + "def dot_product_list_for(x_list, y_list):\n", + " assert len(x_list) == len(y_list)\n", + " s = 0\n", + " for xi, yi in zip(x_list, y_list):\n", + " s += (xi * yi)\n", + " return s\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "0EGXAiSj500Y" + }, + "outputs": [], + "source": [ + "def dot_product_list_for_index(x_list, y_list):\n", + " assert len(x_list) == len(y_list)\n", + " s = 0\n", + " n = len(x_list)\n", + " for i in range(n):\n", + " s += (x_list[i] * y_list[i])\n", + " return s\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "F4vE22oz500Y" + }, + "outputs": [], + "source": [ + "print(f\"dot_product_list_comprehension(b_list, c_list) = {dot_product_list_comprehension(b_list, c_list)}\")\n", + "print(f\"dot_product_map(b_list, c_list) = {dot_product_map(b_list, c_list)}\")\n", + "print(f\"dot_product_list_for(b_list, c_list) = {dot_product_list_for(b_list, c_list)}\")\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "uXpnr9x4500Y" + }, + "outputs": [], + "source": [ + "assert (\n", + " dot_product_list_comprehension(b_list, c_list)\n", + " == dot_product_map(b_list, c_list)\n", + " == dot_product_list_for(b_list, c_list)\n", + ")\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rdelZ6MH500Y" + }, + "source": [ + "## 벡터의 외적
Cross Product of Vectors\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-HPI5L8P500Y" + }, + "source": [ + "아래 비디오 링크를 참고할 수 있다. (15:46)
\n", + "Regarding the vector inner product, you can check the following link. (15:46)
\n", + "
\n", + "[![칸 아카데미 | 벡터와 벡터 공간 | 외적 소개
Khan Academy | Linear Algebra | Vectors and spaces | Cross product introduction](https://i.ytimg.com/vi/pJzmiywagfY/hqdefault.jpg)](https://www.youtube.com/watch?v=pJzmiywagfY)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8iflc6pX500Y" + }, + "source": [ + "열벡터의 잇점은 무엇이라고 생각하는가?
\n", + "What do you think is the advantage of the column vector form?\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bqNG6DZK500Y" + }, + "source": [ + "### `numpy`\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kIFDvMPJ500c" + }, + "source": [ + "다음과 같은 두 벡터를 생각해 보자.
Let's think about following two vectors.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "WtpfsI7w500c" + }, + "outputs": [], + "source": [ + "a = py.array((1, -7, 1))\n", + "b = py.array((5, 2, 4))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "h2sr9nRp500c" + }, + "source": [ + "외적을 계산해 보자.
Let's calculate the cross product.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "3Tj5yMNi500c" + }, + "outputs": [], + "source": [ + "a_cross_b = py.cross(a, b)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "DaE8z01N500c" + }, + "outputs": [], + "source": [ + "a_cross_b\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RIicfHe0500c" + }, + "source": [ + "확인 해 보자.
Let's verify.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "BCJBM_k7500c" + }, + "outputs": [], + "source": [ + "py.dot(a, a_cross_b)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "_A6XgNLF500d" + }, + "outputs": [], + "source": [ + "py.dot(b, a_cross_b)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7euVhGhZ500d" + }, + "source": [ + "외적의 결과가 $\\vec{a}$, $\\vec{b}$ 와 수직임을 알 수 있다.
We can see that the cross product is orthogonal to $\\vec{a}$ and $\\vec{b}$.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "2F2QAtEP500d" + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "from mpl_toolkits.mplot3d import Axes3D\n", + "import numpy as np\n", + "\n", + "\n", + "def plot_3dvec(ax, xyz, name=None):\n", + " ax.quiver(\n", + " *[0, 0, 0], *xyz,\n", + " )\n", + "\n", + " ax.plot3D(\n", + " (0, xyz[0]),\n", + " (0, xyz[1]),\n", + " (0, xyz[2]),\n", + " alpha=0\n", + " )\n", + "\n", + " if name is not None:\n", + " ax.text3D(*xyz, name)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "yPP4Mm-f500d" + }, + "outputs": [], + "source": [ + "fig = plt.figure()\n", + "ax = fig.add_subplot(projection='3d')\n", + "\n", + "plot_3dvec(ax, a, r'$\\vec{a}$')\n", + "plot_3dvec(ax, b, r'$\\vec{b}$')\n", + "plot_3dvec(ax, a_cross_b, r'$\\vec{cross}$')\n", + "\n", + "ax.grid(True)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lrD0rUAs500d" + }, + "source": [ + "* How does the cross product change if you reverse the order of the vectors?
외적의 순서를 바꾸면 결과에 어떤 영향이 있는가?\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "IrSBJ7wIHtiH" + }, + "outputs": [], + "source": [ + "b_cross_a = py.cross(b, a)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "C9_ITNXHHtiQ" + }, + "outputs": [], + "source": [ + "b_cross_a\n", + "\n" + ] + }, + { + "cell_type": "code", + "source": [ + "fig = plt.figure()\n", + "ax = fig.add_subplot(projection='3d')\n", + "\n", + "plot_3dvec(ax, b, r'$\\vec{b}$')\n", + "plot_3dvec(ax, a, r'$\\vec{a}$')\n", + "plot_3dvec(ax, b_cross_a, r'$\\vec{cross}$')\n", + "\n", + "ax.grid(True)\n", + "\n" + ], + "metadata": { + "id": "17yrlGc5H77Y" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "* Can you find two vectors whose cross product is the zero vector? What does this mean geometrically?
외적을 영벡터로 만드는 두 벡터를 찾을 수 있는가? 기하학적으로는 어떤 의미인가?\n", + "\n" + ], + "metadata": { + "id": "I1C5LwHSHyoQ" + } + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8ujwIG7i500d" + }, + "source": [ + "### 표준기능
Standard library\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "wgUeJyAI500d" + }, + "outputs": [], + "source": [ + "a_list = (1, -7, 1)\n", + "b_list = (5, 2, 4)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "g6wCS8K_500d" + }, + "outputs": [], + "source": [ + "def cross_product_list(x_list, y_list):\n", + " assert 3 == len(x_list)\n", + " assert 3 == len(y_list)\n", + " return [\n", + " x_list[1]*y_list[2] - x_list[2]*y_list[1],\n", + " x_list[0]*y_list[2] - x_list[2]*y_list[0],\n", + " x_list[0]*y_list[1] - x_list[1]*y_list[0],\n", + " ]\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "8f8sEu9m500e" + }, + "outputs": [], + "source": [ + "a_cross_b_stdlib = cross_product_list(a_list, b_list)\n", + "print(f\"cross_product_list(a_list, b_list) = {a_cross_b_stdlib}\")\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "PJj3hPIT500e" + }, + "outputs": [], + "source": [ + "fig = plt.figure()\n", + "ax = fig.add_subplot(projection='3d')\n", + "\n", + "plot_3dvec(ax, a_list, r'$\\vec{a}$')\n", + "plot_3dvec(ax, b_list, r'$\\vec{b}$')\n", + "plot_3dvec(ax, a_cross_b_stdlib, r'$\\vec{cross}$')\n", + "\n", + "ax.grid(True)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eYNSqPbf500e" + }, + "source": [ + "## 연습 문제
Exercise\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6hqqWpze500e" + }, + "source": [ + "Try This 1: Given a force vector $\\vec{f}=(10, 10)$, find its components along the directions of the vectors $\\vec{x'}, \\vec{y'}$ directions.
힘 벡터 (10, 10) 의 $\\vec{x'}$ and $\\vec{y'}$ 방향 성분을 각각 구하시오.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GS1AxWDs500e" + }, + "source": [ + "$$\n", + "\\begin{align}\n", + " \\vec{x'}&=\\left(0.8, 0.6\\right) \\\\\n", + " \\vec{y'}&=\\left(-0.6, 0.8\\right)\n", + "\\end{align}\n", + "$$\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "caYsn2eA500e" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6YiosVCf500e" + }, + "source": [ + "Try This 2: Find the magnitude and direction of the moment produced by a force vector \n", + "$\\vec{f}=(-1, 1, -1)$ acting at the point $\\vec{r}= (1, 1, 1)$ on the origin.
힘의 작용점 $\\vec{r}= (1, 1, 1)$인 힘 벡터 $\\vec{f}=(-1, 1, -1)$가 원점에 작용하는 모멘트의 크기와 방향을 구하시오\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "DyA5LSiu500e" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "29XfZE4Z500f" + }, + "source": [ + "## Final Bell
마지막 종\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "VUqpsw-k500g" + }, + "outputs": [], + "source": [ + "# stackoverfow.com/a/24634221\n", + "import os\n", + "os.system(\"printf '\\a'\");\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "xtD6gRLx500g" + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "colab": { + "provenance": [], + "include_colab_link": true + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.0" + } + }, + "nbformat": 4, + "nbformat_minor": 0 } \ No newline at end of file