├── README.md └── code ├── .ipynb_checkpoints ├── ch02-1.파이썬 기초-checkpoint.ipynb ├── ch03-3-1.파이썬 행렬 연산-checkpoint.ipynb ├── ch04-2.파이썬 다양한 행렬-checkpoint.ipynb ├── ch04-3.넘파이 다양한 행렬-checkpoint.ipynb ├── ch05-4.파이썬 방정식-checkpoint.ipynb ├── ch06-4.파이썬 행렬식 연산-checkpoint.ipynb ├── ch07-3.파이썬 역행렬 연산-checkpoint.ipynb ├── ch07-4.넘파이 역행렬 연산-checkpoint.ipynb ├── ch09-6.파이썬 QR 그램 슈미트-checkpoint.ipynb ├── ch16-3.파이썬 텐서-checkpoint.ipynb ├── ch16-4.넘파이 텐서-checkpoint.ipynb ├── ch17-1-2.머신러닝과 선형대수(1)_산불 데이터(넘파이, 판다스)-checkpoint.ipynb ├── ch18-1-1.딥러닝과 선형대수(2)_이미지 데이터(파이썬)-checkpoint.ipynb └── my_linear_algebra-checkpoint.ipynb ├── Untitled.ipynb ├── __pycache__ └── my_linear_algebra.cpython-38.pyc ├── ch02-1.파이썬 기초.ipynb ├── ch03-1-1.스칼라 연산.ipynb ├── ch03-2-1.파이썬 벡터 연산 .ipynb ├── ch03-2-2.넘파이 벡터 연산.ipynb ├── ch03-3-1.파이썬 행렬 연산.ipynb ├── ch03-3-2.넘파이 행렬 연산.ipynb ├── ch04-2.파이썬 다양한 행렬.ipynb ├── ch04-3.넘파이 다양한 행렬.ipynb ├── ch05-4.파이썬 방정식.ipynb ├── ch05-5.넘파이 방정식.ipynb ├── ch06-4.파이썬 행렬식 연산.ipynb ├── ch06-5.넘파이 행렬식 연산.ipynb ├── ch07-3.파이썬 역행렬 연산.ipynb ├── ch07-4.넘파이 역행렬 연산.ipynb ├── ch09-3.파이썬 내적 연산.ipynb ├── ch09-4.넘파이 내적 연산.ipynb ├── ch09-6.파이썬 QR 그램 슈미트.ipynb ├── ch09-7.파이썬 QR 하우스홀더.ipynb ├── ch09-8.넘파이 내적 연산(QR).ipynb ├── ch10-2.파이썬 다양한 곱 연산.ipynb ├── ch10-3.넘파이 다양한 곱 연산.ipynb ├── ch11-1.파이썬 고윳값 연산.ipynb ├── ch11-2.파이썬 고윳값 연산-using QR.ipynb ├── ch11-3.넘파이 고윳값 연산.ipynb ├── ch12-3.파이썬 직교 행렬.ipynb ├── ch12-4.넘파이 직교 행렬.ipynb ├── ch13-2.파이썬 대각화.ipynb ├── ch13-3.넘파이 대각화.ipynb ├── ch14-3.파이썬 LU분해.ipynb ├── ch14-4.넘파이 LU분해.ipynb ├── ch16-3.파이썬 텐서.ipynb ├── ch16-4.넘파이 텐서.ipynb ├── ch17-1-1.머신러닝과 선형대수(1)_산불 데이터(파이썬).ipynb ├── ch17-1-2.머신러닝과 선형대수(1)_산불 데이터(넘파이, 판다스).ipynb ├── ch18-1-1.딥러닝과 선형대수(2)_이미지 데이터(파이썬).ipynb ├── ch18-1-2.딥러닝과 선형대수(2)_이미지 데이터(넘파이, 판다스).ipynb ├── data ├── forestfires │ └── forestfires.csv └── mnist │ └── mnist.csv ├── my_linear_algebra.ipynb └── my_linear_algebra.py /README.md: -------------------------------------------------------------------------------- 1 | # 알고리즘 구현으로 배우는 선형대수 with 파이썬 2 | ![(입체표지) 알고리즘 구현으로 배우는 선형대수 with 파이썬](https://user-images.githubusercontent.com/21074282/148310502-d3e9c6c9-9272-4eea-83c1-31d2fccc6e5b.png) 3 | 4 | - 부제: 행렬의 기초부터 텐서를 활용한 머신러닝과 딥러닝 적용까지 5 | - 저자: 장철원 6 | - 출간일: 2021년 12월 24일 7 | - 페이지수: 592쪽 8 | 9 |


10 | ## 오탈자 정오표 11 | https://cafe.naver.com/aifromstat 12 | 13 |


14 | ## 온라인 서점 구매 링크 15 | - [예스24](http://www.yes24.com/Product/Goods/105772247) 16 | - [교보문고](http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9791165921125&orderClick=LET&Kc=) 17 | - [알라딘](https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=285412337) 18 | - [인터파크](http://book.interpark.com/product/BookDisplay.do?_method=detail&sc.shopNo=0000400000&sc.prdNo=354391293&pis1=book&pis2=product) 19 | 20 |


21 | ## 책 소개 22 |

행렬의 기초부터 텐서를 활용한 머신러닝과 딥러닝 적용까지

23 |

선형대수, 직접 구현하여 내 것으로 만들자!

24 | 『선형대수와 통계학으로 배우는 머신러닝 with 파이썬』의 장철원 저자가 선형대수 기초를 다잡고 싶은 독자를 위해 집필한 선형대수 책이다. 기초적인 행렬부터 고차원 텐서까지 선형대수를 구성하는 개념 및 이론을 소개하고 독자 스스로 자신의 분야에 응용할 수 있도록 도와준다. 또한, 선형대수 이론이 의미하는 바를 자세히 설명하고 선형대수 이론을 파이썬 코드로 직접 구현함으로써 내 손으로 선형대수 라이브러리를 직접 만드는 즐거움을 선사한다. 25 | 26 | 실습은 두 파트로 나뉜다. 파이썬 실습 파트에서는 라이브러리를 사용하지 않고 순수 파이썬 코드로 선형대수 이론을 직접 구현해 봄으로써 선형대수 기본기를 탄탄하게 다진다. 넘파이 실습 파트에서는 파이썬에서 제공하는 넘파이 라이브러리를 활용해 선형대수 이론을 활용하는 방법을 다룬다. 27 | 28 |


29 | ## 이 책의 특징 30 | - 선형대수 내부 알고리즘을 집중 공략하고 실전에 적용해 본다. 31 | - 행렬, 텐서, 기저, 차원 등 선형대수 필수 이론을 자세히 다룬다. 32 | - 추상적인 선형대수 개념을 그림으로 알기 쉽게 설명한다. 33 | 34 |


35 | ## 이 책의 독자 36 | - 선형대수를 공부한 경험이 있지만, 실제 사용에 어려움을 느끼는 분 37 | - 선형대수 알고리즘을 직접 구현하고 싶은 분 38 | 39 |


40 | ## 저자 소개 41 |

장철원

42 | 43 | 공부한 내용을 기록하고 나누는 것을 좋아하는 프리랜서 44 | 45 | 충북대학교에서 통계학을 전공하고 고려대학교에서 통계학 석사를 졸업했다. 이후 플로리다 주립 대학교(Florida State University) 통계학 박사 과정 중 휴학 후 취업 전선에 뛰어들었다. 어렸을 때부터 게임을 좋아해 크래프톤(구 블루홀) 데이터 분석실에서 일했다. 주로 머신러닝을 이용한 이탈률 예측과 고객 분류 업무를 수행했다. 배틀그라운드 핵 관련 업무를 계기로 IT 보안에 흥미를 느껴, 이후 NHN IT보안실에서 일하며 머신러닝을 이용한 매크로 자동 탐지 시스템을 개발하고 특허를 출원했다. 현재는 머신러닝 관련 책을 쓰고 강의를 하는 프리랜서다. 공부한 내용을 공유하는 데 보람을 느껴 블로그와 카페를 운영하고 있다. 관심 분야는 인공지능, 머신러닝, 통계학, 선형대수, 커널, 임베디드, IT보안, 사물인터넷, 물리학, 철학이다. 46 | 47 | - 프리랜서 48 | - 한국정보통신기술협회 외부교수 49 | - 패스트캠퍼스 강사 50 | - 前) NHN IT 보안실 51 | - 前) 크래프톤(구 블루홀) 데이터 분석실 52 | 53 | 저자 운영 카페 https://cafe.naver.com/aifromstat 54 | 55 |


56 | ## 출판사 리뷰 57 |

추상적이고 어렵게만 느껴지는 선형대수,

58 |

더는 피하지 말고 이 책과 함께 정면 돌파하라!

59 | 60 | 선형대수는 머신러닝과 딥러닝 분야뿐만 아니라 숫자를 다루는 거의 모든 분야에서 사용됨에도 불구하고, 그 중요성에 비해 쉽게 접하기 어려운 학문이다. 하지만 이 책과 함께라면 선형대수 이론을 파이썬으로 밑바닥부터 직접 구현해 보며 선형대수의 개념을 확실하게 잡을 수 있다. 이 책은 선형대수 이론을 수식으로 설명하고 파이썬을 이용해 단계별로 구현한 후 Numpy 코드로 검증하는 과정을 거친다. 이를 통해 선형대수의 수학적 개념을 자연스럽게 이해하고 문제 해결을 위한 라이브러리 활용 방법을 학습하도록 돕는다. 이 책을 통해 선형대수를 심도 있게 이해하길 바란다. 61 | 62 |


63 | ## 관련도서 64 | - [선형대수와 통계학으로 배우는 머신러닝 with 파이썬](http://www.yes24.com/Product/Goods/97032765) 65 | 66 |


67 | ## 오탈자 정오표 68 | https://cafe.naver.com/aifromstat 69 | 70 |


71 | ![상세이미지_알고리즘구현으로배우는선형대수with파이썬](https://user-images.githubusercontent.com/21074282/148310702-08861746-1f3b-40a3-97df-45b95da888a2.jpg) 72 | -------------------------------------------------------------------------------- /code/.ipynb_checkpoints/ch03-3-1.파이썬 행렬 연산-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 6, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "# 행렬의 덧셈\n", 10 | "A = [[2,7], [3,4], [6,1]]\n", 11 | "B = [[1,4], [4,-1], [2,5]]\n", 12 | "\n", 13 | "n = len(A)\n", 14 | "p = len(A[0])\n", 15 | "\n", 16 | "res = []\n", 17 | "for i in range(0, n):\n", 18 | " row = []\n", 19 | " for j in range(0, p):\n", 20 | " val = A[i][j] + B[i][j]\n", 21 | " row.append(val)\n", 22 | " res.append(row)" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 7, 28 | "metadata": {}, 29 | "outputs": [ 30 | { 31 | "name": "stdout", 32 | "output_type": "stream", 33 | "text": [ 34 | "[[3, 11], [7, 3], [8, 6]]\n" 35 | ] 36 | } 37 | ], 38 | "source": [ 39 | "print(res)" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 11, 45 | "metadata": {}, 46 | "outputs": [], 47 | "source": [ 48 | "def add(A, B):\n", 49 | " \"\"\"\n", 50 | " 행렬의 덧셈\n", 51 | " 입력값: 행렬의 덧셈을 수행할 행렬 A, B\n", 52 | " 출력값: 행렬 A와 행렬 B의 덧셈 결과인 행렬 res\n", 53 | " \"\"\"\n", 54 | "\n", 55 | " n = len(A)\n", 56 | " p = len(A[0])\n", 57 | "\n", 58 | " res = []\n", 59 | " for i in range(0, n):\n", 60 | " row = []\n", 61 | " for j in range(0, p):\n", 62 | " val = A[i][j] + B[i][j]\n", 63 | " row.append(val)\n", 64 | " res.append(row)\n", 65 | " return res" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 12, 71 | "metadata": {}, 72 | "outputs": [], 73 | "source": [ 74 | "A = [[2,7], [3,4], [6,1]]\n", 75 | "B = [[1,4], [4,-1], [2,5]]" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 13, 81 | "metadata": {}, 82 | "outputs": [ 83 | { 84 | "data": { 85 | "text/plain": [ 86 | "[[3, 11], [7, 3], [8, 6]]" 87 | ] 88 | }, 89 | "execution_count": 13, 90 | "metadata": {}, 91 | "output_type": "execute_result" 92 | } 93 | ], 94 | "source": [ 95 | "add(A,B)" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 14, 101 | "metadata": {}, 102 | "outputs": [], 103 | "source": [ 104 | "# 행렬의 뺄셈\n", 105 | "A = [[2,7], [3,4], [6,1]]\n", 106 | "B = [[1,4], [4,-1], [2,5]]\n", 107 | "\n", 108 | "n = len(A)\n", 109 | "p = len(A[0])\n", 110 | "\n", 111 | "res = []\n", 112 | "for i in range(0, n):\n", 113 | " row = []\n", 114 | " for j in range(0, p):\n", 115 | " val = A[i][j] - B[i][j]\n", 116 | " row.append(val)\n", 117 | " res.append(row)" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 15, 123 | "metadata": {}, 124 | "outputs": [ 125 | { 126 | "name": "stdout", 127 | "output_type": "stream", 128 | "text": [ 129 | "[[1, 3], [-1, 5], [4, -4]]\n" 130 | ] 131 | } 132 | ], 133 | "source": [ 134 | "print(res)" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": 19, 140 | "metadata": {}, 141 | "outputs": [], 142 | "source": [ 143 | "def subtract(A, B):\n", 144 | " \"\"\"\n", 145 | " 행렬의 뺄셈\n", 146 | " 입력값: 행렬의 뺄셈을 수행할 행렬 A, B\n", 147 | " 출력값: 행렬 A와 행렬 B의 뺄셈 결과인 행렬 res\n", 148 | " \"\"\"\n", 149 | " n = len(A)\n", 150 | " p = len(A[0])\n", 151 | "\n", 152 | " res = []\n", 153 | " for i in range(0, n):\n", 154 | " row = []\n", 155 | " for j in range(0, p):\n", 156 | " val = A[i][j] - B[i][j]\n", 157 | " row.append(val)\n", 158 | " res.append(row)\n", 159 | " return res" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 20, 165 | "metadata": {}, 166 | "outputs": [ 167 | { 168 | "data": { 169 | "text/plain": [ 170 | "[[1, 3], [-1, 5], [4, -4]]" 171 | ] 172 | }, 173 | "execution_count": 20, 174 | "metadata": {}, 175 | "output_type": "execute_result" 176 | } 177 | ], 178 | "source": [ 179 | "A = [[2,7], [3,4], [6,1]]\n", 180 | "B = [[1,4], [4,-1], [2,5]]\n", 181 | "subtract(A, B)" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 21, 187 | "metadata": {}, 188 | "outputs": [], 189 | "source": [ 190 | "# 행렬의 스칼라곱\n", 191 | "A = [[2,7], [3,4], [6,1]]\n", 192 | "b = 2\n", 193 | "\n", 194 | "n = len(A)\n", 195 | "p = len(A[0])\n", 196 | "\n", 197 | "res = []\n", 198 | "for i in range(0, n):\n", 199 | " row = []\n", 200 | " for j in range(0, p):\n", 201 | " val = b * A[i][j]\n", 202 | " row.append(val)\n", 203 | " res.append(row)" 204 | ] 205 | }, 206 | { 207 | "cell_type": "code", 208 | "execution_count": 23, 209 | "metadata": {}, 210 | "outputs": [ 211 | { 212 | "name": "stdout", 213 | "output_type": "stream", 214 | "text": [ 215 | "[[4, 14], [6, 8], [12, 2]]\n" 216 | ] 217 | } 218 | ], 219 | "source": [ 220 | "print(res)" 221 | ] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "execution_count": 1, 226 | "metadata": {}, 227 | "outputs": [], 228 | "source": [ 229 | "def scalar_mul(b, A):\n", 230 | " \"\"\"\n", 231 | " 행렬의 스칼라곱\n", 232 | " 입력값: 스칼라곱을 수행할 스칼라 b, 행렬 A\n", 233 | " 출력값: 스칼라 b와 행렬 A의 스칼라 곱 결과인 행렬 res\n", 234 | " \"\"\"\n", 235 | "\n", 236 | " n = len(A)\n", 237 | " p = len(A[0])\n", 238 | " \n", 239 | " res = []\n", 240 | " for i in range(0, n):\n", 241 | " row = []\n", 242 | " for j in range(0, p):\n", 243 | " val = b * A[i][j]\n", 244 | " row.append(val)\n", 245 | " res.append(row)\n", 246 | " return res" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": 2, 252 | "metadata": {}, 253 | "outputs": [ 254 | { 255 | "data": { 256 | "text/plain": [ 257 | "[[4, 14], [6, 8], [12, 2]]" 258 | ] 259 | }, 260 | "execution_count": 2, 261 | "metadata": {}, 262 | "output_type": "execute_result" 263 | } 264 | ], 265 | "source": [ 266 | "A = [[2,7], [3,4], [6,1]]\n", 267 | "b = 2\n", 268 | "scalar_mul(b, A)" 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": 26, 274 | "metadata": {}, 275 | "outputs": [], 276 | "source": [ 277 | "# 행렬의 원소곱\n", 278 | "A = [[1,5], [6,4], [2,7]]\n", 279 | "B = [[5,-1], [1,2], [4,1]]\n", 280 | "\n", 281 | "n = len(A)\n", 282 | "p = len(A[0])\n", 283 | "\n", 284 | "res = []\n", 285 | "for i in range(0, n):\n", 286 | " row = []\n", 287 | " for j in range(0, p):\n", 288 | " val = A[i][j] * B[i][j]\n", 289 | " row.append(val)\n", 290 | " res.append(row)" 291 | ] 292 | }, 293 | { 294 | "cell_type": "code", 295 | "execution_count": 27, 296 | "metadata": {}, 297 | "outputs": [ 298 | { 299 | "name": "stdout", 300 | "output_type": "stream", 301 | "text": [ 302 | "[[5, -5], [6, 8], [8, 7]]\n" 303 | ] 304 | } 305 | ], 306 | "source": [ 307 | "print(res)" 308 | ] 309 | }, 310 | { 311 | "cell_type": "code", 312 | "execution_count": 30, 313 | "metadata": {}, 314 | "outputs": [], 315 | "source": [ 316 | "def ele_product(A,B):\n", 317 | " \"\"\"\n", 318 | " 행렬의 원소곱\n", 319 | " 입력값: 행렬의 원소곱을 수행할 행렬 A, B\n", 320 | " 출력값: 행렬 A와 행렬 B의 원소곱 결과인 행렬 res\n", 321 | " \"\"\"\n", 322 | " n = len(A)\n", 323 | " p = len(A[0])\n", 324 | "\n", 325 | " res = []\n", 326 | " for i in range(0, n):\n", 327 | " row = []\n", 328 | " for j in range(0, p):\n", 329 | " val = A[i][j] * B[i][j]\n", 330 | " row.append(val)\n", 331 | " res.append(row)\n", 332 | " return res" 333 | ] 334 | }, 335 | { 336 | "cell_type": "code", 337 | "execution_count": 31, 338 | "metadata": {}, 339 | "outputs": [ 340 | { 341 | "data": { 342 | "text/plain": [ 343 | "[[5, -5], [6, 8], [8, 7]]" 344 | ] 345 | }, 346 | "execution_count": 31, 347 | "metadata": {}, 348 | "output_type": "execute_result" 349 | } 350 | ], 351 | "source": [ 352 | "A = [[1,5], [6,4], [2,7]]\n", 353 | "B = [[5,-1], [1,2], [4,1]]\n", 354 | "ele_product(A,B)" 355 | ] 356 | }, 357 | { 358 | "cell_type": "code", 359 | "execution_count": 36, 360 | "metadata": {}, 361 | "outputs": [], 362 | "source": [ 363 | "# 행렬곱\n", 364 | "A = [[2,7], [3,4], [5,2]]\n", 365 | "B = [[3,-3,5], [-1,2,-1]]\n", 366 | "\n", 367 | "n = len(A)\n", 368 | "p1 = len(A[0])\n", 369 | "p2 = len(B[0])\n", 370 | "\n", 371 | "res = []\n", 372 | "for i in range(0, n):\n", 373 | " row = []\n", 374 | " for j in range(0, p2):\n", 375 | " val = 0\n", 376 | " for k in range(0, p1):\n", 377 | " val += A[i][k] * B[k][j] \n", 378 | " row.append(val) \n", 379 | " res.append(row)" 380 | ] 381 | }, 382 | { 383 | "cell_type": "code", 384 | "execution_count": 37, 385 | "metadata": {}, 386 | "outputs": [ 387 | { 388 | "name": "stdout", 389 | "output_type": "stream", 390 | "text": [ 391 | "[[-1, 8, 3], [5, -1, 11], [13, -11, 23]]\n" 392 | ] 393 | } 394 | ], 395 | "source": [ 396 | "print(res)" 397 | ] 398 | }, 399 | { 400 | "cell_type": "code", 401 | "execution_count": 40, 402 | "metadata": {}, 403 | "outputs": [], 404 | "source": [ 405 | "def matmul(A, B): \n", 406 | " \"\"\"\n", 407 | " 행렬의 행렬곱\n", 408 | " 입력값: 행렬곱을 수행할 행렬 A, B\n", 409 | " 출력값: 행렬 A와 행렬 B의 행렬곱 결과인 행렬 res\n", 410 | " \"\"\"\n", 411 | " n = len(A)\n", 412 | " p1 = len(A[0])\n", 413 | " p2 = len(B[0])\n", 414 | "\n", 415 | " res = []\n", 416 | " for i in range(0, n):\n", 417 | " row = []\n", 418 | " for j in range(0, p2):\n", 419 | " val = 0\n", 420 | " for k in range(0, p1):\n", 421 | " val += A[i][k] * B[k][j] \n", 422 | " row.append(val) \n", 423 | " res.append(row)\n", 424 | " return res" 425 | ] 426 | }, 427 | { 428 | "cell_type": "code", 429 | "execution_count": 41, 430 | "metadata": {}, 431 | "outputs": [ 432 | { 433 | "data": { 434 | "text/plain": [ 435 | "[[-1, 8, 3], [5, -1, 11], [13, -11, 23]]" 436 | ] 437 | }, 438 | "execution_count": 41, 439 | "metadata": {}, 440 | "output_type": "execute_result" 441 | } 442 | ], 443 | "source": [ 444 | "A = [[2,7], [3,4], [5,2]]\n", 445 | "B = [[3,-3,5], [-1,2,-1]]\n", 446 | "matmul(A, B)" 447 | ] 448 | }, 449 | { 450 | "cell_type": "code", 451 | "execution_count": null, 452 | "metadata": {}, 453 | "outputs": [], 454 | "source": [] 455 | } 456 | ], 457 | "metadata": { 458 | "kernelspec": { 459 | "display_name": "Python 3", 460 | "language": "python", 461 | "name": "python3" 462 | }, 463 | "language_info": { 464 | "codemirror_mode": { 465 | "name": "ipython", 466 | "version": 3 467 | }, 468 | "file_extension": ".py", 469 | "mimetype": "text/x-python", 470 | "name": "python", 471 | "nbconvert_exporter": "python", 472 | "pygments_lexer": "ipython3", 473 | "version": "3.8.5" 474 | } 475 | }, 476 | "nbformat": 4, 477 | "nbformat_minor": 4 478 | } 479 | -------------------------------------------------------------------------------- /code/.ipynb_checkpoints/ch06-4.파이썬 행렬식 연산-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 개별 코드" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "A = [[3,2,0], [-1,-3,6], [2,3,-5]]" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 2, 22 | "metadata": {}, 23 | "outputs": [ 24 | { 25 | "name": "stdout", 26 | "output_type": "stream", 27 | "text": [ 28 | "[[-3, 6], [3, -5]]\n", 29 | "-3\n", 30 | "-9\n", 31 | "[[-1, 6], [2, -5]]\n", 32 | "-7\n", 33 | "5\n", 34 | "[[-1, -3], [2, 3]]\n", 35 | "3\n", 36 | "5\n" 37 | ] 38 | } 39 | ], 40 | "source": [ 41 | "n = len(A)\n", 42 | "p = len(A[0])\n", 43 | "\n", 44 | "detA = 0\n", 45 | "for j in range(0, p): \n", 46 | " M = [A[1][:j]+A[1][j+1:], A[2][:j]+A[2][j+1:]] \n", 47 | " print(M)\n", 48 | " Mij = M[0][0]*M[1][1] - M[0][1]*M[1][0] \n", 49 | " print(Mij)\n", 50 | " Cij = ((-1)**(0+j))*Mij\n", 51 | " detA += A[0][j]*Cij\n", 52 | " print(detA)" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 3, 58 | "metadata": {}, 59 | "outputs": [ 60 | { 61 | "data": { 62 | "text/plain": [ 63 | "[[-3, 6], [3, -5]]" 64 | ] 65 | }, 66 | "execution_count": 3, 67 | "metadata": {}, 68 | "output_type": "execute_result" 69 | } 70 | ], 71 | "source": [ 72 | "[A[1][:0]+A[1][1:], A[2][:0]+A[2][1:]] " 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": 4, 78 | "metadata": {}, 79 | "outputs": [ 80 | { 81 | "data": { 82 | "text/plain": [ 83 | "[[-1, 6], [2, -5]]" 84 | ] 85 | }, 86 | "execution_count": 4, 87 | "metadata": {}, 88 | "output_type": "execute_result" 89 | } 90 | ], 91 | "source": [ 92 | "[A[1][:1]+A[1][2:], A[2][:1]+A[2][2:]] " 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": 5, 98 | "metadata": {}, 99 | "outputs": [ 100 | { 101 | "data": { 102 | "text/plain": [ 103 | "[[-1, -3], [2, 3]]" 104 | ] 105 | }, 106 | "execution_count": 5, 107 | "metadata": {}, 108 | "output_type": "execute_result" 109 | } 110 | ], 111 | "source": [ 112 | "[A[1][:2]+A[1][3:], A[2][:2]+A[2][3:]] " 113 | ] 114 | }, 115 | { 116 | "cell_type": "markdown", 117 | "metadata": {}, 118 | "source": [ 119 | "# 전체 코드" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 6, 125 | "metadata": {}, 126 | "outputs": [ 127 | { 128 | "name": "stdout", 129 | "output_type": "stream", 130 | "text": [ 131 | "5\n" 132 | ] 133 | } 134 | ], 135 | "source": [ 136 | "A = [[3,2,0], [-1,-3,6], [2,3,-5]]\n", 137 | "\n", 138 | "n = len(A)\n", 139 | "p = len(A[0])\n", 140 | "\n", 141 | "\n", 142 | "detA = 0\n", 143 | "for j in range(0, p): \n", 144 | " M = [A[1][:j]+A[1][j+1:], A[2][:j]+A[2][j+1:]] \n", 145 | " Mij = M[0][0]*M[1][1] - M[0][1]*M[1][0] \n", 146 | " Cij = ((-1)**(0+j))*Mij\n", 147 | " detA += A[0][j]*Cij\n", 148 | "\n", 149 | "print(detA)" 150 | ] 151 | }, 152 | { 153 | "cell_type": "markdown", 154 | "metadata": {}, 155 | "source": [ 156 | "# 행렬식(재귀)" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": 7, 162 | "metadata": {}, 163 | "outputs": [], 164 | "source": [ 165 | "def det_rec(A):\n", 166 | " \n", 167 | " \"\"\"\n", 168 | " 행렬 A의 행렬식 구하기(재귀 방식을 이용)\n", 169 | " 입력값: 행렬식을 구하고자 하는 행렬 A\n", 170 | " 출력값: 행렬 A의 행렬식 res\n", 171 | " \"\"\"\n", 172 | " \n", 173 | " import copy\n", 174 | " \n", 175 | " n = len(A)\n", 176 | " p = len(A[0])\n", 177 | " res = 0\n", 178 | "\n", 179 | " # 2x2 행렬의 행렬식 구하기\n", 180 | " if n == 2 and p == 2:\n", 181 | " tmp_det = A[0][0] * A[1][1] - A[1][0] * A[0][1]\n", 182 | " return tmp_det\n", 183 | "\n", 184 | " # nxn 행렬의 행렬식 구하기\n", 185 | " for i in range(0,n): \n", 186 | " A1 = copy.deepcopy(A) \n", 187 | " A1 = A1[1:] \n", 188 | " n1 = len(A1)\n", 189 | "\n", 190 | " for j in range(0,n1): \n", 191 | " A1[j] = A1[j][0:i] + A1[j][i+1:] \n", 192 | "\n", 193 | " sign = (-1) ** (i % 2) \n", 194 | " sub_det = det_rec(A1) \n", 195 | " res += sign * A[0][i] * sub_det \n", 196 | "\n", 197 | " return res" 198 | ] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "metadata": {}, 203 | "source": [ 204 | "# copy 라이브러리 안쓴 버전" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": 7, 210 | "metadata": {}, 211 | "outputs": [], 212 | "source": [ 213 | "def zero_mat(n, p):\n", 214 | " \"\"\"\n", 215 | " 영 행렬 생성\n", 216 | " 입력값: 생성하고자 할 영 행렬의 크기 n행, p열\n", 217 | " 출력값: nxp 영 행렬 Z\n", 218 | " \"\"\"\n", 219 | " Z = []\n", 220 | " for i in range(0, n):\n", 221 | " row = []\n", 222 | " for j in range(0, p):\n", 223 | " row.append(0)\n", 224 | " Z.append(row)\n", 225 | " return Z\n", 226 | "\n", 227 | "\n", 228 | "\n", 229 | "def deepcopy(A):\n", 230 | " \"\"\"\n", 231 | " 깊은 복사(deepcopy) 구현\n", 232 | " 입력값: 깊은 복사를 하고자 하는 행렬 리스트 A\n", 233 | " 출력값: 깊은 복사 된 결과 행렬 리스트 res \n", 234 | " \"\"\"\n", 235 | " if type(A[0]) == list:\n", 236 | " n = len(A)\n", 237 | " p = len(A[0])\n", 238 | " res = zero_mat(n,p)\n", 239 | " for i in range(0,n):\n", 240 | " for j in range(0,p):\n", 241 | " res[i][j] = A[i][j]\n", 242 | " return res\n", 243 | " else:\n", 244 | " n = len(A)\n", 245 | " res = []\n", 246 | " for i in range(0,n):\n", 247 | " res.append(A[i])\n", 248 | " return res\n", 249 | " \n", 250 | "\n", 251 | "def det_rec(A):\n", 252 | " \n", 253 | " \"\"\"\n", 254 | " 행렬 A의 행렬식 구하기(재귀 방식을 이용)\n", 255 | " 입력값: 행렬식을 구하고자 하는 행렬 A\n", 256 | " 출력값: 행렬 A의 행렬식 res\n", 257 | " \"\"\"\n", 258 | " \n", 259 | " n = len(A)\n", 260 | " res = 0\n", 261 | "\n", 262 | " # 2x2 행렬의 행렬식 구하기\n", 263 | " if n == 2:\n", 264 | " res = A[0][0] * A[1][1] - A[1][0] * A[0][1]\n", 265 | " return res\n", 266 | "\n", 267 | " # nxn 행렬의 행렬식 구하기\n", 268 | " for i in range(0,n): \n", 269 | " X = deepcopy(A) \n", 270 | " X = X[1:] \n", 271 | " nx = len(X)\n", 272 | "\n", 273 | " for j in range(0,nx): \n", 274 | " X[j] = X[j][0:i] + X[j][i+1:] \n", 275 | "\n", 276 | " sign = (-1) ** (i % 2) \n", 277 | " sub_det = det_rec(X) \n", 278 | " res += sign * A[0][i] * sub_det \n", 279 | "\n", 280 | " return res" 281 | ] 282 | }, 283 | { 284 | "cell_type": "code", 285 | "execution_count": 9, 286 | "metadata": {}, 287 | "outputs": [ 288 | { 289 | "data": { 290 | "text/plain": [ 291 | "-4" 292 | ] 293 | }, 294 | "execution_count": 9, 295 | "metadata": {}, 296 | "output_type": "execute_result" 297 | } 298 | ], 299 | "source": [ 300 | "A = [[1,3,1,4], [3,9,5,15], [0,2,1,1],[0,4,2,3]]\n", 301 | "det_rec(A)" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": 10, 307 | "metadata": {}, 308 | "outputs": [ 309 | { 310 | "data": { 311 | "text/plain": [ 312 | "9" 313 | ] 314 | }, 315 | "execution_count": 10, 316 | "metadata": {}, 317 | "output_type": "execute_result" 318 | } 319 | ], 320 | "source": [ 321 | "B = [[6,3],[5,4]]\n", 322 | "det_rec(B)" 323 | ] 324 | }, 325 | { 326 | "cell_type": "markdown", 327 | "metadata": {}, 328 | "source": [ 329 | "# 상 삼각 행렬 변환을 통해 행렬식 구하기" 330 | ] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": 11, 335 | "metadata": {}, 336 | "outputs": [], 337 | "source": [ 338 | "def det_tri(A):\n", 339 | " \n", 340 | " import copy\n", 341 | " \n", 342 | " n = len(A)\n", 343 | " A1 = copy.deepcopy(A)\n", 344 | " \n", 345 | " for i in range(0,n): \n", 346 | " for j in range(i+1,n): \n", 347 | " if A1[i][i] == 0: \n", 348 | " A1[i][i] == 1.0e-18 \n", 349 | " ratio = A1[j][i] / A1[i][i] \n", 350 | " for k in range(0, n): \n", 351 | " A1[j][k] = A1[j][k] - ratio * A1[i][k]\n", 352 | " \n", 353 | " product = 1\n", 354 | " for i in range(n):\n", 355 | " product *= A1[i][i] \n", 356 | " \n", 357 | " return product" 358 | ] 359 | }, 360 | { 361 | "cell_type": "markdown", 362 | "metadata": {}, 363 | "source": [ 364 | "# copy 라이브러리 안쓰고" 365 | ] 366 | }, 367 | { 368 | "cell_type": "code", 369 | "execution_count": 10, 370 | "metadata": {}, 371 | "outputs": [], 372 | "source": [ 373 | "def det_tri(A):\n", 374 | " \"\"\"\n", 375 | " 상 삼각 행렬 변환을 이용해 행렬식 구하기\n", 376 | " 입력값: 행렬 A\n", 377 | " 출력값: 행렬식 res\n", 378 | " \"\"\"\n", 379 | " n = len(A)\n", 380 | " X = deepcopy(A)\n", 381 | " n_row_change = 0\n", 382 | " \n", 383 | " for i in range(0,n): \n", 384 | " if X[i][i] == 0:\n", 385 | " tmp = X[i+1]\n", 386 | " X[i+1] = X[i]\n", 387 | " X[i] = tmp\n", 388 | " n_row_change += 1\n", 389 | " for j in range(i+1,n):\n", 390 | " ratio = X[j][i] / X[i][i] \n", 391 | " for k in range(0, n):\n", 392 | " X[j][k] = X[j][k] - ratio * X[i][k]\n", 393 | " \n", 394 | " n_row_change = (-1)**(n_row_change) \n", 395 | " res = 1\n", 396 | " for i in range(n):\n", 397 | " res *= X[i][i] \n", 398 | " res *= n_row_change \n", 399 | " return res" 400 | ] 401 | }, 402 | { 403 | "cell_type": "code", 404 | "execution_count": 11, 405 | "metadata": {}, 406 | "outputs": [ 407 | { 408 | "data": { 409 | "text/plain": [ 410 | "-4.0" 411 | ] 412 | }, 413 | "execution_count": 11, 414 | "metadata": {}, 415 | "output_type": "execute_result" 416 | } 417 | ], 418 | "source": [ 419 | "A = [[1,3,1,4],[3,9,5,15],[0,2,1,1],[0,4,2,3]]\n", 420 | "det_tri(A)" 421 | ] 422 | }, 423 | { 424 | "cell_type": "code", 425 | "execution_count": 12, 426 | "metadata": {}, 427 | "outputs": [ 428 | { 429 | "data": { 430 | "text/plain": [ 431 | "9.0" 432 | ] 433 | }, 434 | "execution_count": 12, 435 | "metadata": {}, 436 | "output_type": "execute_result" 437 | } 438 | ], 439 | "source": [ 440 | "B = [[6,3],[5,4]]\n", 441 | "det_tri(B)" 442 | ] 443 | }, 444 | { 445 | "cell_type": "code", 446 | "execution_count": null, 447 | "metadata": {}, 448 | "outputs": [], 449 | "source": [] 450 | } 451 | ], 452 | "metadata": { 453 | "kernelspec": { 454 | "display_name": "Python 3", 455 | "language": "python", 456 | "name": "python3" 457 | }, 458 | "language_info": { 459 | "codemirror_mode": { 460 | "name": "ipython", 461 | "version": 3 462 | }, 463 | "file_extension": ".py", 464 | "mimetype": "text/x-python", 465 | "name": "python", 466 | "nbconvert_exporter": "python", 467 | "pygments_lexer": "ipython3", 468 | "version": "3.8.5" 469 | } 470 | }, 471 | "nbformat": 4, 472 | "nbformat_minor": 4 473 | } 474 | -------------------------------------------------------------------------------- /code/.ipynb_checkpoints/ch07-3.파이썬 역행렬 연산-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 행렬식 구하기" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 18, 13 | "metadata": {}, 14 | "outputs": [ 15 | { 16 | "name": "stdout", 17 | "output_type": "stream", 18 | "text": [ 19 | "5\n" 20 | ] 21 | } 22 | ], 23 | "source": [ 24 | "A = [[3,2,0], [-1,-3,6], [2,3,-5]]\n", 25 | "\n", 26 | "n = len(A)\n", 27 | "p = len(A[0])\n", 28 | "\n", 29 | "detA = 0\n", 30 | "for j in range(0, p): \n", 31 | " M = [A[1][:j]+A[1][j+1:], A[2][:j]+A[2][j+1:]] \n", 32 | " Mij = M[0][0]*M[1][1] - M[0][1]*M[1][0] \n", 33 | " Cij = ((-1)**(0+j))*Mij\n", 34 | " detA += A[0][j]*Cij\n", 35 | "\n", 36 | "print(detA)" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "# 여인수행렬 구하기" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 19, 49 | "metadata": {}, 50 | "outputs": [ 51 | { 52 | "data": { 53 | "text/plain": [ 54 | "[[-3, 6], [3, -5]]" 55 | ] 56 | }, 57 | "execution_count": 19, 58 | "metadata": {}, 59 | "output_type": "execute_result" 60 | } 61 | ], 62 | "source": [ 63 | "# 1행 1열\n", 64 | "[A[1][:0]+A[1][0+1:], A[2][:0]+A[2][0+1:]] " 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 20, 70 | "metadata": {}, 71 | "outputs": [ 72 | { 73 | "data": { 74 | "text/plain": [ 75 | "[[-1, 6], [2, -5]]" 76 | ] 77 | }, 78 | "execution_count": 20, 79 | "metadata": {}, 80 | "output_type": "execute_result" 81 | } 82 | ], 83 | "source": [ 84 | "# 1행 2열\n", 85 | "[A[1][:1]+A[1][1+1:], A[2][:1]+A[2][1+1:]] " 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 21, 91 | "metadata": {}, 92 | "outputs": [ 93 | { 94 | "data": { 95 | "text/plain": [ 96 | "[[-1, -3], [2, 3]]" 97 | ] 98 | }, 99 | "execution_count": 21, 100 | "metadata": {}, 101 | "output_type": "execute_result" 102 | } 103 | ], 104 | "source": [ 105 | "# 1행 3열\n", 106 | "[A[1][:2]+A[1][2+1:], A[2][:2]+A[2][2+1:]] " 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 22, 112 | "metadata": {}, 113 | "outputs": [ 114 | { 115 | "data": { 116 | "text/plain": [ 117 | "[[2, 0], [3, -5]]" 118 | ] 119 | }, 120 | "execution_count": 22, 121 | "metadata": {}, 122 | "output_type": "execute_result" 123 | } 124 | ], 125 | "source": [ 126 | "# 2행 1열\n", 127 | "[A[0][:0]+A[0][0+1:], A[2][:0]+A[2][0+1:]] " 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": 23, 133 | "metadata": {}, 134 | "outputs": [ 135 | { 136 | "data": { 137 | "text/plain": [ 138 | "[[3, 0], [2, -5]]" 139 | ] 140 | }, 141 | "execution_count": 23, 142 | "metadata": {}, 143 | "output_type": "execute_result" 144 | } 145 | ], 146 | "source": [ 147 | "# 2행 2열\n", 148 | "[A[0][:1]+A[0][1+1:], A[2][:1]+A[2][1+1:]] " 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": 24, 154 | "metadata": {}, 155 | "outputs": [ 156 | { 157 | "data": { 158 | "text/plain": [ 159 | "[[3, 2], [2, 3]]" 160 | ] 161 | }, 162 | "execution_count": 24, 163 | "metadata": {}, 164 | "output_type": "execute_result" 165 | } 166 | ], 167 | "source": [ 168 | "# 2행 3열\n", 169 | "[A[0][:2]+A[0][2+1:], A[2][:2]+A[2][2+1:]] " 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": 25, 175 | "metadata": {}, 176 | "outputs": [ 177 | { 178 | "data": { 179 | "text/plain": [ 180 | "[[2, 0], [-3, 6]]" 181 | ] 182 | }, 183 | "execution_count": 25, 184 | "metadata": {}, 185 | "output_type": "execute_result" 186 | } 187 | ], 188 | "source": [ 189 | "# 3행 1열\n", 190 | "[A[0][:0]+A[0][0+1:], A[1][:0]+A[1][0+1:]] " 191 | ] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "execution_count": 26, 196 | "metadata": {}, 197 | "outputs": [ 198 | { 199 | "data": { 200 | "text/plain": [ 201 | "[[3, 0], [-1, 6]]" 202 | ] 203 | }, 204 | "execution_count": 26, 205 | "metadata": {}, 206 | "output_type": "execute_result" 207 | } 208 | ], 209 | "source": [ 210 | "# 3행 2열\n", 211 | "[A[0][:1]+A[0][1+1:], A[1][:1]+A[1][1+1:]] " 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": 27, 217 | "metadata": {}, 218 | "outputs": [ 219 | { 220 | "data": { 221 | "text/plain": [ 222 | "[[3, 2], [-1, -3]]" 223 | ] 224 | }, 225 | "execution_count": 27, 226 | "metadata": {}, 227 | "output_type": "execute_result" 228 | } 229 | ], 230 | "source": [ 231 | "# 3행 3열\n", 232 | "[A[0][:2]+A[0][2+1:], A[1][:2]+A[1][2+1:]] " 233 | ] 234 | }, 235 | { 236 | "cell_type": "code", 237 | "execution_count": 28, 238 | "metadata": {}, 239 | "outputs": [], 240 | "source": [ 241 | "def zero_mat(n, p):\n", 242 | " \"\"\"\n", 243 | " 영 행렬 생성\n", 244 | " 입력값: 생성하고자 할 영 행렬의 크기 n행, p열\n", 245 | " 출력값: nxp 영 행렬 Z\n", 246 | " \"\"\"\n", 247 | " Z = []\n", 248 | " for i in range(0, n):\n", 249 | " row = []\n", 250 | " for j in range(0, p):\n", 251 | " row.append(0)\n", 252 | " Z.append(row)\n", 253 | " return Z\n", 254 | "\n", 255 | "\n", 256 | "def deepcopy(A):\n", 257 | " \"\"\"\n", 258 | " 깊은 복사(deepcopy) 구현\n", 259 | " 입력값: 깊은 복사를 하고자 하는 행렬 리스트 A\n", 260 | " 출력값: 깊은 복사 된 결과 행렬 리스트 res \n", 261 | " \"\"\"\n", 262 | " if type(A[0]) == list:\n", 263 | " n = len(A)\n", 264 | " p = len(A[0])\n", 265 | " res = zero_mat(n,p)\n", 266 | " for i in range(0,n):\n", 267 | " for j in range(0,p):\n", 268 | " res[i][j] = A[i][j]\n", 269 | " return res\n", 270 | " else:\n", 271 | " n = len(A)\n", 272 | " res = []\n", 273 | " for i in range(0,n):\n", 274 | " res.append(A[i])\n", 275 | " return res\n", 276 | "\n", 277 | "def det_rec(A):\n", 278 | " \n", 279 | " \"\"\"\n", 280 | " 행렬 A의 행렬식 구하기(재귀 방식을 이용)\n", 281 | " 입력값: 행렬식을 구하고자 하는 행렬 A\n", 282 | " 출력값: 행렬 A의 행렬식 res\n", 283 | " \"\"\"\n", 284 | " \n", 285 | " n = len(A)\n", 286 | " res = 0\n", 287 | "\n", 288 | " # 2x2 행렬의 행렬식 구하기\n", 289 | " if n == 2:\n", 290 | " res = A[0][0] * A[1][1] - A[1][0] * A[0][1]\n", 291 | " return res\n", 292 | "\n", 293 | " # nxn 행렬의 행렬식 구하기\n", 294 | " for i in range(0,n): \n", 295 | " X = deepcopy(A) \n", 296 | " X = X[1:] \n", 297 | " nx = len(X)\n", 298 | "\n", 299 | " for j in range(0,nx): \n", 300 | " X[j] = X[j][0:i] + X[j][i+1:] \n", 301 | "\n", 302 | " sign = (-1) ** (i % 2) \n", 303 | " sub_det = det_rec(X) \n", 304 | " res += sign * A[0][i] * sub_det \n", 305 | "\n", 306 | " return res" 307 | ] 308 | }, 309 | { 310 | "cell_type": "code", 311 | "execution_count": 29, 312 | "metadata": { 313 | "scrolled": true 314 | }, 315 | "outputs": [], 316 | "source": [ 317 | "C = []\n", 318 | "for i in range(0, n):\n", 319 | " row_C = []\n", 320 | " idx_r = list(range(0, n))\n", 321 | " idx_r.remove(i)\n", 322 | " for j in range(0, n):\n", 323 | " idx_c = list(range(0,n))\n", 324 | " idx_c.remove(j)\n", 325 | " M = []\n", 326 | " for k in idx_r:\n", 327 | " row_M = []\n", 328 | " for l in idx_c:\n", 329 | " val = A[k][l]\n", 330 | " row_M.append(val)\n", 331 | " M.append(row_M)\n", 332 | " Mij = det_rec(M)\n", 333 | " Cij = ((-1)**(i+j))*Mij\n", 334 | " row_C.append(Cij)\n", 335 | " C.append(row_C)" 336 | ] 337 | }, 338 | { 339 | "cell_type": "code", 340 | "execution_count": 30, 341 | "metadata": {}, 342 | "outputs": [ 343 | { 344 | "data": { 345 | "text/plain": [ 346 | "[[-3, 7, 3], [10, -15, -5], [12, -18, -7]]" 347 | ] 348 | }, 349 | "execution_count": 30, 350 | "metadata": {}, 351 | "output_type": "execute_result" 352 | } 353 | ], 354 | "source": [ 355 | "C" 356 | ] 357 | }, 358 | { 359 | "cell_type": "markdown", 360 | "metadata": {}, 361 | "source": [ 362 | "# 수반 행렬" 363 | ] 364 | }, 365 | { 366 | "cell_type": "code", 367 | "execution_count": 31, 368 | "metadata": {}, 369 | "outputs": [], 370 | "source": [ 371 | "def transpose(A):\n", 372 | " \"\"\"\n", 373 | " 행렬의 전치행렬\n", 374 | " 입력값: 전치행렬을 구하고자 하는 행렬 A\n", 375 | " 출력값: 행렬 A의 전치행렬 At\n", 376 | " \"\"\"\n", 377 | " n = len(A)\n", 378 | " p = len(A[0])\n", 379 | "\n", 380 | " At = []\n", 381 | " for i in range(0, p):\n", 382 | " row = []\n", 383 | " for j in range(0, n):\n", 384 | " val = A[j][i]\n", 385 | " row.append(val)\n", 386 | " At.append(row)\n", 387 | " return At " 388 | ] 389 | }, 390 | { 391 | "cell_type": "code", 392 | "execution_count": 32, 393 | "metadata": {}, 394 | "outputs": [ 395 | { 396 | "name": "stdout", 397 | "output_type": "stream", 398 | "text": [ 399 | "[[-3, 10, 12], [7, -15, -18], [3, -5, -7]]\n" 400 | ] 401 | } 402 | ], 403 | "source": [ 404 | "adj = transpose(C)\n", 405 | "print(adj)" 406 | ] 407 | }, 408 | { 409 | "cell_type": "markdown", 410 | "metadata": {}, 411 | "source": [ 412 | "# 역행렬" 413 | ] 414 | }, 415 | { 416 | "cell_type": "code", 417 | "execution_count": 33, 418 | "metadata": {}, 419 | "outputs": [], 420 | "source": [ 421 | "def scalar_mul(b, A):\n", 422 | " \"\"\"\n", 423 | " 행렬의 스칼라곱\n", 424 | " 입력값: 스칼라곱을 수행할 스칼라 b, 행렬 A\n", 425 | " 출력값: 스칼라 b와 행렬 A의 스칼라곱 결과인 행렬 res\n", 426 | " \"\"\"\n", 427 | "\n", 428 | " n = len(A)\n", 429 | " p = len(A[0])\n", 430 | " \n", 431 | " res = []\n", 432 | " for i in range(0, n):\n", 433 | " row = []\n", 434 | " for j in range(0, p):\n", 435 | " val = b * A[i][j]\n", 436 | " row.append(val)\n", 437 | " res.append(row)\n", 438 | " return res" 439 | ] 440 | }, 441 | { 442 | "cell_type": "code", 443 | "execution_count": 39, 444 | "metadata": {}, 445 | "outputs": [], 446 | "source": [ 447 | "invA = scalar_mul(1/detA, adj)" 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "execution_count": 40, 453 | "metadata": {}, 454 | "outputs": [ 455 | { 456 | "data": { 457 | "text/plain": [ 458 | "[[-0.6000000000000001, 2.0, 2.4000000000000004],\n", 459 | " [1.4000000000000001, -3.0, -3.6],\n", 460 | " [0.6000000000000001, -1.0, -1.4000000000000001]]" 461 | ] 462 | }, 463 | "execution_count": 40, 464 | "metadata": {}, 465 | "output_type": "execute_result" 466 | } 467 | ], 468 | "source": [ 469 | "invA" 470 | ] 471 | }, 472 | { 473 | "cell_type": "markdown", 474 | "metadata": {}, 475 | "source": [ 476 | "# 함수로 구현 하기" 477 | ] 478 | }, 479 | { 480 | "cell_type": "code", 481 | "execution_count": 36, 482 | "metadata": {}, 483 | "outputs": [], 484 | "source": [ 485 | "def zero_mat(n, p):\n", 486 | " \"\"\"\n", 487 | " 영 행렬 생성\n", 488 | " 입력값: 생성하고자 할 영 행렬의 크기 n행, p열\n", 489 | " 출력값: nxp 영 행렬 Z\n", 490 | " \"\"\"\n", 491 | " Z = []\n", 492 | " for i in range(0, n):\n", 493 | " row = []\n", 494 | " for j in range(0, p):\n", 495 | " row.append(0)\n", 496 | " Z.append(row)\n", 497 | " return Z\n", 498 | "\n", 499 | "\n", 500 | "def deepcopy(A):\n", 501 | " \"\"\"\n", 502 | " 깊은 복사(deepcopy) 구현\n", 503 | " 입력값: 깊은 복사를 하고자 하는 행렬 리스트 A\n", 504 | " 출력값: 깊은 복사 된 결과 행렬 리스트 res \n", 505 | " \"\"\"\n", 506 | " if type(A[0]) == list:\n", 507 | " n = len(A)\n", 508 | " p = len(A[0])\n", 509 | " res = zero_mat(n,p)\n", 510 | " for i in range(0,n):\n", 511 | " for j in range(0,p):\n", 512 | " res[i][j] = A[i][j]\n", 513 | " return res\n", 514 | " else:\n", 515 | " n = len(A)\n", 516 | " res = []\n", 517 | " for i in range(0,n):\n", 518 | " res.append(A[i])\n", 519 | " return res\n", 520 | "\n", 521 | "def transpose(A):\n", 522 | " \"\"\"\n", 523 | " 행렬의 전치행렬\n", 524 | " 입력값: 전치행렬을 구하고자 하는 행렬 A\n", 525 | " 출력값: 행렬 A의 전치행렬 At\n", 526 | " \"\"\"\n", 527 | " n = len(A)\n", 528 | " p = len(A[0])\n", 529 | "\n", 530 | " At = []\n", 531 | " for i in range(0, p):\n", 532 | " row = []\n", 533 | " for j in range(0, n):\n", 534 | " val = A[j][i]\n", 535 | " row.append(val)\n", 536 | " At.append(row)\n", 537 | " return At \n", 538 | "\n", 539 | "\n", 540 | "def scalar_mul(b, A):\n", 541 | " \"\"\"\n", 542 | " 행렬의 스칼라곱\n", 543 | " 입력값: 스칼라곱을 수행할 스칼라 b, 행렬 A\n", 544 | " 출력값: 스칼라 b와 행렬 A의 스칼라곱 결과인 행렬 res\n", 545 | " \"\"\"\n", 546 | "\n", 547 | " n = len(A)\n", 548 | " p = len(A[0])\n", 549 | " \n", 550 | " res = []\n", 551 | " for i in range(0, n):\n", 552 | " row = []\n", 553 | " for j in range(0, p):\n", 554 | " val = b * A[i][j]\n", 555 | " row.append(val)\n", 556 | " res.append(row)\n", 557 | " return res\n", 558 | "\n", 559 | "\n", 560 | "\n", 561 | "def det_rec(A):\n", 562 | " \n", 563 | " \"\"\"\n", 564 | " 행렬 A의 행렬식 구하기(재귀 방식을 이용)\n", 565 | " 입력값: 행렬식을 구하고자 하는 행렬 A\n", 566 | " 출력값: 행렬 A의 행렬식 res\n", 567 | " \"\"\"\n", 568 | " \n", 569 | " n = len(A)\n", 570 | " res = 0\n", 571 | "\n", 572 | " # 2x2 행렬의 행렬식 구하기\n", 573 | " if n == 2:\n", 574 | " res = A[0][0] * A[1][1] - A[1][0] * A[0][1]\n", 575 | " return res\n", 576 | "\n", 577 | " # nxn 행렬의 행렬식 구하기\n", 578 | " for i in range(0,n): \n", 579 | " X = deepcopy(A) \n", 580 | " X = X[1:] \n", 581 | " nx = len(X)\n", 582 | "\n", 583 | " for j in range(0,nx): \n", 584 | " X[j] = X[j][0:i] + X[j][i+1:] \n", 585 | "\n", 586 | " sign = (-1) ** (i % 2) \n", 587 | " sub_det = det_rec(X) \n", 588 | " res += sign * A[0][i] * sub_det \n", 589 | "\n", 590 | " return res\n", 591 | "\n", 592 | "\n", 593 | "\n", 594 | " \n", 595 | "def inv(A):\n", 596 | " \"\"\"\n", 597 | " 행렬 A의 역행렬 구하기\n", 598 | " 입력값: 행렬 A\n", 599 | " 출력값: 행렬 A의 역행렬 res\n", 600 | " \"\"\"\n", 601 | " \n", 602 | " n = len(A)\n", 603 | " X = deepcopy(A)\n", 604 | " \n", 605 | " C = []\n", 606 | " for i in range(0, n):\n", 607 | " row_C = []\n", 608 | " idx_r = list(range(0, n))\n", 609 | " idx_r.remove(i)\n", 610 | " for j in range(0, n):\n", 611 | " idx_c = list(range(0,n))\n", 612 | " idx_c.remove(j)\n", 613 | " M = []\n", 614 | " for k in idx_r:\n", 615 | " row_M = []\n", 616 | " for l in idx_c:\n", 617 | " val = X[k][l]\n", 618 | " row_M.append(val)\n", 619 | " M.append(row_M)\n", 620 | " Mij = det_rec(M)\n", 621 | " Cij = ((-1)**(i+j))*Mij\n", 622 | " row_C.append(Cij)\n", 623 | " C.append(row_C)\n", 624 | " \n", 625 | " adj = transpose(C)\n", 626 | " res = scalar_mul(1/det_rec(X), adj)\n", 627 | " \n", 628 | " return res" 629 | ] 630 | }, 631 | { 632 | "cell_type": "code", 633 | "execution_count": 37, 634 | "metadata": {}, 635 | "outputs": [], 636 | "source": [ 637 | "A = [[3,2,0], [-1,-3,6], [2,3,-5]]" 638 | ] 639 | }, 640 | { 641 | "cell_type": "code", 642 | "execution_count": 38, 643 | "metadata": {}, 644 | "outputs": [ 645 | { 646 | "data": { 647 | "text/plain": [ 648 | "[[-0.6000000000000001, 2.0, 2.4000000000000004],\n", 649 | " [1.4000000000000001, -3.0, -3.6],\n", 650 | " [0.6000000000000001, -1.0, -1.4000000000000001]]" 651 | ] 652 | }, 653 | "execution_count": 38, 654 | "metadata": {}, 655 | "output_type": "execute_result" 656 | } 657 | ], 658 | "source": [ 659 | "inv(A)" 660 | ] 661 | }, 662 | { 663 | "cell_type": "code", 664 | "execution_count": null, 665 | "metadata": {}, 666 | "outputs": [], 667 | "source": [] 668 | } 669 | ], 670 | "metadata": { 671 | "kernelspec": { 672 | "display_name": "Python 3", 673 | "language": "python", 674 | "name": "python3" 675 | }, 676 | "language_info": { 677 | "codemirror_mode": { 678 | "name": "ipython", 679 | "version": 3 680 | }, 681 | "file_extension": ".py", 682 | "mimetype": "text/x-python", 683 | "name": "python", 684 | "nbconvert_exporter": "python", 685 | "pygments_lexer": "ipython3", 686 | "version": "3.8.5" 687 | } 688 | }, 689 | "nbformat": 4, 690 | "nbformat_minor": 4 691 | } 692 | -------------------------------------------------------------------------------- /code/.ipynb_checkpoints/ch07-4.넘파이 역행렬 연산-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 넘파이를 활용한 역행렬 계산" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import numpy as np" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 3, 22 | "metadata": {}, 23 | "outputs": [ 24 | { 25 | "name": "stdout", 26 | "output_type": "stream", 27 | "text": [ 28 | "[[ 3 2 0]\n", 29 | " [-1 -3 6]\n", 30 | " [ 2 3 -5]]\n", 31 | "----\n", 32 | "[[-0.6 2. 2.4]\n", 33 | " [ 1.4 -3. -3.6]\n", 34 | " [ 0.6 -1. -1.4]]\n" 35 | ] 36 | } 37 | ], 38 | "source": [ 39 | "A = np.array([[3,2,0], [-1,-3,6], [2,3,-5]])\n", 40 | "invA = np.linalg.inv(A)\n", 41 | "print(A)\n", 42 | "print('----')\n", 43 | "print(invA)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [] 52 | } 53 | ], 54 | "metadata": { 55 | "kernelspec": { 56 | "display_name": "Python 3", 57 | "language": "python", 58 | "name": "python3" 59 | }, 60 | "language_info": { 61 | "codemirror_mode": { 62 | "name": "ipython", 63 | "version": 3 64 | }, 65 | "file_extension": ".py", 66 | "mimetype": "text/x-python", 67 | "name": "python", 68 | "nbconvert_exporter": "python", 69 | "pygments_lexer": "ipython3", 70 | "version": "3.8.5" 71 | } 72 | }, 73 | "nbformat": 4, 74 | "nbformat_minor": 4 75 | } 76 | -------------------------------------------------------------------------------- /code/.ipynb_checkpoints/ch16-3.파이썬 텐서-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 텐서의 기초" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 3, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "# 벡터\n", 17 | "x = [1,2]" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": 5, 23 | "metadata": {}, 24 | "outputs": [ 25 | { 26 | "data": { 27 | "text/plain": [ 28 | "1" 29 | ] 30 | }, 31 | "execution_count": 5, 32 | "metadata": {}, 33 | "output_type": "execute_result" 34 | } 35 | ], 36 | "source": [ 37 | "x[0]" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 6, 43 | "metadata": {}, 44 | "outputs": [ 45 | { 46 | "data": { 47 | "text/plain": [ 48 | "2" 49 | ] 50 | }, 51 | "execution_count": 6, 52 | "metadata": {}, 53 | "output_type": "execute_result" 54 | } 55 | ], 56 | "source": [ 57 | "x[1]" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 4, 63 | "metadata": {}, 64 | "outputs": [], 65 | "source": [ 66 | "# 행렬\n", 67 | "A = [[1,2], [3,4]]" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 8, 73 | "metadata": {}, 74 | "outputs": [ 75 | { 76 | "data": { 77 | "text/plain": [ 78 | "1" 79 | ] 80 | }, 81 | "execution_count": 8, 82 | "metadata": {}, 83 | "output_type": "execute_result" 84 | } 85 | ], 86 | "source": [ 87 | "A[0][0]" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 9, 93 | "metadata": {}, 94 | "outputs": [ 95 | { 96 | "data": { 97 | "text/plain": [ 98 | "2" 99 | ] 100 | }, 101 | "execution_count": 9, 102 | "metadata": {}, 103 | "output_type": "execute_result" 104 | } 105 | ], 106 | "source": [ 107 | "A[0][1]" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 11, 113 | "metadata": {}, 114 | "outputs": [ 115 | { 116 | "data": { 117 | "text/plain": [ 118 | "3" 119 | ] 120 | }, 121 | "execution_count": 11, 122 | "metadata": {}, 123 | "output_type": "execute_result" 124 | } 125 | ], 126 | "source": [ 127 | "A[1][0]" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": 12, 133 | "metadata": {}, 134 | "outputs": [ 135 | { 136 | "data": { 137 | "text/plain": [ 138 | "4" 139 | ] 140 | }, 141 | "execution_count": 12, 142 | "metadata": {}, 143 | "output_type": "execute_result" 144 | } 145 | ], 146 | "source": [ 147 | "A[1][1]" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": 13, 153 | "metadata": {}, 154 | "outputs": [], 155 | "source": [ 156 | "# 텐서\n", 157 | "T = [[[1,2], [3,4]], [[5,6], [7,8]]]" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": 14, 163 | "metadata": {}, 164 | "outputs": [ 165 | { 166 | "data": { 167 | "text/plain": [ 168 | "1" 169 | ] 170 | }, 171 | "execution_count": 14, 172 | "metadata": {}, 173 | "output_type": "execute_result" 174 | } 175 | ], 176 | "source": [ 177 | "T[0][0][0]" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 15, 183 | "metadata": {}, 184 | "outputs": [ 185 | { 186 | "data": { 187 | "text/plain": [ 188 | "2" 189 | ] 190 | }, 191 | "execution_count": 15, 192 | "metadata": {}, 193 | "output_type": "execute_result" 194 | } 195 | ], 196 | "source": [ 197 | "T[0][0][1]" 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": 16, 203 | "metadata": {}, 204 | "outputs": [ 205 | { 206 | "data": { 207 | "text/plain": [ 208 | "3" 209 | ] 210 | }, 211 | "execution_count": 16, 212 | "metadata": {}, 213 | "output_type": "execute_result" 214 | } 215 | ], 216 | "source": [ 217 | "T[0][1][0]" 218 | ] 219 | }, 220 | { 221 | "cell_type": "code", 222 | "execution_count": 17, 223 | "metadata": {}, 224 | "outputs": [ 225 | { 226 | "data": { 227 | "text/plain": [ 228 | "4" 229 | ] 230 | }, 231 | "execution_count": 17, 232 | "metadata": {}, 233 | "output_type": "execute_result" 234 | } 235 | ], 236 | "source": [ 237 | "T[0][1][1]" 238 | ] 239 | }, 240 | { 241 | "cell_type": "code", 242 | "execution_count": 18, 243 | "metadata": {}, 244 | "outputs": [ 245 | { 246 | "data": { 247 | "text/plain": [ 248 | "5" 249 | ] 250 | }, 251 | "execution_count": 18, 252 | "metadata": {}, 253 | "output_type": "execute_result" 254 | } 255 | ], 256 | "source": [ 257 | "T[1][0][0]" 258 | ] 259 | }, 260 | { 261 | "cell_type": "code", 262 | "execution_count": 19, 263 | "metadata": {}, 264 | "outputs": [ 265 | { 266 | "data": { 267 | "text/plain": [ 268 | "6" 269 | ] 270 | }, 271 | "execution_count": 19, 272 | "metadata": {}, 273 | "output_type": "execute_result" 274 | } 275 | ], 276 | "source": [ 277 | "T[1][0][1]" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": 20, 283 | "metadata": {}, 284 | "outputs": [ 285 | { 286 | "data": { 287 | "text/plain": [ 288 | "7" 289 | ] 290 | }, 291 | "execution_count": 20, 292 | "metadata": {}, 293 | "output_type": "execute_result" 294 | } 295 | ], 296 | "source": [ 297 | "T[1][1][0]" 298 | ] 299 | }, 300 | { 301 | "cell_type": "code", 302 | "execution_count": 21, 303 | "metadata": {}, 304 | "outputs": [ 305 | { 306 | "data": { 307 | "text/plain": [ 308 | "8" 309 | ] 310 | }, 311 | "execution_count": 21, 312 | "metadata": {}, 313 | "output_type": "execute_result" 314 | } 315 | ], 316 | "source": [ 317 | "T[1][1][1]" 318 | ] 319 | }, 320 | { 321 | "cell_type": "markdown", 322 | "metadata": {}, 323 | "source": [ 324 | "# 텐서의 기본 연산" 325 | ] 326 | }, 327 | { 328 | "cell_type": "markdown", 329 | "metadata": {}, 330 | "source": [ 331 | "## 텐서의 노름" 332 | ] 333 | }, 334 | { 335 | "cell_type": "code", 336 | "execution_count": 2, 337 | "metadata": {}, 338 | "outputs": [], 339 | "source": [ 340 | "A = [ [[1,0,1,0],[2,1,0,1],[3,4,0,2]], \n", 341 | " [[3,1,2,0],[1,0,4,2],[0,1,0,2]] ]" 342 | ] 343 | }, 344 | { 345 | "cell_type": "code", 346 | "execution_count": 3, 347 | "metadata": {}, 348 | "outputs": [ 349 | { 350 | "name": "stdout", 351 | "output_type": "stream", 352 | "text": [ 353 | "[[[1, 0, 1, 0], [2, 1, 0, 1], [3, 4, 0, 2]], [[3, 1, 2, 0], [1, 0, 4, 2], [0, 1, 0, 2]]]\n" 354 | ] 355 | } 356 | ], 357 | "source": [ 358 | "print(A)" 359 | ] 360 | }, 361 | { 362 | "cell_type": "code", 363 | "execution_count": 4, 364 | "metadata": {}, 365 | "outputs": [], 366 | "source": [ 367 | "n = len(A[0])\n", 368 | "p = len(A[0][0])\n", 369 | "q = len(A)" 370 | ] 371 | }, 372 | { 373 | "cell_type": "code", 374 | "execution_count": 5, 375 | "metadata": {}, 376 | "outputs": [ 377 | { 378 | "name": "stdout", 379 | "output_type": "stream", 380 | "text": [ 381 | "3\n", 382 | "4\n", 383 | "2\n" 384 | ] 385 | } 386 | ], 387 | "source": [ 388 | "print(n)\n", 389 | "print(p)\n", 390 | "print(q)" 391 | ] 392 | }, 393 | { 394 | "cell_type": "code", 395 | "execution_count": 6, 396 | "metadata": {}, 397 | "outputs": [], 398 | "source": [ 399 | "norm = 0\n", 400 | "for i in range(0, n):\n", 401 | " for j in range(0, p):\n", 402 | " for k in range(0, q):\n", 403 | " norm += A[k][i][j]**2\n", 404 | "norm = norm**0.5" 405 | ] 406 | }, 407 | { 408 | "cell_type": "code", 409 | "execution_count": 7, 410 | "metadata": {}, 411 | "outputs": [ 412 | { 413 | "name": "stdout", 414 | "output_type": "stream", 415 | "text": [ 416 | "8.774964387392123\n" 417 | ] 418 | } 419 | ], 420 | "source": [ 421 | "print(norm)" 422 | ] 423 | }, 424 | { 425 | "cell_type": "markdown", 426 | "metadata": {}, 427 | "source": [ 428 | "# 텐서의 내적" 429 | ] 430 | }, 431 | { 432 | "cell_type": "code", 433 | "execution_count": 51, 434 | "metadata": {}, 435 | "outputs": [], 436 | "source": [ 437 | "A = [ [[1,0,1,0],[2,1,0,1],[3,4,0,2]], \n", 438 | " [[3,1,2,0],[1,0,4,2],[0,1,0,2]] ]\n", 439 | "\n", 440 | "B = [ [[2,1,3,1],[0,2,1,3],[1,0,1,1]], \n", 441 | " [[1,2,3,1],[3,1,0,3],[0,2,3,1]] ]" 442 | ] 443 | }, 444 | { 445 | "cell_type": "code", 446 | "execution_count": 53, 447 | "metadata": {}, 448 | "outputs": [], 449 | "source": [ 450 | "n = len(A[0])\n", 451 | "p = len(A[0][0])\n", 452 | "q = len(A)" 453 | ] 454 | }, 455 | { 456 | "cell_type": "code", 457 | "execution_count": 54, 458 | "metadata": {}, 459 | "outputs": [], 460 | "source": [ 461 | "inner_product = 0\n", 462 | "for i in range(0, n):\n", 463 | " for j in range(0, p):\n", 464 | " for k in range(0, q):\n", 465 | " inner_product += A[k][i][j]*B[k][i][j]" 466 | ] 467 | }, 468 | { 469 | "cell_type": "code", 470 | "execution_count": 76, 471 | "metadata": {}, 472 | "outputs": [ 473 | { 474 | "name": "stdout", 475 | "output_type": "stream", 476 | "text": [ 477 | "39\n" 478 | ] 479 | } 480 | ], 481 | "source": [ 482 | "print(inner_product)" 483 | ] 484 | }, 485 | { 486 | "cell_type": "markdown", 487 | "metadata": {}, 488 | "source": [ 489 | "# 텐서의 행렬화" 490 | ] 491 | }, 492 | { 493 | "cell_type": "code", 494 | "execution_count": 56, 495 | "metadata": {}, 496 | "outputs": [], 497 | "source": [ 498 | "A = [ [[1,4,7,10],[2,5,8,11],[3,6,9,12]], \n", 499 | " [[13,16,19,22],[14,17,20,23],[15,18,21,24]] ]" 500 | ] 501 | }, 502 | { 503 | "cell_type": "code", 504 | "execution_count": 57, 505 | "metadata": {}, 506 | "outputs": [], 507 | "source": [ 508 | "n = len(A[0])\n", 509 | "p = len(A[0][0])\n", 510 | "q = len(A)" 511 | ] 512 | }, 513 | { 514 | "cell_type": "code", 515 | "execution_count": 58, 516 | "metadata": {}, 517 | "outputs": [ 518 | { 519 | "name": "stdout", 520 | "output_type": "stream", 521 | "text": [ 522 | "3\n", 523 | "4\n", 524 | "2\n" 525 | ] 526 | } 527 | ], 528 | "source": [ 529 | "print(n)\n", 530 | "print(p)\n", 531 | "print(q)" 532 | ] 533 | }, 534 | { 535 | "cell_type": "code", 536 | "execution_count": 61, 537 | "metadata": {}, 538 | "outputs": [], 539 | "source": [ 540 | "mode1 = []\n", 541 | "for i in range(0,n):\n", 542 | " row = []\n", 543 | " for k in range(0,q):\n", 544 | " for j in range(0,p):\n", 545 | " row.append(A[k][i][j])\n", 546 | " mode1.append(row)" 547 | ] 548 | }, 549 | { 550 | "cell_type": "code", 551 | "execution_count": 62, 552 | "metadata": {}, 553 | "outputs": [ 554 | { 555 | "data": { 556 | "text/plain": [ 557 | "[[1, 4, 7, 10, 13, 16, 19, 22],\n", 558 | " [2, 5, 8, 11, 14, 17, 20, 23],\n", 559 | " [3, 6, 9, 12, 15, 18, 21, 24]]" 560 | ] 561 | }, 562 | "execution_count": 62, 563 | "metadata": {}, 564 | "output_type": "execute_result" 565 | } 566 | ], 567 | "source": [ 568 | "mode1" 569 | ] 570 | }, 571 | { 572 | "cell_type": "code", 573 | "execution_count": 63, 574 | "metadata": {}, 575 | "outputs": [], 576 | "source": [ 577 | "mode2 = []\n", 578 | "for j in range(0,p):\n", 579 | " row = []\n", 580 | " for k in range(0,q):\n", 581 | " for i in range(0,n):\n", 582 | " row.append(A[k][i][j])\n", 583 | " mode2.append(row)" 584 | ] 585 | }, 586 | { 587 | "cell_type": "code", 588 | "execution_count": 64, 589 | "metadata": {}, 590 | "outputs": [ 591 | { 592 | "data": { 593 | "text/plain": [ 594 | "[[1, 2, 3, 13, 14, 15],\n", 595 | " [4, 5, 6, 16, 17, 18],\n", 596 | " [7, 8, 9, 19, 20, 21],\n", 597 | " [10, 11, 12, 22, 23, 24]]" 598 | ] 599 | }, 600 | "execution_count": 64, 601 | "metadata": {}, 602 | "output_type": "execute_result" 603 | } 604 | ], 605 | "source": [ 606 | "mode2" 607 | ] 608 | }, 609 | { 610 | "cell_type": "code", 611 | "execution_count": 65, 612 | "metadata": {}, 613 | "outputs": [], 614 | "source": [ 615 | "mode3 = []\n", 616 | "for k in range(0,q):\n", 617 | " row = []\n", 618 | " for j in range(0,p):\n", 619 | " for i in range(0,n):\n", 620 | " row.append(A[k][i][j])\n", 621 | " mode3.append(row)" 622 | ] 623 | }, 624 | { 625 | "cell_type": "code", 626 | "execution_count": 66, 627 | "metadata": {}, 628 | "outputs": [ 629 | { 630 | "data": { 631 | "text/plain": [ 632 | "[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],\n", 633 | " [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]]" 634 | ] 635 | }, 636 | "execution_count": 66, 637 | "metadata": {}, 638 | "output_type": "execute_result" 639 | } 640 | ], 641 | "source": [ 642 | "mode3" 643 | ] 644 | }, 645 | { 646 | "cell_type": "markdown", 647 | "metadata": {}, 648 | "source": [ 649 | "# 텐서 곱" 650 | ] 651 | }, 652 | { 653 | "cell_type": "code", 654 | "execution_count": 67, 655 | "metadata": {}, 656 | "outputs": [], 657 | "source": [ 658 | "U = [[1,3,5],[2,4,6]]\n", 659 | "\n", 660 | "A = [ [[1,4,7,10],[2,5,8,11],[3,6,9,12]], \n", 661 | " [[13,16,19,22],[14,17,20,23],[15,18,21,24]] ]" 662 | ] 663 | }, 664 | { 665 | "cell_type": "code", 666 | "execution_count": 70, 667 | "metadata": {}, 668 | "outputs": [], 669 | "source": [ 670 | "n1 = len(U)\n", 671 | "p1 = len(U[0])\n", 672 | "\n", 673 | "n2 = len(A[0])\n", 674 | "p2 = len(A[0][0])\n", 675 | "q2 = len(A)" 676 | ] 677 | }, 678 | { 679 | "cell_type": "code", 680 | "execution_count": 71, 681 | "metadata": {}, 682 | "outputs": [ 683 | { 684 | "name": "stdout", 685 | "output_type": "stream", 686 | "text": [ 687 | "2\n", 688 | "3\n" 689 | ] 690 | } 691 | ], 692 | "source": [ 693 | "print(n1)\n", 694 | "print(p1)" 695 | ] 696 | }, 697 | { 698 | "cell_type": "code", 699 | "execution_count": 73, 700 | "metadata": {}, 701 | "outputs": [ 702 | { 703 | "name": "stdout", 704 | "output_type": "stream", 705 | "text": [ 706 | "3\n", 707 | "4\n", 708 | "2\n" 709 | ] 710 | } 711 | ], 712 | "source": [ 713 | "print(n2)\n", 714 | "print(p2)\n", 715 | "print(q2)" 716 | ] 717 | }, 718 | { 719 | "cell_type": "code", 720 | "execution_count": 74, 721 | "metadata": {}, 722 | "outputs": [], 723 | "source": [ 724 | "tensor_product = []\n", 725 | "for k in range(0, q2):\n", 726 | " sub_matrix = []\n", 727 | " for i in range(0, n1):\n", 728 | " row = []\n", 729 | " for j2 in range(0,p2):\n", 730 | " val = 0\n", 731 | " for j1 in range(0,p1):\n", 732 | " val += U[i][j1]*A[k][j1][j2]\n", 733 | " row.append(val)\n", 734 | " sub_matrix.append(row)\n", 735 | " tensor_product.append(sub_matrix)" 736 | ] 737 | }, 738 | { 739 | "cell_type": "code", 740 | "execution_count": 75, 741 | "metadata": {}, 742 | "outputs": [ 743 | { 744 | "data": { 745 | "text/plain": [ 746 | "[[[22, 49, 76, 103], [28, 64, 100, 136]],\n", 747 | " [[130, 157, 184, 211], [172, 208, 244, 280]]]" 748 | ] 749 | }, 750 | "execution_count": 75, 751 | "metadata": {}, 752 | "output_type": "execute_result" 753 | } 754 | ], 755 | "source": [ 756 | "tensor_product" 757 | ] 758 | }, 759 | { 760 | "cell_type": "code", 761 | "execution_count": null, 762 | "metadata": {}, 763 | "outputs": [], 764 | "source": [] 765 | } 766 | ], 767 | "metadata": { 768 | "kernelspec": { 769 | "display_name": "Python 3", 770 | "language": "python", 771 | "name": "python3" 772 | }, 773 | "language_info": { 774 | "codemirror_mode": { 775 | "name": "ipython", 776 | "version": 3 777 | }, 778 | "file_extension": ".py", 779 | "mimetype": "text/x-python", 780 | "name": "python", 781 | "nbconvert_exporter": "python", 782 | "pygments_lexer": "ipython3", 783 | "version": "3.8.5" 784 | } 785 | }, 786 | "nbformat": 4, 787 | "nbformat_minor": 4 788 | } 789 | -------------------------------------------------------------------------------- /code/Untitled.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 5, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stdout", 10 | "output_type": "stream", 11 | "text": [ 12 | "[1 2 3]\n" 13 | ] 14 | } 15 | ], 16 | "source": [ 17 | "import numpy as np\n", 18 | "\n", 19 | "A = np.array([1,2,3])\n", 20 | "print(A)" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 1, 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "import my_linear_algebra as mla" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 2, 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [ 45 | "A = [[1,2], [3,4]]" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 3, 51 | "metadata": {}, 52 | "outputs": [], 53 | "source": [ 54 | "B = mla.deepcopy(A)" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 4, 60 | "metadata": {}, 61 | "outputs": [ 62 | { 63 | "name": "stdout", 64 | "output_type": "stream", 65 | "text": [ 66 | "[[1, 2], [3, 4]]\n" 67 | ] 68 | } 69 | ], 70 | "source": [ 71 | "print(B)" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": null, 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [] 80 | } 81 | ], 82 | "metadata": { 83 | "kernelspec": { 84 | "display_name": "Python 3", 85 | "language": "python", 86 | "name": "python3" 87 | }, 88 | "language_info": { 89 | "codemirror_mode": { 90 | "name": "ipython", 91 | "version": 3 92 | }, 93 | "file_extension": ".py", 94 | "mimetype": "text/x-python", 95 | "name": "python", 96 | "nbconvert_exporter": "python", 97 | "pygments_lexer": "ipython3", 98 | "version": "3.8.5" 99 | } 100 | }, 101 | "nbformat": 4, 102 | "nbformat_minor": 4 103 | } 104 | -------------------------------------------------------------------------------- /code/__pycache__/my_linear_algebra.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bjpublic/LinearAlgebra/02bcc1fb19bc48e14a9b385f42c7198543f750b9/code/__pycache__/my_linear_algebra.cpython-38.pyc -------------------------------------------------------------------------------- /code/ch03-1-1.스칼라 연산.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 15, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "# 스칼라 정의" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 13, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "2\n" 22 | ] 23 | } 24 | ], 25 | "source": [ 26 | "x = 2\n", 27 | "print(x)" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 14, 33 | "metadata": {}, 34 | "outputs": [ 35 | { 36 | "name": "stdout", 37 | "output_type": "stream", 38 | "text": [ 39 | "3\n" 40 | ] 41 | } 42 | ], 43 | "source": [ 44 | "x = 3\n", 45 | "print(x)" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 16, 51 | "metadata": {}, 52 | "outputs": [], 53 | "source": [ 54 | "# 스칼라 덧셈" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 18, 60 | "metadata": {}, 61 | "outputs": [ 62 | { 63 | "name": "stdout", 64 | "output_type": "stream", 65 | "text": [ 66 | "5\n" 67 | ] 68 | } 69 | ], 70 | "source": [ 71 | "x = 2\n", 72 | "y = 3\n", 73 | "z = x + y\n", 74 | "print(z)" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 19, 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [ 83 | "# 스칼라 뺄셈" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 21, 89 | "metadata": {}, 90 | "outputs": [ 91 | { 92 | "name": "stdout", 93 | "output_type": "stream", 94 | "text": [ 95 | "3\n" 96 | ] 97 | } 98 | ], 99 | "source": [ 100 | "x = 4\n", 101 | "y = 1\n", 102 | "z = x - y\n", 103 | "print(z)" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 20, 109 | "metadata": {}, 110 | "outputs": [], 111 | "source": [ 112 | "# 스칼라 곱셈" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": 23, 118 | "metadata": {}, 119 | "outputs": [ 120 | { 121 | "name": "stdout", 122 | "output_type": "stream", 123 | "text": [ 124 | "15\n" 125 | ] 126 | } 127 | ], 128 | "source": [ 129 | "x = 5\n", 130 | "y = 3\n", 131 | "z = x * y\n", 132 | "print(z)" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": null, 138 | "metadata": {}, 139 | "outputs": [], 140 | "source": [ 141 | "# 스칼라 나눗셈" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 24, 147 | "metadata": {}, 148 | "outputs": [ 149 | { 150 | "name": "stdout", 151 | "output_type": "stream", 152 | "text": [ 153 | "2.5\n" 154 | ] 155 | } 156 | ], 157 | "source": [ 158 | "x = 5\n", 159 | "y = 2\n", 160 | "z = x / y\n", 161 | "print(z)" 162 | ] 163 | }, 164 | { 165 | "cell_type": "markdown", 166 | "metadata": {}, 167 | "source": [ 168 | "# 전체 코드" 169 | ] 170 | }, 171 | { 172 | "cell_type": "code", 173 | "execution_count": 26, 174 | "metadata": {}, 175 | "outputs": [ 176 | { 177 | "name": "stdout", 178 | "output_type": "stream", 179 | "text": [ 180 | "2\n", 181 | "3\n", 182 | "5\n", 183 | "3\n", 184 | "15\n", 185 | "2.5\n" 186 | ] 187 | } 188 | ], 189 | "source": [ 190 | "# 스칼라 정의\n", 191 | "x = 2\n", 192 | "print(x)\n", 193 | "\n", 194 | "x = 3\n", 195 | "print(x)\n", 196 | "\n", 197 | "# 스칼라 덧셈\n", 198 | "x = 2\n", 199 | "y = 3\n", 200 | "z = x + y\n", 201 | "print(z)\n", 202 | "\n", 203 | "# 스칼라 뺄셈\n", 204 | "x = 4\n", 205 | "y = 1\n", 206 | "z = x - y\n", 207 | "print(z)\n", 208 | "\n", 209 | "# 스칼라 곱셈\n", 210 | "x = 5\n", 211 | "y = 3\n", 212 | "z = x * y\n", 213 | "print(z)\n", 214 | "\n", 215 | "# 스칼라 나눗셈\n", 216 | "x = 5\n", 217 | "y = 2\n", 218 | "z = x / y\n", 219 | "print(z)" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": null, 225 | "metadata": {}, 226 | "outputs": [], 227 | "source": [] 228 | } 229 | ], 230 | "metadata": { 231 | "kernelspec": { 232 | "display_name": "Python 3", 233 | "language": "python", 234 | "name": "python3" 235 | }, 236 | "language_info": { 237 | "codemirror_mode": { 238 | "name": "ipython", 239 | "version": 3 240 | }, 241 | "file_extension": ".py", 242 | "mimetype": "text/x-python", 243 | "name": "python", 244 | "nbconvert_exporter": "python", 245 | "pygments_lexer": "ipython3", 246 | "version": "3.8.5" 247 | } 248 | }, 249 | "nbformat": 4, 250 | "nbformat_minor": 4 251 | } 252 | -------------------------------------------------------------------------------- /code/ch03-2-1.파이썬 벡터 연산 .ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 파이썬 벡터 실습" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 5, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "# 벡터 덧셈\n", 17 | "\n", 18 | "u = [1,2,3]\n", 19 | "v = [4,5,6]\n", 20 | "\n", 21 | "n = len(u)\n", 22 | "w = []\n", 23 | "\n", 24 | "for i in range(0, n):\n", 25 | " val = u[i] + v[i]\n", 26 | " w.append(val) " 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 2, 32 | "metadata": {}, 33 | "outputs": [ 34 | { 35 | "name": "stdout", 36 | "output_type": "stream", 37 | "text": [ 38 | "[5, 7, 9]\n" 39 | ] 40 | } 41 | ], 42 | "source": [ 43 | "print(w)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 3, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | "def v_add(u,v):\n", 53 | " \"\"\"\n", 54 | " 벡터의 덧셈\n", 55 | " 입력값: 더하고자 하는 벡터 u, v\n", 56 | " 출력값: 벡터 u, v의 덧셈 결과 w\n", 57 | " \"\"\"\n", 58 | " n = len(u)\n", 59 | " w = []\n", 60 | "\n", 61 | " for i in range(0, n):\n", 62 | " val = u[i] + v[i]\n", 63 | " w.append(val) \n", 64 | " \n", 65 | " return w" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 6, 71 | "metadata": {}, 72 | "outputs": [ 73 | { 74 | "data": { 75 | "text/plain": [ 76 | "[5, 7, 9]" 77 | ] 78 | }, 79 | "execution_count": 6, 80 | "metadata": {}, 81 | "output_type": "execute_result" 82 | } 83 | ], 84 | "source": [ 85 | "u = [1,2,3]\n", 86 | "v = [4,5,6]\n", 87 | "v_add(u,v)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 7, 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [ 96 | "# 벡터 뺄셈\n", 97 | "\n", 98 | "u = [7,3,9]\n", 99 | "v = [2,5,7]\n", 100 | "\n", 101 | "n = len(u)\n", 102 | "w = []\n", 103 | "\n", 104 | "for i in range(0, n):\n", 105 | " val = u[i] - v[i]\n", 106 | " w.append(val) " 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 8, 112 | "metadata": {}, 113 | "outputs": [ 114 | { 115 | "name": "stdout", 116 | "output_type": "stream", 117 | "text": [ 118 | "[5, -2, 2]\n" 119 | ] 120 | } 121 | ], 122 | "source": [ 123 | "print(w)" 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": 9, 129 | "metadata": {}, 130 | "outputs": [], 131 | "source": [ 132 | "def v_subtract(u,v):\n", 133 | " '''\n", 134 | " 벡터의 뺄셈\n", 135 | " 입력값: 빼고자하는 벡터 리스트 u,v\n", 136 | " 출력값: 벡터 u,v의 뺄셈 결과 w\n", 137 | " '''\n", 138 | " n = len(u)\n", 139 | " w = []\n", 140 | "\n", 141 | " for i in range(0, n):\n", 142 | " val = u[i] - v[i]\n", 143 | " w.append(val)\n", 144 | " return w" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": 12, 150 | "metadata": {}, 151 | "outputs": [ 152 | { 153 | "data": { 154 | "text/plain": [ 155 | "[5, -2, 2]" 156 | ] 157 | }, 158 | "execution_count": 12, 159 | "metadata": {}, 160 | "output_type": "execute_result" 161 | } 162 | ], 163 | "source": [ 164 | "u = [7,3,9]\n", 165 | "v = [2,5,7]\n", 166 | "v_subtract(u,v)" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 25, 172 | "metadata": {}, 173 | "outputs": [], 174 | "source": [ 175 | "# 스칼라와 벡터 곱\n", 176 | "\n", 177 | "u = [2,4,3]\n", 178 | "a = 3\n", 179 | "\n", 180 | "n = len(u)\n", 181 | "w = []\n", 182 | "\n", 183 | "for i in range(0, n):\n", 184 | " val = a*u[i]\n", 185 | " w.append(val) " 186 | ] 187 | }, 188 | { 189 | "cell_type": "code", 190 | "execution_count": 26, 191 | "metadata": {}, 192 | "outputs": [ 193 | { 194 | "name": "stdout", 195 | "output_type": "stream", 196 | "text": [ 197 | "[6, 12, 9]\n" 198 | ] 199 | } 200 | ], 201 | "source": [ 202 | "print(w)" 203 | ] 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": 14, 208 | "metadata": {}, 209 | "outputs": [], 210 | "source": [ 211 | "def scalar_v_mul(a,u):\n", 212 | " '''\n", 213 | " 벡터의 스칼라 곱\n", 214 | " 입력값: 스칼라 a, 벡터 리스트 u\n", 215 | " 출력값: 스칼라 a와 벡터 리스트 u의 곱 결과 w\n", 216 | " '''\n", 217 | " n = len(u)\n", 218 | " w = []\n", 219 | "\n", 220 | " for i in range(0, n):\n", 221 | " val = a*u[i]\n", 222 | " w.append(val) \n", 223 | " \n", 224 | " return w" 225 | ] 226 | }, 227 | { 228 | "cell_type": "code", 229 | "execution_count": 15, 230 | "metadata": {}, 231 | "outputs": [ 232 | { 233 | "data": { 234 | "text/plain": [ 235 | "[6, 12, 9]" 236 | ] 237 | }, 238 | "execution_count": 15, 239 | "metadata": {}, 240 | "output_type": "execute_result" 241 | } 242 | ], 243 | "source": [ 244 | "u = [2,4,3]\n", 245 | "a = 3\n", 246 | "scalar_v_mul(a, u)" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": 16, 252 | "metadata": {}, 253 | "outputs": [], 254 | "source": [ 255 | "# 벡터 곱셈\n", 256 | "\n", 257 | "u = [1,2,4]\n", 258 | "v = [7,3,2]\n", 259 | "\n", 260 | "n = len(u)\n", 261 | "w = []\n", 262 | "\n", 263 | "for i in range(0, n):\n", 264 | " val = u[i] * v[i]\n", 265 | " w.append(val) " 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": 17, 271 | "metadata": {}, 272 | "outputs": [ 273 | { 274 | "name": "stdout", 275 | "output_type": "stream", 276 | "text": [ 277 | "[7, 6, 8]\n" 278 | ] 279 | } 280 | ], 281 | "source": [ 282 | "print(w)" 283 | ] 284 | }, 285 | { 286 | "cell_type": "code", 287 | "execution_count": 18, 288 | "metadata": {}, 289 | "outputs": [], 290 | "source": [ 291 | "def v_mul(u,v):\n", 292 | " \"\"\"\n", 293 | " 벡터의 원소 곱\n", 294 | " 입력값: 원소 곱 하고자할 벡터 리스트 u, v\n", 295 | " 출력값: 벡터 u, v의 원소 곱 결과 w\n", 296 | " \"\"\"\n", 297 | " n = len(u)\n", 298 | " w = []\n", 299 | "\n", 300 | " for i in range(0, n):\n", 301 | " val = u[i] * v[i]\n", 302 | " w.append(val) \n", 303 | " \n", 304 | " return w" 305 | ] 306 | }, 307 | { 308 | "cell_type": "code", 309 | "execution_count": 19, 310 | "metadata": {}, 311 | "outputs": [ 312 | { 313 | "data": { 314 | "text/plain": [ 315 | "[7, 6, 8]" 316 | ] 317 | }, 318 | "execution_count": 19, 319 | "metadata": {}, 320 | "output_type": "execute_result" 321 | } 322 | ], 323 | "source": [ 324 | "u = [1,2,4]\n", 325 | "v = [7,3,2]\n", 326 | "v_mul(u,v)" 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "execution_count": 19, 332 | "metadata": {}, 333 | "outputs": [], 334 | "source": [ 335 | "# 벡터 나눗셈\n", 336 | "\n", 337 | "u = [6,5,9]\n", 338 | "v = [2,2,-3]\n", 339 | "\n", 340 | "n = len(u)\n", 341 | "w = []\n", 342 | "\n", 343 | "for i in range(0, n):\n", 344 | " val = u[i] / v[i]\n", 345 | " w.append(val) " 346 | ] 347 | }, 348 | { 349 | "cell_type": "code", 350 | "execution_count": 52, 351 | "metadata": {}, 352 | "outputs": [ 353 | { 354 | "name": "stdout", 355 | "output_type": "stream", 356 | "text": [ 357 | "[3.0, 2.5, -3.0]\n" 358 | ] 359 | } 360 | ], 361 | "source": [ 362 | "print(w)" 363 | ] 364 | }, 365 | { 366 | "cell_type": "code", 367 | "execution_count": 21, 368 | "metadata": {}, 369 | "outputs": [], 370 | "source": [ 371 | "def v_div(u,v):\n", 372 | " \"\"\"\n", 373 | " 벡터의 원소 나눗셈\n", 374 | " 입력값: 원소 나눗셈 하고자할 벡터 리스트 u, v\n", 375 | " 출력값: 벡터 u, v의 원소 나눗셈 결과 w \n", 376 | " \"\"\"\n", 377 | " n = len(u)\n", 378 | " w = []\n", 379 | "\n", 380 | " for i in range(0, n):\n", 381 | " val = u[i] / v[i]\n", 382 | " w.append(val) \n", 383 | " \n", 384 | " return w" 385 | ] 386 | }, 387 | { 388 | "cell_type": "code", 389 | "execution_count": 22, 390 | "metadata": {}, 391 | "outputs": [ 392 | { 393 | "data": { 394 | "text/plain": [ 395 | "[3.0, 2.5, -3.0]" 396 | ] 397 | }, 398 | "execution_count": 22, 399 | "metadata": {}, 400 | "output_type": "execute_result" 401 | } 402 | ], 403 | "source": [ 404 | "u = [6,5,9]\n", 405 | "v = [2,2,-3]\n", 406 | "v_div(u,v)" 407 | ] 408 | } 409 | ], 410 | "metadata": { 411 | "kernelspec": { 412 | "display_name": "Python 3", 413 | "language": "python", 414 | "name": "python3" 415 | }, 416 | "language_info": { 417 | "codemirror_mode": { 418 | "name": "ipython", 419 | "version": 3 420 | }, 421 | "file_extension": ".py", 422 | "mimetype": "text/x-python", 423 | "name": "python", 424 | "nbconvert_exporter": "python", 425 | "pygments_lexer": "ipython3", 426 | "version": "3.8.5" 427 | } 428 | }, 429 | "nbformat": 4, 430 | "nbformat_minor": 4 431 | } 432 | -------------------------------------------------------------------------------- /code/ch03-2-2.넘파이 벡터 연산.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 넘파이 벡터 실습" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 2, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import numpy as np" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 61, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "# 벡터 덧셈\n", 26 | "u = np.array([1,2,3])\n", 27 | "v = np.array([4,5,6])\n", 28 | "w = u + v" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 62, 34 | "metadata": {}, 35 | "outputs": [ 36 | { 37 | "name": "stdout", 38 | "output_type": "stream", 39 | "text": [ 40 | "[5 7 9]\n" 41 | ] 42 | } 43 | ], 44 | "source": [ 45 | "print(w)" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 63, 51 | "metadata": {}, 52 | "outputs": [], 53 | "source": [ 54 | "# 벡터 뺄셈\n", 55 | "u = np.array([7,3,9])\n", 56 | "v = np.array([2,5,7])\n", 57 | "w = u - v" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 64, 63 | "metadata": {}, 64 | "outputs": [ 65 | { 66 | "name": "stdout", 67 | "output_type": "stream", 68 | "text": [ 69 | "[ 5 -2 2]\n" 70 | ] 71 | } 72 | ], 73 | "source": [ 74 | "print(w)" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 3, 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [ 83 | "# 벡터 스칼라 곱\n", 84 | "a = 3\n", 85 | "u = np.array([1,2,4])\n", 86 | "w = a * u" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 4, 92 | "metadata": {}, 93 | "outputs": [ 94 | { 95 | "name": "stdout", 96 | "output_type": "stream", 97 | "text": [ 98 | "[ 3 6 12]\n" 99 | ] 100 | } 101 | ], 102 | "source": [ 103 | "print(w)" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 67, 109 | "metadata": {}, 110 | "outputs": [], 111 | "source": [ 112 | "# 벡터 곱셈\n", 113 | "u = np.array([1,2,4])\n", 114 | "v = np.array([7,3,2])\n", 115 | "w = u * v" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 68, 121 | "metadata": {}, 122 | "outputs": [ 123 | { 124 | "name": "stdout", 125 | "output_type": "stream", 126 | "text": [ 127 | "[7 6 8]\n" 128 | ] 129 | } 130 | ], 131 | "source": [ 132 | "print(w)" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": 69, 138 | "metadata": {}, 139 | "outputs": [], 140 | "source": [ 141 | "# 벡터 나눗셈\n", 142 | "u = np.array([6,5,9])\n", 143 | "v = np.array([2,2,-3])\n", 144 | "w = u / v" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": 70, 150 | "metadata": {}, 151 | "outputs": [ 152 | { 153 | "name": "stdout", 154 | "output_type": "stream", 155 | "text": [ 156 | "[ 3. 2.5 -3. ]\n" 157 | ] 158 | } 159 | ], 160 | "source": [ 161 | "print(w)" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": null, 167 | "metadata": {}, 168 | "outputs": [], 169 | "source": [] 170 | } 171 | ], 172 | "metadata": { 173 | "kernelspec": { 174 | "display_name": "Python 3", 175 | "language": "python", 176 | "name": "python3" 177 | }, 178 | "language_info": { 179 | "codemirror_mode": { 180 | "name": "ipython", 181 | "version": 3 182 | }, 183 | "file_extension": ".py", 184 | "mimetype": "text/x-python", 185 | "name": "python", 186 | "nbconvert_exporter": "python", 187 | "pygments_lexer": "ipython3", 188 | "version": "3.8.5" 189 | } 190 | }, 191 | "nbformat": 4, 192 | "nbformat_minor": 4 193 | } 194 | -------------------------------------------------------------------------------- /code/ch03-3-1.파이썬 행렬 연산.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 6, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "# 행렬의 덧셈\n", 10 | "A = [[2,7], [3,4], [6,1]]\n", 11 | "B = [[1,4], [4,-1], [2,5]]\n", 12 | "\n", 13 | "n = len(A)\n", 14 | "p = len(A[0])\n", 15 | "\n", 16 | "res = []\n", 17 | "for i in range(0, n):\n", 18 | " row = []\n", 19 | " for j in range(0, p):\n", 20 | " val = A[i][j] + B[i][j]\n", 21 | " row.append(val)\n", 22 | " res.append(row)" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 7, 28 | "metadata": {}, 29 | "outputs": [ 30 | { 31 | "name": "stdout", 32 | "output_type": "stream", 33 | "text": [ 34 | "[[3, 11], [7, 3], [8, 6]]\n" 35 | ] 36 | } 37 | ], 38 | "source": [ 39 | "print(res)" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 11, 45 | "metadata": {}, 46 | "outputs": [], 47 | "source": [ 48 | "def add(A, B):\n", 49 | " \"\"\"\n", 50 | " 행렬의 덧셈\n", 51 | " 입력값: 행렬의 덧셈을 수행할 행렬 A, B\n", 52 | " 출력값: 행렬 A와 행렬 B의 덧셈 결과인 행렬 res\n", 53 | " \"\"\"\n", 54 | "\n", 55 | " n = len(A)\n", 56 | " p = len(A[0])\n", 57 | "\n", 58 | " res = []\n", 59 | " for i in range(0, n):\n", 60 | " row = []\n", 61 | " for j in range(0, p):\n", 62 | " val = A[i][j] + B[i][j]\n", 63 | " row.append(val)\n", 64 | " res.append(row)\n", 65 | " return res" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 12, 71 | "metadata": {}, 72 | "outputs": [], 73 | "source": [ 74 | "A = [[2,7], [3,4], [6,1]]\n", 75 | "B = [[1,4], [4,-1], [2,5]]" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 13, 81 | "metadata": {}, 82 | "outputs": [ 83 | { 84 | "data": { 85 | "text/plain": [ 86 | "[[3, 11], [7, 3], [8, 6]]" 87 | ] 88 | }, 89 | "execution_count": 13, 90 | "metadata": {}, 91 | "output_type": "execute_result" 92 | } 93 | ], 94 | "source": [ 95 | "add(A,B)" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 14, 101 | "metadata": {}, 102 | "outputs": [], 103 | "source": [ 104 | "# 행렬의 뺄셈\n", 105 | "A = [[2,7], [3,4], [6,1]]\n", 106 | "B = [[1,4], [4,-1], [2,5]]\n", 107 | "\n", 108 | "n = len(A)\n", 109 | "p = len(A[0])\n", 110 | "\n", 111 | "res = []\n", 112 | "for i in range(0, n):\n", 113 | " row = []\n", 114 | " for j in range(0, p):\n", 115 | " val = A[i][j] - B[i][j]\n", 116 | " row.append(val)\n", 117 | " res.append(row)" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 15, 123 | "metadata": {}, 124 | "outputs": [ 125 | { 126 | "name": "stdout", 127 | "output_type": "stream", 128 | "text": [ 129 | "[[1, 3], [-1, 5], [4, -4]]\n" 130 | ] 131 | } 132 | ], 133 | "source": [ 134 | "print(res)" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": 19, 140 | "metadata": {}, 141 | "outputs": [], 142 | "source": [ 143 | "def subtract(A, B):\n", 144 | " \"\"\"\n", 145 | " 행렬의 뺄셈\n", 146 | " 입력값: 행렬의 뺄셈을 수행할 행렬 A, B\n", 147 | " 출력값: 행렬 A와 행렬 B의 뺄셈 결과인 행렬 res\n", 148 | " \"\"\"\n", 149 | " n = len(A)\n", 150 | " p = len(A[0])\n", 151 | "\n", 152 | " res = []\n", 153 | " for i in range(0, n):\n", 154 | " row = []\n", 155 | " for j in range(0, p):\n", 156 | " val = A[i][j] - B[i][j]\n", 157 | " row.append(val)\n", 158 | " res.append(row)\n", 159 | " return res" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 20, 165 | "metadata": {}, 166 | "outputs": [ 167 | { 168 | "data": { 169 | "text/plain": [ 170 | "[[1, 3], [-1, 5], [4, -4]]" 171 | ] 172 | }, 173 | "execution_count": 20, 174 | "metadata": {}, 175 | "output_type": "execute_result" 176 | } 177 | ], 178 | "source": [ 179 | "A = [[2,7], [3,4], [6,1]]\n", 180 | "B = [[1,4], [4,-1], [2,5]]\n", 181 | "subtract(A, B)" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 21, 187 | "metadata": {}, 188 | "outputs": [], 189 | "source": [ 190 | "# 행렬의 스칼라곱\n", 191 | "A = [[2,7], [3,4], [6,1]]\n", 192 | "b = 2\n", 193 | "\n", 194 | "n = len(A)\n", 195 | "p = len(A[0])\n", 196 | "\n", 197 | "res = []\n", 198 | "for i in range(0, n):\n", 199 | " row = []\n", 200 | " for j in range(0, p):\n", 201 | " val = b * A[i][j]\n", 202 | " row.append(val)\n", 203 | " res.append(row)" 204 | ] 205 | }, 206 | { 207 | "cell_type": "code", 208 | "execution_count": 23, 209 | "metadata": {}, 210 | "outputs": [ 211 | { 212 | "name": "stdout", 213 | "output_type": "stream", 214 | "text": [ 215 | "[[4, 14], [6, 8], [12, 2]]\n" 216 | ] 217 | } 218 | ], 219 | "source": [ 220 | "print(res)" 221 | ] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "execution_count": 1, 226 | "metadata": {}, 227 | "outputs": [], 228 | "source": [ 229 | "def scalar_mul(b, A):\n", 230 | " \"\"\"\n", 231 | " 행렬의 스칼라곱\n", 232 | " 입력값: 스칼라곱을 수행할 스칼라 b, 행렬 A\n", 233 | " 출력값: 스칼라 b와 행렬 A의 스칼라 곱 결과인 행렬 res\n", 234 | " \"\"\"\n", 235 | "\n", 236 | " n = len(A)\n", 237 | " p = len(A[0])\n", 238 | " \n", 239 | " res = []\n", 240 | " for i in range(0, n):\n", 241 | " row = []\n", 242 | " for j in range(0, p):\n", 243 | " val = b * A[i][j]\n", 244 | " row.append(val)\n", 245 | " res.append(row)\n", 246 | " return res" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": 2, 252 | "metadata": {}, 253 | "outputs": [ 254 | { 255 | "data": { 256 | "text/plain": [ 257 | "[[4, 14], [6, 8], [12, 2]]" 258 | ] 259 | }, 260 | "execution_count": 2, 261 | "metadata": {}, 262 | "output_type": "execute_result" 263 | } 264 | ], 265 | "source": [ 266 | "A = [[2,7], [3,4], [6,1]]\n", 267 | "b = 2\n", 268 | "scalar_mul(b, A)" 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": 26, 274 | "metadata": {}, 275 | "outputs": [], 276 | "source": [ 277 | "# 행렬의 원소곱\n", 278 | "A = [[1,5], [6,4], [2,7]]\n", 279 | "B = [[5,-1], [1,2], [4,1]]\n", 280 | "\n", 281 | "n = len(A)\n", 282 | "p = len(A[0])\n", 283 | "\n", 284 | "res = []\n", 285 | "for i in range(0, n):\n", 286 | " row = []\n", 287 | " for j in range(0, p):\n", 288 | " val = A[i][j] * B[i][j]\n", 289 | " row.append(val)\n", 290 | " res.append(row)" 291 | ] 292 | }, 293 | { 294 | "cell_type": "code", 295 | "execution_count": 27, 296 | "metadata": {}, 297 | "outputs": [ 298 | { 299 | "name": "stdout", 300 | "output_type": "stream", 301 | "text": [ 302 | "[[5, -5], [6, 8], [8, 7]]\n" 303 | ] 304 | } 305 | ], 306 | "source": [ 307 | "print(res)" 308 | ] 309 | }, 310 | { 311 | "cell_type": "code", 312 | "execution_count": 30, 313 | "metadata": {}, 314 | "outputs": [], 315 | "source": [ 316 | "def ele_product(A,B):\n", 317 | " \"\"\"\n", 318 | " 행렬의 원소곱\n", 319 | " 입력값: 행렬의 원소곱을 수행할 행렬 A, B\n", 320 | " 출력값: 행렬 A와 행렬 B의 원소곱 결과인 행렬 res\n", 321 | " \"\"\"\n", 322 | " n = len(A)\n", 323 | " p = len(A[0])\n", 324 | "\n", 325 | " res = []\n", 326 | " for i in range(0, n):\n", 327 | " row = []\n", 328 | " for j in range(0, p):\n", 329 | " val = A[i][j] * B[i][j]\n", 330 | " row.append(val)\n", 331 | " res.append(row)\n", 332 | " return res" 333 | ] 334 | }, 335 | { 336 | "cell_type": "code", 337 | "execution_count": 31, 338 | "metadata": {}, 339 | "outputs": [ 340 | { 341 | "data": { 342 | "text/plain": [ 343 | "[[5, -5], [6, 8], [8, 7]]" 344 | ] 345 | }, 346 | "execution_count": 31, 347 | "metadata": {}, 348 | "output_type": "execute_result" 349 | } 350 | ], 351 | "source": [ 352 | "A = [[1,5], [6,4], [2,7]]\n", 353 | "B = [[5,-1], [1,2], [4,1]]\n", 354 | "ele_product(A,B)" 355 | ] 356 | }, 357 | { 358 | "cell_type": "code", 359 | "execution_count": 36, 360 | "metadata": {}, 361 | "outputs": [], 362 | "source": [ 363 | "# 행렬곱\n", 364 | "A = [[2,7], [3,4], [5,2]]\n", 365 | "B = [[3,-3,5], [-1,2,-1]]\n", 366 | "\n", 367 | "n = len(A)\n", 368 | "p1 = len(A[0])\n", 369 | "p2 = len(B[0])\n", 370 | "\n", 371 | "res = []\n", 372 | "for i in range(0, n):\n", 373 | " row = []\n", 374 | " for j in range(0, p2):\n", 375 | " val = 0\n", 376 | " for k in range(0, p1):\n", 377 | " val += A[i][k] * B[k][j] \n", 378 | " row.append(val) \n", 379 | " res.append(row)" 380 | ] 381 | }, 382 | { 383 | "cell_type": "code", 384 | "execution_count": 37, 385 | "metadata": {}, 386 | "outputs": [ 387 | { 388 | "name": "stdout", 389 | "output_type": "stream", 390 | "text": [ 391 | "[[-1, 8, 3], [5, -1, 11], [13, -11, 23]]\n" 392 | ] 393 | } 394 | ], 395 | "source": [ 396 | "print(res)" 397 | ] 398 | }, 399 | { 400 | "cell_type": "code", 401 | "execution_count": 40, 402 | "metadata": {}, 403 | "outputs": [], 404 | "source": [ 405 | "def matmul(A, B): \n", 406 | " \"\"\"\n", 407 | " 행렬의 행렬곱\n", 408 | " 입력값: 행렬곱을 수행할 행렬 A, B\n", 409 | " 출력값: 행렬 A와 행렬 B의 행렬곱 결과인 행렬 res\n", 410 | " \"\"\"\n", 411 | " n = len(A)\n", 412 | " p1 = len(A[0])\n", 413 | " p2 = len(B[0])\n", 414 | "\n", 415 | " res = []\n", 416 | " for i in range(0, n):\n", 417 | " row = []\n", 418 | " for j in range(0, p2):\n", 419 | " val = 0\n", 420 | " for k in range(0, p1):\n", 421 | " val += A[i][k] * B[k][j] \n", 422 | " row.append(val) \n", 423 | " res.append(row)\n", 424 | " return res" 425 | ] 426 | }, 427 | { 428 | "cell_type": "code", 429 | "execution_count": 41, 430 | "metadata": {}, 431 | "outputs": [ 432 | { 433 | "data": { 434 | "text/plain": [ 435 | "[[-1, 8, 3], [5, -1, 11], [13, -11, 23]]" 436 | ] 437 | }, 438 | "execution_count": 41, 439 | "metadata": {}, 440 | "output_type": "execute_result" 441 | } 442 | ], 443 | "source": [ 444 | "A = [[2,7], [3,4], [5,2]]\n", 445 | "B = [[3,-3,5], [-1,2,-1]]\n", 446 | "matmul(A, B)" 447 | ] 448 | }, 449 | { 450 | "cell_type": "code", 451 | "execution_count": null, 452 | "metadata": {}, 453 | "outputs": [], 454 | "source": [] 455 | } 456 | ], 457 | "metadata": { 458 | "kernelspec": { 459 | "display_name": "Python 3", 460 | "language": "python", 461 | "name": "python3" 462 | }, 463 | "language_info": { 464 | "codemirror_mode": { 465 | "name": "ipython", 466 | "version": 3 467 | }, 468 | "file_extension": ".py", 469 | "mimetype": "text/x-python", 470 | "name": "python", 471 | "nbconvert_exporter": "python", 472 | "pygments_lexer": "ipython3", 473 | "version": "3.8.5" 474 | } 475 | }, 476 | "nbformat": 4, 477 | "nbformat_minor": 4 478 | } 479 | -------------------------------------------------------------------------------- /code/ch03-3-2.넘파이 행렬 연산.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import numpy as np" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 2, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "[[ 3 11]\n", 22 | " [ 7 3]\n", 23 | " [ 8 6]]\n" 24 | ] 25 | } 26 | ], 27 | "source": [ 28 | "# 행렬의 덧셈\n", 29 | "A = np.array([[2,7], [3,4], [6,1]])\n", 30 | "B = np.array([[1,4], [4,-1], [2,5]])\n", 31 | "C = A + B\n", 32 | "print(C)" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 3, 38 | "metadata": {}, 39 | "outputs": [ 40 | { 41 | "name": "stdout", 42 | "output_type": "stream", 43 | "text": [ 44 | "[[ 1 3]\n", 45 | " [-1 5]\n", 46 | " [ 4 -4]]\n" 47 | ] 48 | } 49 | ], 50 | "source": [ 51 | "# 행렬의 뺄셈\n", 52 | "A = np.array([[2,7], [3,4], [6,1]])\n", 53 | "B = np.array([[1,4], [4,-1], [2,5]])\n", 54 | "C = A - B\n", 55 | "print(C)" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 4, 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "name": "stdout", 65 | "output_type": "stream", 66 | "text": [ 67 | "[[ 4 14]\n", 68 | " [ 6 8]\n", 69 | " [12 2]]\n" 70 | ] 71 | } 72 | ], 73 | "source": [ 74 | "# 행렬의 스칼라곱\n", 75 | "A = np.array([[2,7], [3,4], [6,1]])\n", 76 | "b = 2\n", 77 | "C = b*A \n", 78 | "print(C)" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 12, 84 | "metadata": {}, 85 | "outputs": [ 86 | { 87 | "name": "stdout", 88 | "output_type": "stream", 89 | "text": [ 90 | "[[ 5 -5]\n", 91 | " [ 6 8]\n", 92 | " [ 8 7]]\n" 93 | ] 94 | } 95 | ], 96 | "source": [ 97 | "# 행렬의 원소곱\n", 98 | "A = np.array([[1,5], [6,4], [2,7]])\n", 99 | "B = np.array([[5,-1], [1,2], [4,1]])\n", 100 | "C = np.multiply(A, B)\n", 101 | "print(C)" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 15, 107 | "metadata": {}, 108 | "outputs": [ 109 | { 110 | "name": "stdout", 111 | "output_type": "stream", 112 | "text": [ 113 | "[[ -1 8 3]\n", 114 | " [ 5 -1 11]\n", 115 | " [ 13 -11 23]]\n" 116 | ] 117 | } 118 | ], 119 | "source": [ 120 | "# 행렬 곱\n", 121 | "A = np.array([[2,7], [3,4], [5,2]])\n", 122 | "B = np.array([[3,-3,5], [-1,2,-1]])\n", 123 | "C = np.matmul(A, B)\n", 124 | "print(C)" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": null, 130 | "metadata": {}, 131 | "outputs": [], 132 | "source": [] 133 | } 134 | ], 135 | "metadata": { 136 | "kernelspec": { 137 | "display_name": "Python 3", 138 | "language": "python", 139 | "name": "python3" 140 | }, 141 | "language_info": { 142 | "codemirror_mode": { 143 | "name": "ipython", 144 | "version": 3 145 | }, 146 | "file_extension": ".py", 147 | "mimetype": "text/x-python", 148 | "name": "python", 149 | "nbconvert_exporter": "python", 150 | "pygments_lexer": "ipython3", 151 | "version": "3.8.5" 152 | } 153 | }, 154 | "nbformat": 4, 155 | "nbformat_minor": 4 156 | } 157 | -------------------------------------------------------------------------------- /code/ch05-5.넘파이 방정식.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 넘파이를 이용해 방정식 풀기" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import numpy as np" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 6, 22 | "metadata": {}, 23 | "outputs": [ 24 | { 25 | "name": "stdout", 26 | "output_type": "stream", 27 | "text": [ 28 | "[[1.]\n", 29 | " [0.]\n", 30 | " [1.]]\n" 31 | ] 32 | } 33 | ], 34 | "source": [ 35 | "X = np.array([[3, 1, 2],[2, 6, -1],[4, 0, -1]])\n", 36 | "y = np.array([[5],[1],[3]])\n", 37 | " \n", 38 | "sol = np.linalg.solve(X, y)\n", 39 | " \n", 40 | "print(sol)" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": null, 53 | "metadata": {}, 54 | "outputs": [], 55 | "source": [] 56 | } 57 | ], 58 | "metadata": { 59 | "kernelspec": { 60 | "display_name": "Python 3", 61 | "language": "python", 62 | "name": "python3" 63 | }, 64 | "language_info": { 65 | "codemirror_mode": { 66 | "name": "ipython", 67 | "version": 3 68 | }, 69 | "file_extension": ".py", 70 | "mimetype": "text/x-python", 71 | "name": "python", 72 | "nbconvert_exporter": "python", 73 | "pygments_lexer": "ipython3", 74 | "version": "3.8.5" 75 | } 76 | }, 77 | "nbformat": 4, 78 | "nbformat_minor": 4 79 | } 80 | -------------------------------------------------------------------------------- /code/ch06-4.파이썬 행렬식 연산.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 개별 코드" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "A = [[3,2,0], [-1,-3,6], [2,3,-5]]" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 2, 22 | "metadata": {}, 23 | "outputs": [ 24 | { 25 | "name": "stdout", 26 | "output_type": "stream", 27 | "text": [ 28 | "[[-3, 6], [3, -5]]\n", 29 | "-3\n", 30 | "-9\n", 31 | "[[-1, 6], [2, -5]]\n", 32 | "-7\n", 33 | "5\n", 34 | "[[-1, -3], [2, 3]]\n", 35 | "3\n", 36 | "5\n" 37 | ] 38 | } 39 | ], 40 | "source": [ 41 | "n = len(A)\n", 42 | "p = len(A[0])\n", 43 | "\n", 44 | "detA = 0\n", 45 | "for j in range(0, p): \n", 46 | " M = [A[1][:j]+A[1][j+1:], A[2][:j]+A[2][j+1:]] \n", 47 | " print(M)\n", 48 | " Mij = M[0][0]*M[1][1] - M[0][1]*M[1][0] \n", 49 | " print(Mij)\n", 50 | " Cij = ((-1)**(0+j))*Mij\n", 51 | " detA += A[0][j]*Cij\n", 52 | " print(detA)" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 3, 58 | "metadata": {}, 59 | "outputs": [ 60 | { 61 | "data": { 62 | "text/plain": [ 63 | "[[-3, 6], [3, -5]]" 64 | ] 65 | }, 66 | "execution_count": 3, 67 | "metadata": {}, 68 | "output_type": "execute_result" 69 | } 70 | ], 71 | "source": [ 72 | "[A[1][:0]+A[1][1:], A[2][:0]+A[2][1:]] " 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": 4, 78 | "metadata": {}, 79 | "outputs": [ 80 | { 81 | "data": { 82 | "text/plain": [ 83 | "[[-1, 6], [2, -5]]" 84 | ] 85 | }, 86 | "execution_count": 4, 87 | "metadata": {}, 88 | "output_type": "execute_result" 89 | } 90 | ], 91 | "source": [ 92 | "[A[1][:1]+A[1][2:], A[2][:1]+A[2][2:]] " 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": 5, 98 | "metadata": {}, 99 | "outputs": [ 100 | { 101 | "data": { 102 | "text/plain": [ 103 | "[[-1, -3], [2, 3]]" 104 | ] 105 | }, 106 | "execution_count": 5, 107 | "metadata": {}, 108 | "output_type": "execute_result" 109 | } 110 | ], 111 | "source": [ 112 | "[A[1][:2]+A[1][3:], A[2][:2]+A[2][3:]] " 113 | ] 114 | }, 115 | { 116 | "cell_type": "markdown", 117 | "metadata": {}, 118 | "source": [ 119 | "# 전체 코드" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 6, 125 | "metadata": {}, 126 | "outputs": [ 127 | { 128 | "name": "stdout", 129 | "output_type": "stream", 130 | "text": [ 131 | "5\n" 132 | ] 133 | } 134 | ], 135 | "source": [ 136 | "A = [[3,2,0], [-1,-3,6], [2,3,-5]]\n", 137 | "\n", 138 | "n = len(A)\n", 139 | "p = len(A[0])\n", 140 | "\n", 141 | "\n", 142 | "detA = 0\n", 143 | "for j in range(0, p): \n", 144 | " M = [A[1][:j]+A[1][j+1:], A[2][:j]+A[2][j+1:]] \n", 145 | " Mij = M[0][0]*M[1][1] - M[0][1]*M[1][0] \n", 146 | " Cij = ((-1)**(0+j))*Mij\n", 147 | " detA += A[0][j]*Cij\n", 148 | "\n", 149 | "print(detA)" 150 | ] 151 | }, 152 | { 153 | "cell_type": "markdown", 154 | "metadata": {}, 155 | "source": [ 156 | "# 행렬식(재귀)" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": 7, 162 | "metadata": {}, 163 | "outputs": [], 164 | "source": [ 165 | "def det_rec(A):\n", 166 | " \n", 167 | " \"\"\"\n", 168 | " 행렬 A의 행렬식 구하기(재귀 방식을 이용)\n", 169 | " 입력값: 행렬식을 구하고자 하는 행렬 A\n", 170 | " 출력값: 행렬 A의 행렬식 res\n", 171 | " \"\"\"\n", 172 | " \n", 173 | " import copy\n", 174 | " \n", 175 | " n = len(A)\n", 176 | " p = len(A[0])\n", 177 | " res = 0\n", 178 | "\n", 179 | " # 2x2 행렬의 행렬식 구하기\n", 180 | " if n == 2 and p == 2:\n", 181 | " tmp_det = A[0][0] * A[1][1] - A[1][0] * A[0][1]\n", 182 | " return tmp_det\n", 183 | "\n", 184 | " # nxn 행렬의 행렬식 구하기\n", 185 | " for i in range(0,n): \n", 186 | " A1 = copy.deepcopy(A) \n", 187 | " A1 = A1[1:] \n", 188 | " n1 = len(A1)\n", 189 | "\n", 190 | " for j in range(0,n1): \n", 191 | " A1[j] = A1[j][0:i] + A1[j][i+1:] \n", 192 | "\n", 193 | " sign = (-1) ** (i % 2) \n", 194 | " sub_det = det_rec(A1) \n", 195 | " res += sign * A[0][i] * sub_det \n", 196 | "\n", 197 | " return res" 198 | ] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "metadata": {}, 203 | "source": [ 204 | "# copy 라이브러리 안쓴 버전" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": 7, 210 | "metadata": {}, 211 | "outputs": [], 212 | "source": [ 213 | "def zero_mat(n, p):\n", 214 | " \"\"\"\n", 215 | " 영 행렬 생성\n", 216 | " 입력값: 생성하고자 할 영 행렬의 크기 n행, p열\n", 217 | " 출력값: nxp 영 행렬 Z\n", 218 | " \"\"\"\n", 219 | " Z = []\n", 220 | " for i in range(0, n):\n", 221 | " row = []\n", 222 | " for j in range(0, p):\n", 223 | " row.append(0)\n", 224 | " Z.append(row)\n", 225 | " return Z\n", 226 | "\n", 227 | "\n", 228 | "\n", 229 | "def deepcopy(A):\n", 230 | " \"\"\"\n", 231 | " 깊은 복사(deepcopy) 구현\n", 232 | " 입력값: 깊은 복사를 하고자 하는 행렬 리스트 A\n", 233 | " 출력값: 깊은 복사 된 결과 행렬 리스트 res \n", 234 | " \"\"\"\n", 235 | " if type(A[0]) == list:\n", 236 | " n = len(A)\n", 237 | " p = len(A[0])\n", 238 | " res = zero_mat(n,p)\n", 239 | " for i in range(0,n):\n", 240 | " for j in range(0,p):\n", 241 | " res[i][j] = A[i][j]\n", 242 | " return res\n", 243 | " else:\n", 244 | " n = len(A)\n", 245 | " res = []\n", 246 | " for i in range(0,n):\n", 247 | " res.append(A[i])\n", 248 | " return res\n", 249 | " \n", 250 | "\n", 251 | "def det_rec(A):\n", 252 | " \n", 253 | " \"\"\"\n", 254 | " 행렬 A의 행렬식 구하기(재귀 방식을 이용)\n", 255 | " 입력값: 행렬식을 구하고자 하는 행렬 A\n", 256 | " 출력값: 행렬 A의 행렬식 res\n", 257 | " \"\"\"\n", 258 | " \n", 259 | " n = len(A)\n", 260 | " res = 0\n", 261 | "\n", 262 | " # 2x2 행렬의 행렬식 구하기\n", 263 | " if n == 2:\n", 264 | " res = A[0][0] * A[1][1] - A[1][0] * A[0][1]\n", 265 | " return res\n", 266 | "\n", 267 | " # nxn 행렬의 행렬식 구하기\n", 268 | " for i in range(0,n): \n", 269 | " X = deepcopy(A) \n", 270 | " X = X[1:] \n", 271 | " nx = len(X)\n", 272 | "\n", 273 | " for j in range(0,nx): \n", 274 | " X[j] = X[j][0:i] + X[j][i+1:] \n", 275 | "\n", 276 | " sign = (-1) ** (i % 2) \n", 277 | " sub_det = det_rec(X) \n", 278 | " res += sign * A[0][i] * sub_det \n", 279 | "\n", 280 | " return res" 281 | ] 282 | }, 283 | { 284 | "cell_type": "code", 285 | "execution_count": 9, 286 | "metadata": {}, 287 | "outputs": [ 288 | { 289 | "data": { 290 | "text/plain": [ 291 | "-4" 292 | ] 293 | }, 294 | "execution_count": 9, 295 | "metadata": {}, 296 | "output_type": "execute_result" 297 | } 298 | ], 299 | "source": [ 300 | "A = [[1,3,1,4], [3,9,5,15], [0,2,1,1],[0,4,2,3]]\n", 301 | "det_rec(A)" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": 10, 307 | "metadata": {}, 308 | "outputs": [ 309 | { 310 | "data": { 311 | "text/plain": [ 312 | "9" 313 | ] 314 | }, 315 | "execution_count": 10, 316 | "metadata": {}, 317 | "output_type": "execute_result" 318 | } 319 | ], 320 | "source": [ 321 | "B = [[6,3],[5,4]]\n", 322 | "det_rec(B)" 323 | ] 324 | }, 325 | { 326 | "cell_type": "markdown", 327 | "metadata": {}, 328 | "source": [ 329 | "# 상 삼각 행렬 변환을 통해 행렬식 구하기" 330 | ] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": 11, 335 | "metadata": {}, 336 | "outputs": [], 337 | "source": [ 338 | "def det_tri(A):\n", 339 | " \n", 340 | " import copy\n", 341 | " \n", 342 | " n = len(A)\n", 343 | " A1 = copy.deepcopy(A)\n", 344 | " \n", 345 | " for i in range(0,n): \n", 346 | " for j in range(i+1,n): \n", 347 | " if A1[i][i] == 0: \n", 348 | " A1[i][i] == 1.0e-18 \n", 349 | " ratio = A1[j][i] / A1[i][i] \n", 350 | " for k in range(0, n): \n", 351 | " A1[j][k] = A1[j][k] - ratio * A1[i][k]\n", 352 | " \n", 353 | " product = 1\n", 354 | " for i in range(n):\n", 355 | " product *= A1[i][i] \n", 356 | " \n", 357 | " return product" 358 | ] 359 | }, 360 | { 361 | "cell_type": "markdown", 362 | "metadata": {}, 363 | "source": [ 364 | "# copy 라이브러리 안쓰고" 365 | ] 366 | }, 367 | { 368 | "cell_type": "code", 369 | "execution_count": 10, 370 | "metadata": {}, 371 | "outputs": [], 372 | "source": [ 373 | "def det_tri(A):\n", 374 | " \"\"\"\n", 375 | " 상 삼각 행렬 변환을 이용해 행렬식 구하기\n", 376 | " 입력값: 행렬 A\n", 377 | " 출력값: 행렬식 res\n", 378 | " \"\"\"\n", 379 | " n = len(A)\n", 380 | " X = deepcopy(A)\n", 381 | " n_row_change = 0\n", 382 | " \n", 383 | " for i in range(0,n): \n", 384 | " if X[i][i] == 0:\n", 385 | " tmp = X[i+1]\n", 386 | " X[i+1] = X[i]\n", 387 | " X[i] = tmp\n", 388 | " n_row_change += 1\n", 389 | " for j in range(i+1,n):\n", 390 | " ratio = X[j][i] / X[i][i] \n", 391 | " for k in range(0, n):\n", 392 | " X[j][k] = X[j][k] - ratio * X[i][k]\n", 393 | " \n", 394 | " n_row_change = (-1)**(n_row_change) \n", 395 | " res = 1\n", 396 | " for i in range(n):\n", 397 | " res *= X[i][i] \n", 398 | " res *= n_row_change \n", 399 | " return res" 400 | ] 401 | }, 402 | { 403 | "cell_type": "code", 404 | "execution_count": 11, 405 | "metadata": {}, 406 | "outputs": [ 407 | { 408 | "data": { 409 | "text/plain": [ 410 | "-4.0" 411 | ] 412 | }, 413 | "execution_count": 11, 414 | "metadata": {}, 415 | "output_type": "execute_result" 416 | } 417 | ], 418 | "source": [ 419 | "A = [[1,3,1,4],[3,9,5,15],[0,2,1,1],[0,4,2,3]]\n", 420 | "det_tri(A)" 421 | ] 422 | }, 423 | { 424 | "cell_type": "code", 425 | "execution_count": 12, 426 | "metadata": {}, 427 | "outputs": [ 428 | { 429 | "data": { 430 | "text/plain": [ 431 | "9.0" 432 | ] 433 | }, 434 | "execution_count": 12, 435 | "metadata": {}, 436 | "output_type": "execute_result" 437 | } 438 | ], 439 | "source": [ 440 | "B = [[6,3],[5,4]]\n", 441 | "det_tri(B)" 442 | ] 443 | }, 444 | { 445 | "cell_type": "code", 446 | "execution_count": null, 447 | "metadata": {}, 448 | "outputs": [], 449 | "source": [] 450 | } 451 | ], 452 | "metadata": { 453 | "kernelspec": { 454 | "display_name": "Python 3", 455 | "language": "python", 456 | "name": "python3" 457 | }, 458 | "language_info": { 459 | "codemirror_mode": { 460 | "name": "ipython", 461 | "version": 3 462 | }, 463 | "file_extension": ".py", 464 | "mimetype": "text/x-python", 465 | "name": "python", 466 | "nbconvert_exporter": "python", 467 | "pygments_lexer": "ipython3", 468 | "version": "3.8.5" 469 | } 470 | }, 471 | "nbformat": 4, 472 | "nbformat_minor": 4 473 | } 474 | -------------------------------------------------------------------------------- /code/ch06-5.넘파이 행렬식 연산.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 넘파이 행렬식 계산" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import numpy as np" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 29, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "A = np.array([[3,2,0], [-1,-3,6], [2,3,-5]])" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 30, 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "detA = np.linalg.det(A)" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 31, 40 | "metadata": {}, 41 | "outputs": [ 42 | { 43 | "name": "stdout", 44 | "output_type": "stream", 45 | "text": [ 46 | "5.000000000000002\n" 47 | ] 48 | } 49 | ], 50 | "source": [ 51 | "print(detA)" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": null, 57 | "metadata": {}, 58 | "outputs": [], 59 | "source": [] 60 | } 61 | ], 62 | "metadata": { 63 | "kernelspec": { 64 | "display_name": "Python 3", 65 | "language": "python", 66 | "name": "python3" 67 | }, 68 | "language_info": { 69 | "codemirror_mode": { 70 | "name": "ipython", 71 | "version": 3 72 | }, 73 | "file_extension": ".py", 74 | "mimetype": "text/x-python", 75 | "name": "python", 76 | "nbconvert_exporter": "python", 77 | "pygments_lexer": "ipython3", 78 | "version": "3.8.5" 79 | } 80 | }, 81 | "nbformat": 4, 82 | "nbformat_minor": 4 83 | } 84 | -------------------------------------------------------------------------------- /code/ch07-3.파이썬 역행렬 연산.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 행렬식 구하기" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 18, 13 | "metadata": {}, 14 | "outputs": [ 15 | { 16 | "name": "stdout", 17 | "output_type": "stream", 18 | "text": [ 19 | "5\n" 20 | ] 21 | } 22 | ], 23 | "source": [ 24 | "A = [[3,2,0], [-1,-3,6], [2,3,-5]]\n", 25 | "\n", 26 | "n = len(A)\n", 27 | "p = len(A[0])\n", 28 | "\n", 29 | "detA = 0\n", 30 | "for j in range(0, p): \n", 31 | " M = [A[1][:j]+A[1][j+1:], A[2][:j]+A[2][j+1:]] \n", 32 | " Mij = M[0][0]*M[1][1] - M[0][1]*M[1][0] \n", 33 | " Cij = ((-1)**(0+j))*Mij\n", 34 | " detA += A[0][j]*Cij\n", 35 | "\n", 36 | "print(detA)" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "# 여인수행렬 구하기" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 19, 49 | "metadata": {}, 50 | "outputs": [ 51 | { 52 | "data": { 53 | "text/plain": [ 54 | "[[-3, 6], [3, -5]]" 55 | ] 56 | }, 57 | "execution_count": 19, 58 | "metadata": {}, 59 | "output_type": "execute_result" 60 | } 61 | ], 62 | "source": [ 63 | "# 1행 1열\n", 64 | "[A[1][:0]+A[1][0+1:], A[2][:0]+A[2][0+1:]] " 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 20, 70 | "metadata": {}, 71 | "outputs": [ 72 | { 73 | "data": { 74 | "text/plain": [ 75 | "[[-1, 6], [2, -5]]" 76 | ] 77 | }, 78 | "execution_count": 20, 79 | "metadata": {}, 80 | "output_type": "execute_result" 81 | } 82 | ], 83 | "source": [ 84 | "# 1행 2열\n", 85 | "[A[1][:1]+A[1][1+1:], A[2][:1]+A[2][1+1:]] " 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 21, 91 | "metadata": {}, 92 | "outputs": [ 93 | { 94 | "data": { 95 | "text/plain": [ 96 | "[[-1, -3], [2, 3]]" 97 | ] 98 | }, 99 | "execution_count": 21, 100 | "metadata": {}, 101 | "output_type": "execute_result" 102 | } 103 | ], 104 | "source": [ 105 | "# 1행 3열\n", 106 | "[A[1][:2]+A[1][2+1:], A[2][:2]+A[2][2+1:]] " 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 22, 112 | "metadata": {}, 113 | "outputs": [ 114 | { 115 | "data": { 116 | "text/plain": [ 117 | "[[2, 0], [3, -5]]" 118 | ] 119 | }, 120 | "execution_count": 22, 121 | "metadata": {}, 122 | "output_type": "execute_result" 123 | } 124 | ], 125 | "source": [ 126 | "# 2행 1열\n", 127 | "[A[0][:0]+A[0][0+1:], A[2][:0]+A[2][0+1:]] " 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": 23, 133 | "metadata": {}, 134 | "outputs": [ 135 | { 136 | "data": { 137 | "text/plain": [ 138 | "[[3, 0], [2, -5]]" 139 | ] 140 | }, 141 | "execution_count": 23, 142 | "metadata": {}, 143 | "output_type": "execute_result" 144 | } 145 | ], 146 | "source": [ 147 | "# 2행 2열\n", 148 | "[A[0][:1]+A[0][1+1:], A[2][:1]+A[2][1+1:]] " 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": 24, 154 | "metadata": {}, 155 | "outputs": [ 156 | { 157 | "data": { 158 | "text/plain": [ 159 | "[[3, 2], [2, 3]]" 160 | ] 161 | }, 162 | "execution_count": 24, 163 | "metadata": {}, 164 | "output_type": "execute_result" 165 | } 166 | ], 167 | "source": [ 168 | "# 2행 3열\n", 169 | "[A[0][:2]+A[0][2+1:], A[2][:2]+A[2][2+1:]] " 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": 25, 175 | "metadata": {}, 176 | "outputs": [ 177 | { 178 | "data": { 179 | "text/plain": [ 180 | "[[2, 0], [-3, 6]]" 181 | ] 182 | }, 183 | "execution_count": 25, 184 | "metadata": {}, 185 | "output_type": "execute_result" 186 | } 187 | ], 188 | "source": [ 189 | "# 3행 1열\n", 190 | "[A[0][:0]+A[0][0+1:], A[1][:0]+A[1][0+1:]] " 191 | ] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "execution_count": 26, 196 | "metadata": {}, 197 | "outputs": [ 198 | { 199 | "data": { 200 | "text/plain": [ 201 | "[[3, 0], [-1, 6]]" 202 | ] 203 | }, 204 | "execution_count": 26, 205 | "metadata": {}, 206 | "output_type": "execute_result" 207 | } 208 | ], 209 | "source": [ 210 | "# 3행 2열\n", 211 | "[A[0][:1]+A[0][1+1:], A[1][:1]+A[1][1+1:]] " 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": 27, 217 | "metadata": {}, 218 | "outputs": [ 219 | { 220 | "data": { 221 | "text/plain": [ 222 | "[[3, 2], [-1, -3]]" 223 | ] 224 | }, 225 | "execution_count": 27, 226 | "metadata": {}, 227 | "output_type": "execute_result" 228 | } 229 | ], 230 | "source": [ 231 | "# 3행 3열\n", 232 | "[A[0][:2]+A[0][2+1:], A[1][:2]+A[1][2+1:]] " 233 | ] 234 | }, 235 | { 236 | "cell_type": "code", 237 | "execution_count": 28, 238 | "metadata": {}, 239 | "outputs": [], 240 | "source": [ 241 | "def zero_mat(n, p):\n", 242 | " \"\"\"\n", 243 | " 영 행렬 생성\n", 244 | " 입력값: 생성하고자 할 영 행렬의 크기 n행, p열\n", 245 | " 출력값: nxp 영 행렬 Z\n", 246 | " \"\"\"\n", 247 | " Z = []\n", 248 | " for i in range(0, n):\n", 249 | " row = []\n", 250 | " for j in range(0, p):\n", 251 | " row.append(0)\n", 252 | " Z.append(row)\n", 253 | " return Z\n", 254 | "\n", 255 | "\n", 256 | "def deepcopy(A):\n", 257 | " \"\"\"\n", 258 | " 깊은 복사(deepcopy) 구현\n", 259 | " 입력값: 깊은 복사를 하고자 하는 행렬 리스트 A\n", 260 | " 출력값: 깊은 복사 된 결과 행렬 리스트 res \n", 261 | " \"\"\"\n", 262 | " if type(A[0]) == list:\n", 263 | " n = len(A)\n", 264 | " p = len(A[0])\n", 265 | " res = zero_mat(n,p)\n", 266 | " for i in range(0,n):\n", 267 | " for j in range(0,p):\n", 268 | " res[i][j] = A[i][j]\n", 269 | " return res\n", 270 | " else:\n", 271 | " n = len(A)\n", 272 | " res = []\n", 273 | " for i in range(0,n):\n", 274 | " res.append(A[i])\n", 275 | " return res\n", 276 | "\n", 277 | "def det_rec(A):\n", 278 | " \n", 279 | " \"\"\"\n", 280 | " 행렬 A의 행렬식 구하기(재귀 방식을 이용)\n", 281 | " 입력값: 행렬식을 구하고자 하는 행렬 A\n", 282 | " 출력값: 행렬 A의 행렬식 res\n", 283 | " \"\"\"\n", 284 | " \n", 285 | " n = len(A)\n", 286 | " res = 0\n", 287 | "\n", 288 | " # 2x2 행렬의 행렬식 구하기\n", 289 | " if n == 2:\n", 290 | " res = A[0][0] * A[1][1] - A[1][0] * A[0][1]\n", 291 | " return res\n", 292 | "\n", 293 | " # nxn 행렬의 행렬식 구하기\n", 294 | " for i in range(0,n): \n", 295 | " X = deepcopy(A) \n", 296 | " X = X[1:] \n", 297 | " nx = len(X)\n", 298 | "\n", 299 | " for j in range(0,nx): \n", 300 | " X[j] = X[j][0:i] + X[j][i+1:] \n", 301 | "\n", 302 | " sign = (-1) ** (i % 2) \n", 303 | " sub_det = det_rec(X) \n", 304 | " res += sign * A[0][i] * sub_det \n", 305 | "\n", 306 | " return res" 307 | ] 308 | }, 309 | { 310 | "cell_type": "code", 311 | "execution_count": 29, 312 | "metadata": { 313 | "scrolled": true 314 | }, 315 | "outputs": [], 316 | "source": [ 317 | "C = []\n", 318 | "for i in range(0, n):\n", 319 | " row_C = []\n", 320 | " idx_r = list(range(0, n))\n", 321 | " idx_r.remove(i)\n", 322 | " for j in range(0, n):\n", 323 | " idx_c = list(range(0,n))\n", 324 | " idx_c.remove(j)\n", 325 | " M = []\n", 326 | " for k in idx_r:\n", 327 | " row_M = []\n", 328 | " for l in idx_c:\n", 329 | " val = A[k][l]\n", 330 | " row_M.append(val)\n", 331 | " M.append(row_M)\n", 332 | " Mij = det_rec(M)\n", 333 | " Cij = ((-1)**(i+j))*Mij\n", 334 | " row_C.append(Cij)\n", 335 | " C.append(row_C)" 336 | ] 337 | }, 338 | { 339 | "cell_type": "code", 340 | "execution_count": 30, 341 | "metadata": {}, 342 | "outputs": [ 343 | { 344 | "data": { 345 | "text/plain": [ 346 | "[[-3, 7, 3], [10, -15, -5], [12, -18, -7]]" 347 | ] 348 | }, 349 | "execution_count": 30, 350 | "metadata": {}, 351 | "output_type": "execute_result" 352 | } 353 | ], 354 | "source": [ 355 | "C" 356 | ] 357 | }, 358 | { 359 | "cell_type": "markdown", 360 | "metadata": {}, 361 | "source": [ 362 | "# 수반 행렬" 363 | ] 364 | }, 365 | { 366 | "cell_type": "code", 367 | "execution_count": 31, 368 | "metadata": {}, 369 | "outputs": [], 370 | "source": [ 371 | "def transpose(A):\n", 372 | " \"\"\"\n", 373 | " 행렬의 전치행렬\n", 374 | " 입력값: 전치행렬을 구하고자 하는 행렬 A\n", 375 | " 출력값: 행렬 A의 전치행렬 At\n", 376 | " \"\"\"\n", 377 | " n = len(A)\n", 378 | " p = len(A[0])\n", 379 | "\n", 380 | " At = []\n", 381 | " for i in range(0, p):\n", 382 | " row = []\n", 383 | " for j in range(0, n):\n", 384 | " val = A[j][i]\n", 385 | " row.append(val)\n", 386 | " At.append(row)\n", 387 | " return At " 388 | ] 389 | }, 390 | { 391 | "cell_type": "code", 392 | "execution_count": 32, 393 | "metadata": {}, 394 | "outputs": [ 395 | { 396 | "name": "stdout", 397 | "output_type": "stream", 398 | "text": [ 399 | "[[-3, 10, 12], [7, -15, -18], [3, -5, -7]]\n" 400 | ] 401 | } 402 | ], 403 | "source": [ 404 | "adj = transpose(C)\n", 405 | "print(adj)" 406 | ] 407 | }, 408 | { 409 | "cell_type": "markdown", 410 | "metadata": {}, 411 | "source": [ 412 | "# 역행렬" 413 | ] 414 | }, 415 | { 416 | "cell_type": "code", 417 | "execution_count": 33, 418 | "metadata": {}, 419 | "outputs": [], 420 | "source": [ 421 | "def scalar_mul(b, A):\n", 422 | " \"\"\"\n", 423 | " 행렬의 스칼라곱\n", 424 | " 입력값: 스칼라곱을 수행할 스칼라 b, 행렬 A\n", 425 | " 출력값: 스칼라 b와 행렬 A의 스칼라곱 결과인 행렬 res\n", 426 | " \"\"\"\n", 427 | "\n", 428 | " n = len(A)\n", 429 | " p = len(A[0])\n", 430 | " \n", 431 | " res = []\n", 432 | " for i in range(0, n):\n", 433 | " row = []\n", 434 | " for j in range(0, p):\n", 435 | " val = b * A[i][j]\n", 436 | " row.append(val)\n", 437 | " res.append(row)\n", 438 | " return res" 439 | ] 440 | }, 441 | { 442 | "cell_type": "code", 443 | "execution_count": 39, 444 | "metadata": {}, 445 | "outputs": [], 446 | "source": [ 447 | "invA = scalar_mul(1/detA, adj)" 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "execution_count": 40, 453 | "metadata": {}, 454 | "outputs": [ 455 | { 456 | "data": { 457 | "text/plain": [ 458 | "[[-0.6000000000000001, 2.0, 2.4000000000000004],\n", 459 | " [1.4000000000000001, -3.0, -3.6],\n", 460 | " [0.6000000000000001, -1.0, -1.4000000000000001]]" 461 | ] 462 | }, 463 | "execution_count": 40, 464 | "metadata": {}, 465 | "output_type": "execute_result" 466 | } 467 | ], 468 | "source": [ 469 | "invA" 470 | ] 471 | }, 472 | { 473 | "cell_type": "markdown", 474 | "metadata": {}, 475 | "source": [ 476 | "# 함수로 구현 하기" 477 | ] 478 | }, 479 | { 480 | "cell_type": "code", 481 | "execution_count": 36, 482 | "metadata": {}, 483 | "outputs": [], 484 | "source": [ 485 | "def zero_mat(n, p):\n", 486 | " \"\"\"\n", 487 | " 영 행렬 생성\n", 488 | " 입력값: 생성하고자 할 영 행렬의 크기 n행, p열\n", 489 | " 출력값: nxp 영 행렬 Z\n", 490 | " \"\"\"\n", 491 | " Z = []\n", 492 | " for i in range(0, n):\n", 493 | " row = []\n", 494 | " for j in range(0, p):\n", 495 | " row.append(0)\n", 496 | " Z.append(row)\n", 497 | " return Z\n", 498 | "\n", 499 | "\n", 500 | "def deepcopy(A):\n", 501 | " \"\"\"\n", 502 | " 깊은 복사(deepcopy) 구현\n", 503 | " 입력값: 깊은 복사를 하고자 하는 행렬 리스트 A\n", 504 | " 출력값: 깊은 복사 된 결과 행렬 리스트 res \n", 505 | " \"\"\"\n", 506 | " if type(A[0]) == list:\n", 507 | " n = len(A)\n", 508 | " p = len(A[0])\n", 509 | " res = zero_mat(n,p)\n", 510 | " for i in range(0,n):\n", 511 | " for j in range(0,p):\n", 512 | " res[i][j] = A[i][j]\n", 513 | " return res\n", 514 | " else:\n", 515 | " n = len(A)\n", 516 | " res = []\n", 517 | " for i in range(0,n):\n", 518 | " res.append(A[i])\n", 519 | " return res\n", 520 | "\n", 521 | "def transpose(A):\n", 522 | " \"\"\"\n", 523 | " 행렬의 전치행렬\n", 524 | " 입력값: 전치행렬을 구하고자 하는 행렬 A\n", 525 | " 출력값: 행렬 A의 전치행렬 At\n", 526 | " \"\"\"\n", 527 | " n = len(A)\n", 528 | " p = len(A[0])\n", 529 | "\n", 530 | " At = []\n", 531 | " for i in range(0, p):\n", 532 | " row = []\n", 533 | " for j in range(0, n):\n", 534 | " val = A[j][i]\n", 535 | " row.append(val)\n", 536 | " At.append(row)\n", 537 | " return At \n", 538 | "\n", 539 | "\n", 540 | "def scalar_mul(b, A):\n", 541 | " \"\"\"\n", 542 | " 행렬의 스칼라곱\n", 543 | " 입력값: 스칼라곱을 수행할 스칼라 b, 행렬 A\n", 544 | " 출력값: 스칼라 b와 행렬 A의 스칼라곱 결과인 행렬 res\n", 545 | " \"\"\"\n", 546 | "\n", 547 | " n = len(A)\n", 548 | " p = len(A[0])\n", 549 | " \n", 550 | " res = []\n", 551 | " for i in range(0, n):\n", 552 | " row = []\n", 553 | " for j in range(0, p):\n", 554 | " val = b * A[i][j]\n", 555 | " row.append(val)\n", 556 | " res.append(row)\n", 557 | " return res\n", 558 | "\n", 559 | "\n", 560 | "\n", 561 | "def det_rec(A):\n", 562 | " \n", 563 | " \"\"\"\n", 564 | " 행렬 A의 행렬식 구하기(재귀 방식을 이용)\n", 565 | " 입력값: 행렬식을 구하고자 하는 행렬 A\n", 566 | " 출력값: 행렬 A의 행렬식 res\n", 567 | " \"\"\"\n", 568 | " \n", 569 | " n = len(A)\n", 570 | " res = 0\n", 571 | "\n", 572 | " # 2x2 행렬의 행렬식 구하기\n", 573 | " if n == 2:\n", 574 | " res = A[0][0] * A[1][1] - A[1][0] * A[0][1]\n", 575 | " return res\n", 576 | "\n", 577 | " # nxn 행렬의 행렬식 구하기\n", 578 | " for i in range(0,n): \n", 579 | " X = deepcopy(A) \n", 580 | " X = X[1:] \n", 581 | " nx = len(X)\n", 582 | "\n", 583 | " for j in range(0,nx): \n", 584 | " X[j] = X[j][0:i] + X[j][i+1:] \n", 585 | "\n", 586 | " sign = (-1) ** (i % 2) \n", 587 | " sub_det = det_rec(X) \n", 588 | " res += sign * A[0][i] * sub_det \n", 589 | "\n", 590 | " return res\n", 591 | "\n", 592 | "\n", 593 | "\n", 594 | " \n", 595 | "def inv(A):\n", 596 | " \"\"\"\n", 597 | " 행렬 A의 역행렬 구하기\n", 598 | " 입력값: 행렬 A\n", 599 | " 출력값: 행렬 A의 역행렬 res\n", 600 | " \"\"\"\n", 601 | " \n", 602 | " n = len(A)\n", 603 | " X = deepcopy(A)\n", 604 | " \n", 605 | " C = []\n", 606 | " for i in range(0, n):\n", 607 | " row_C = []\n", 608 | " idx_r = list(range(0, n))\n", 609 | " idx_r.remove(i)\n", 610 | " for j in range(0, n):\n", 611 | " idx_c = list(range(0,n))\n", 612 | " idx_c.remove(j)\n", 613 | " M = []\n", 614 | " for k in idx_r:\n", 615 | " row_M = []\n", 616 | " for l in idx_c:\n", 617 | " val = X[k][l]\n", 618 | " row_M.append(val)\n", 619 | " M.append(row_M)\n", 620 | " Mij = det_rec(M)\n", 621 | " Cij = ((-1)**(i+j))*Mij\n", 622 | " row_C.append(Cij)\n", 623 | " C.append(row_C)\n", 624 | " \n", 625 | " adj = transpose(C)\n", 626 | " res = scalar_mul(1/det_rec(X), adj)\n", 627 | " \n", 628 | " return res" 629 | ] 630 | }, 631 | { 632 | "cell_type": "code", 633 | "execution_count": 37, 634 | "metadata": {}, 635 | "outputs": [], 636 | "source": [ 637 | "A = [[3,2,0], [-1,-3,6], [2,3,-5]]" 638 | ] 639 | }, 640 | { 641 | "cell_type": "code", 642 | "execution_count": 38, 643 | "metadata": {}, 644 | "outputs": [ 645 | { 646 | "data": { 647 | "text/plain": [ 648 | "[[-0.6000000000000001, 2.0, 2.4000000000000004],\n", 649 | " [1.4000000000000001, -3.0, -3.6],\n", 650 | " [0.6000000000000001, -1.0, -1.4000000000000001]]" 651 | ] 652 | }, 653 | "execution_count": 38, 654 | "metadata": {}, 655 | "output_type": "execute_result" 656 | } 657 | ], 658 | "source": [ 659 | "inv(A)" 660 | ] 661 | }, 662 | { 663 | "cell_type": "code", 664 | "execution_count": null, 665 | "metadata": {}, 666 | "outputs": [], 667 | "source": [] 668 | } 669 | ], 670 | "metadata": { 671 | "kernelspec": { 672 | "display_name": "Python 3", 673 | "language": "python", 674 | "name": "python3" 675 | }, 676 | "language_info": { 677 | "codemirror_mode": { 678 | "name": "ipython", 679 | "version": 3 680 | }, 681 | "file_extension": ".py", 682 | "mimetype": "text/x-python", 683 | "name": "python", 684 | "nbconvert_exporter": "python", 685 | "pygments_lexer": "ipython3", 686 | "version": "3.8.5" 687 | } 688 | }, 689 | "nbformat": 4, 690 | "nbformat_minor": 4 691 | } 692 | -------------------------------------------------------------------------------- /code/ch07-4.넘파이 역행렬 연산.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 넘파이를 활용한 역행렬 계산" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import numpy as np" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 3, 22 | "metadata": {}, 23 | "outputs": [ 24 | { 25 | "name": "stdout", 26 | "output_type": "stream", 27 | "text": [ 28 | "[[ 3 2 0]\n", 29 | " [-1 -3 6]\n", 30 | " [ 2 3 -5]]\n", 31 | "----\n", 32 | "[[-0.6 2. 2.4]\n", 33 | " [ 1.4 -3. -3.6]\n", 34 | " [ 0.6 -1. -1.4]]\n" 35 | ] 36 | } 37 | ], 38 | "source": [ 39 | "A = np.array([[3,2,0], [-1,-3,6], [2,3,-5]])\n", 40 | "invA = np.linalg.inv(A)\n", 41 | "print(A)\n", 42 | "print('----')\n", 43 | "print(invA)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [] 52 | } 53 | ], 54 | "metadata": { 55 | "kernelspec": { 56 | "display_name": "Python 3", 57 | "language": "python", 58 | "name": "python3" 59 | }, 60 | "language_info": { 61 | "codemirror_mode": { 62 | "name": "ipython", 63 | "version": 3 64 | }, 65 | "file_extension": ".py", 66 | "mimetype": "text/x-python", 67 | "name": "python", 68 | "nbconvert_exporter": "python", 69 | "pygments_lexer": "ipython3", 70 | "version": "3.8.5" 71 | } 72 | }, 73 | "nbformat": 4, 74 | "nbformat_minor": 4 75 | } 76 | -------------------------------------------------------------------------------- /code/ch09-3.파이썬 내적 연산.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 파이썬 내적 연산" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "a = [1,2,3]\n", 17 | "b = [4,5,6]\n", 18 | "n = len(a)\n", 19 | "res = 0\n", 20 | "for i in range(0, n):\n", 21 | " res += a[i]*b[i]" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 2, 27 | "metadata": {}, 28 | "outputs": [ 29 | { 30 | "data": { 31 | "text/plain": [ 32 | "32" 33 | ] 34 | }, 35 | "execution_count": 2, 36 | "metadata": {}, 37 | "output_type": "execute_result" 38 | } 39 | ], 40 | "source": [ 41 | "res" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 3, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "def inner_product(a, b):\n", 51 | " \"\"\"\n", 52 | " 벡터의 내적\n", 53 | " 입력값: 내적할 벡터 리스트 a, b\n", 54 | " 출력값: 벡터 a, b의 내적 결과 res\n", 55 | " \"\"\"\n", 56 | " n = len(a)\n", 57 | " res = 0\n", 58 | " for i in range(0, n):\n", 59 | " res += a[i]*b[i]\n", 60 | " return res" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 4, 66 | "metadata": {}, 67 | "outputs": [ 68 | { 69 | "data": { 70 | "text/plain": [ 71 | "32" 72 | ] 73 | }, 74 | "execution_count": 4, 75 | "metadata": {}, 76 | "output_type": "execute_result" 77 | } 78 | ], 79 | "source": [ 80 | "inner_product(a, b)" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": null, 86 | "metadata": {}, 87 | "outputs": [], 88 | "source": [] 89 | } 90 | ], 91 | "metadata": { 92 | "kernelspec": { 93 | "display_name": "Python 3", 94 | "language": "python", 95 | "name": "python3" 96 | }, 97 | "language_info": { 98 | "codemirror_mode": { 99 | "name": "ipython", 100 | "version": 3 101 | }, 102 | "file_extension": ".py", 103 | "mimetype": "text/x-python", 104 | "name": "python", 105 | "nbconvert_exporter": "python", 106 | "pygments_lexer": "ipython3", 107 | "version": "3.8.5" 108 | } 109 | }, 110 | "nbformat": 4, 111 | "nbformat_minor": 4 112 | } 113 | -------------------------------------------------------------------------------- /code/ch09-4.넘파이 내적 연산.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 넘파이 내적 연산 " 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import numpy as np" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 3, 22 | "metadata": {}, 23 | "outputs": [ 24 | { 25 | "name": "stdout", 26 | "output_type": "stream", 27 | "text": [ 28 | "32\n" 29 | ] 30 | } 31 | ], 32 | "source": [ 33 | "a = np.array([1,2,3])\n", 34 | "b = np.array([4,5,6])\n", 35 | "res = np.inner(a, b)\n", 36 | "print(res)" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": null, 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [] 45 | } 46 | ], 47 | "metadata": { 48 | "kernelspec": { 49 | "display_name": "Python 3", 50 | "language": "python", 51 | "name": "python3" 52 | }, 53 | "language_info": { 54 | "codemirror_mode": { 55 | "name": "ipython", 56 | "version": 3 57 | }, 58 | "file_extension": ".py", 59 | "mimetype": "text/x-python", 60 | "name": "python", 61 | "nbconvert_exporter": "python", 62 | "pygments_lexer": "ipython3", 63 | "version": "3.8.5" 64 | } 65 | }, 66 | "nbformat": 4, 67 | "nbformat_minor": 4 68 | } 69 | -------------------------------------------------------------------------------- /code/ch09-8.넘파이 내적 연산(QR).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 38, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import numpy as np\n", 10 | "A = np.array([[1, 0, 1], [0, 1, 1], [1, 2, 0]])\n", 11 | "Q, R = np.linalg.qr(A)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 39, 17 | "metadata": {}, 18 | "outputs": [ 19 | { 20 | "name": "stdout", 21 | "output_type": "stream", 22 | "text": [ 23 | "[[-0.70710678 0.57735027 -0.40824829]\n", 24 | " [-0. -0.57735027 -0.81649658]\n", 25 | " [-0.70710678 -0.57735027 0.40824829]]\n" 26 | ] 27 | } 28 | ], 29 | "source": [ 30 | "print(Q)" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 40, 36 | "metadata": {}, 37 | "outputs": [ 38 | { 39 | "name": "stdout", 40 | "output_type": "stream", 41 | "text": [ 42 | "[[-1.41421356 -1.41421356 -0.70710678]\n", 43 | " [ 0. -1.73205081 0. ]\n", 44 | " [ 0. 0. -1.22474487]]\n" 45 | ] 46 | } 47 | ], 48 | "source": [ 49 | "print(R)" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": null, 55 | "metadata": {}, 56 | "outputs": [], 57 | "source": [] 58 | } 59 | ], 60 | "metadata": { 61 | "kernelspec": { 62 | "display_name": "Python 3", 63 | "language": "python", 64 | "name": "python3" 65 | }, 66 | "language_info": { 67 | "codemirror_mode": { 68 | "name": "ipython", 69 | "version": 3 70 | }, 71 | "file_extension": ".py", 72 | "mimetype": "text/x-python", 73 | "name": "python", 74 | "nbconvert_exporter": "python", 75 | "pygments_lexer": "ipython3", 76 | "version": "3.8.5" 77 | } 78 | }, 79 | "nbformat": 4, 80 | "nbformat_minor": 4 81 | } 82 | -------------------------------------------------------------------------------- /code/ch10-2.파이썬 다양한 곱 연산.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 외적(텐서 곱)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "a = [1, 2, 3]\n", 17 | "b = [4, 5]\n", 18 | "\n", 19 | "res = []\n", 20 | "n1 = len(a)\n", 21 | "n2 = len(b)\n", 22 | "for i in range(0, n1):\n", 23 | " row = []\n", 24 | " for j in range(0, n2):\n", 25 | " val = a[i]*b[j]\n", 26 | " row.append(val)\n", 27 | " res.append(row)" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 2, 33 | "metadata": {}, 34 | "outputs": [ 35 | { 36 | "data": { 37 | "text/plain": [ 38 | "[[4, 5], [8, 10], [12, 15]]" 39 | ] 40 | }, 41 | "execution_count": 2, 42 | "metadata": {}, 43 | "output_type": "execute_result" 44 | } 45 | ], 46 | "source": [ 47 | "res" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 3, 53 | "metadata": {}, 54 | "outputs": [], 55 | "source": [ 56 | "def outer_product(a, b):\n", 57 | " \"\"\"\n", 58 | " 벡터의 외적\n", 59 | " 입력값: 외적할 벡터 리스트 a, b\n", 60 | " 출력값: 벡터 a, b의 외적 결과 res\n", 61 | " \"\"\"\n", 62 | " res = []\n", 63 | " n1 = len(a)\n", 64 | " n2 = len(b)\n", 65 | " for i in range(0, n1):\n", 66 | " row = []\n", 67 | " for j in range(0, n2):\n", 68 | " val = a[i]*b[j]\n", 69 | " row.append(val)\n", 70 | " res.append(row)\n", 71 | " return res" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 4, 77 | "metadata": {}, 78 | "outputs": [ 79 | { 80 | "data": { 81 | "text/plain": [ 82 | "[[4, 5], [8, 10], [12, 15]]" 83 | ] 84 | }, 85 | "execution_count": 4, 86 | "metadata": {}, 87 | "output_type": "execute_result" 88 | } 89 | ], 90 | "source": [ 91 | "outer_product(a, b)" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": null, 97 | "metadata": {}, 98 | "outputs": [], 99 | "source": [] 100 | } 101 | ], 102 | "metadata": { 103 | "kernelspec": { 104 | "display_name": "Python 3", 105 | "language": "python", 106 | "name": "python3" 107 | }, 108 | "language_info": { 109 | "codemirror_mode": { 110 | "name": "ipython", 111 | "version": 3 112 | }, 113 | "file_extension": ".py", 114 | "mimetype": "text/x-python", 115 | "name": "python", 116 | "nbconvert_exporter": "python", 117 | "pygments_lexer": "ipython3", 118 | "version": "3.8.5" 119 | } 120 | }, 121 | "nbformat": 4, 122 | "nbformat_minor": 4 123 | } 124 | -------------------------------------------------------------------------------- /code/ch10-3.넘파이 다양한 곱 연산.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 외적(텐서 곱)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 2, 13 | "metadata": {}, 14 | "outputs": [ 15 | { 16 | "name": "stdout", 17 | "output_type": "stream", 18 | "text": [ 19 | "[[ 4 5]\n", 20 | " [ 8 10]\n", 21 | " [12 15]]\n" 22 | ] 23 | } 24 | ], 25 | "source": [ 26 | "import numpy as np\n", 27 | "\n", 28 | "a = np.array([1, 2, 3])\n", 29 | "b = np.array([4, 5])\n", 30 | "\n", 31 | "res = np.outer(a, b)\n", 32 | "print(res)" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [] 41 | } 42 | ], 43 | "metadata": { 44 | "kernelspec": { 45 | "display_name": "Python 3", 46 | "language": "python", 47 | "name": "python3" 48 | }, 49 | "language_info": { 50 | "codemirror_mode": { 51 | "name": "ipython", 52 | "version": 3 53 | }, 54 | "file_extension": ".py", 55 | "mimetype": "text/x-python", 56 | "name": "python", 57 | "nbconvert_exporter": "python", 58 | "pygments_lexer": "ipython3", 59 | "version": "3.8.5" 60 | } 61 | }, 62 | "nbformat": 4, 63 | "nbformat_minor": 4 64 | } 65 | -------------------------------------------------------------------------------- /code/ch11-1.파이썬 고윳값 연산.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "A = [[3, 2, -3], [5, 0, 4], [0, -1, 3]]" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 3, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "[[3, 2, -3], [5, 0, 4], [0, -1, 3]]\n" 22 | ] 23 | } 24 | ], 25 | "source": [ 26 | "print(A)" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 4, 32 | "metadata": {}, 33 | "outputs": [], 34 | "source": [ 35 | "n = len(A)\n", 36 | "p = len(A[0])" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": null, 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [ 45 | "import random\n", 46 | "\n", 47 | "random.seed(0)\n", 48 | "\n", 49 | "b_k = []\n", 50 | "for i in range(0, p):\n", 51 | " b_i = random.random()\n", 52 | " b_k.append(b_i)\n" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [ 61 | "b_k" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "# (1단계) 행렬 A와 벡터 b_k 행렬곱 = b_k1" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": null, 74 | "metadata": {}, 75 | "outputs": [], 76 | "source": [ 77 | "n_sim = 100\n", 78 | "\n", 79 | "b_k1 = [0]*p\n", 80 | "\n", 81 | "for i in range(0, n):\n", 82 | " prod_sum = 0\n", 83 | " for j in range(0, p):\n", 84 | " prod_sum += A[i][j]*b_k[j]\n", 85 | " b_k1[i] = prod_sum\n", 86 | "print(b_k1)" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "# (2단계) 행렬 b_k1의 norm 구하기" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": null, 99 | "metadata": {}, 100 | "outputs": [], 101 | "source": [ 102 | "ss = 0\n", 103 | "for i in range(0, p):\n", 104 | " ss += b_k1[i]**2\n", 105 | "b_k1_norm = ss**(0.5)\n", 106 | "print(b_k1_norm)\n" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "# (3단계) 행렬 b_k1 정규화" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": null, 119 | "metadata": {}, 120 | "outputs": [], 121 | "source": [ 122 | "for i in range(0, p):\n", 123 | " b_k[i] = b_k1[i]/b_k1_norm\n", 124 | "print(b_k)" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "metadata": {}, 130 | "source": [ 131 | "# 1 + 2 + 3단계" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": 7, 137 | "metadata": {}, 138 | "outputs": [], 139 | "source": [ 140 | "import random\n", 141 | "\n", 142 | "random.seed(0)\n", 143 | "\n", 144 | "b_k = []\n", 145 | "for i in range(0, p):\n", 146 | " b_i = random.random()\n", 147 | " b_k.append(b_i)\n", 148 | " \n", 149 | "n_sim = 10\n", 150 | "\n", 151 | "b_k1 = [0]*p\n", 152 | "for k in range(0, n_sim):\n", 153 | " \n", 154 | " # 1단계\n", 155 | " for i in range(0, n):\n", 156 | " prod_sum = 0\n", 157 | " for j in range(0, p):\n", 158 | " prod_sum += A[i][j]*b_k[j]\n", 159 | " b_k1[i] = prod_sum\n", 160 | "\n", 161 | " # 2단계\n", 162 | " ss = 0\n", 163 | " for i in range(0, p):\n", 164 | " ss += b_k1[i]**2\n", 165 | " b_k1_norm = ss**(0.5)\n", 166 | "\n", 167 | " # 3단계\n", 168 | " for i in range(0, p):\n", 169 | " b_k[i] = b_k1[i]/b_k1_norm\n" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": 8, 175 | "metadata": {}, 176 | "outputs": [ 177 | { 178 | "data": { 179 | "text/plain": [ 180 | "[0.7915665328697569, 0.5616171610701941, -0.24084972167724808]" 181 | ] 182 | }, 183 | "execution_count": 8, 184 | "metadata": {}, 185 | "output_type": "execute_result" 186 | } 187 | ], 188 | "source": [ 189 | "b_k" 190 | ] 191 | }, 192 | { 193 | "cell_type": "code", 194 | "execution_count": null, 195 | "metadata": {}, 196 | "outputs": [], 197 | "source": [] 198 | } 199 | ], 200 | "metadata": { 201 | "kernelspec": { 202 | "display_name": "Python 3", 203 | "language": "python", 204 | "name": "python3" 205 | }, 206 | "language_info": { 207 | "codemirror_mode": { 208 | "name": "ipython", 209 | "version": 3 210 | }, 211 | "file_extension": ".py", 212 | "mimetype": "text/x-python", 213 | "name": "python", 214 | "nbconvert_exporter": "python", 215 | "pygments_lexer": "ipython3", 216 | "version": "3.8.5" 217 | } 218 | }, 219 | "nbformat": 4, 220 | "nbformat_minor": 4 221 | } 222 | -------------------------------------------------------------------------------- /code/ch11-2.파이썬 고윳값 연산-using QR.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 5, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "def zero_mat(n, p):\n", 10 | " \"\"\"\n", 11 | " 영 행렬 생성\n", 12 | " 입력값: 생성하고자 할 영 행렬의 크기 n행, p열\n", 13 | " 출력값: nxp 영 행렬 Z\n", 14 | " \"\"\"\n", 15 | " Z = []\n", 16 | " for i in range(0, n):\n", 17 | " row = []\n", 18 | " for j in range(0, p):\n", 19 | " row.append(0)\n", 20 | " Z.append(row)\n", 21 | " return Z\n", 22 | "\n", 23 | "\n", 24 | "\n", 25 | "def deepcopy(A):\n", 26 | " \"\"\"\n", 27 | " 깊은 복사(deepcopy) 구현\n", 28 | " 입력값: 깊은 복사를 하고자 하는 행렬 리스트 A\n", 29 | " 출력값: 깊은 복사 된 결과 행렬 리스트 res \n", 30 | " \"\"\"\n", 31 | " if type(A[0]) == list:\n", 32 | " n = len(A)\n", 33 | " p = len(A[0])\n", 34 | " res = zero_mat(n,p)\n", 35 | " for i in range(0,n):\n", 36 | " for j in range(0,p):\n", 37 | " res[i][j] = A[i][j]\n", 38 | " return res\n", 39 | " else:\n", 40 | " n = len(A)\n", 41 | " res = []\n", 42 | " for i in range(0,n):\n", 43 | " res.append(A[i])\n", 44 | " return res\n", 45 | "\n", 46 | "\n", 47 | "def norm(a):\n", 48 | " \"\"\"\n", 49 | " 벡터의 norm\n", 50 | " 입력값: norm을 구하고자 할 벡터 a\n", 51 | " 출력값: 벡터 a의 norm 결과 res\n", 52 | " \"\"\"\n", 53 | " n = len(a)\n", 54 | " res = 0\n", 55 | " for i in range(0, n):\n", 56 | " res += a[i]**2\n", 57 | " res = res**(0.5) \n", 58 | " return res\n", 59 | "\n", 60 | "\n", 61 | "\n", 62 | "def inner_product(a, b):\n", 63 | " \"\"\"\n", 64 | " 벡터의 내적\n", 65 | " 입력값: 내적할 벡터 리스트 a, b\n", 66 | " 출력값: 벡터 a, b의 내적 결과 res\n", 67 | " \"\"\"\n", 68 | " n = len(a)\n", 69 | " res = 0\n", 70 | " for i in range(0, n):\n", 71 | " res += a[i]*b[i]\n", 72 | " return res\n", 73 | "\n", 74 | "\n", 75 | "def normalize(a):\n", 76 | " \"\"\"\n", 77 | " 벡터 a의 normalization\n", 78 | " 벡터 a의 norm을 1로 만들어줌\n", 79 | " 입력값: normalization할 벡터 리스트 a\n", 80 | " 출력값: 벡터 a를 normalization한 결과 벡터 리스트 v\n", 81 | " \"\"\"\n", 82 | " n = len(a)\n", 83 | " v = []\n", 84 | " for i in range(0,n):\n", 85 | " tmp = a[i]/norm(a)\n", 86 | " v.append(tmp)\n", 87 | " return v\n", 88 | "\n", 89 | "\n", 90 | "\n", 91 | "def diag_ele(A):\n", 92 | " \"\"\"\n", 93 | " 대각 원소 구하기\n", 94 | " 입력값: 대각 원소를 구하고자 할 행렬 A\n", 95 | " 출력값: 행렬 A의 대각 원소 리스트 d\n", 96 | " \"\"\"\n", 97 | " n = len(A)\n", 98 | " d = []\n", 99 | " for i in range(0, n):\n", 100 | " d.append(A[i][i])\n", 101 | " return d\n", 102 | "\n", 103 | "def ele2diag(a):\n", 104 | " \"\"\"\n", 105 | " 대각원소 -> 대각행렬 변환\n", 106 | " 입력값: 대각 원소 리스트 a\n", 107 | " 출력값: 대각 원소 a를 이용해 생성한 nxn 대각 행렬 D\n", 108 | " n: 대각 원소 리스트 a의 길이\n", 109 | " \"\"\"\n", 110 | " n = len(a)\n", 111 | " D = []\n", 112 | " for i in range(0, n):\n", 113 | " row = []\n", 114 | " for j in range(0, n):\n", 115 | " if i==j:\n", 116 | " row.append(a[i])\n", 117 | " else:\n", 118 | " row.append(0)\n", 119 | " D.append(row)\n", 120 | " return D\n", 121 | "\n", 122 | "\n", 123 | "def identity(n):\n", 124 | " \"\"\"\n", 125 | " 항등행렬 생성\n", 126 | " 입력값: 항등 행렬의 크기 n\n", 127 | " 출력값: nxn 항등 행렬 I\n", 128 | " \"\"\"\n", 129 | " I = []\n", 130 | " for i in range(0, n):\n", 131 | " row = []\n", 132 | " for j in range(0, n):\n", 133 | " if i==j:\n", 134 | " row.append(1)\n", 135 | " else:\n", 136 | " row.append(0)\n", 137 | " I.append(row)\n", 138 | " return I\n", 139 | "\n", 140 | "\n", 141 | "\n", 142 | "def transpose(A):\n", 143 | " \"\"\"\n", 144 | " 행렬의 전치행렬\n", 145 | " 입력값: 전치행렬을 구하고자 하는 행렬 A\n", 146 | " 출력값: 행렬 A의 전치행렬 At\n", 147 | " \"\"\"\n", 148 | " n = len(A)\n", 149 | " p = len(A[0])\n", 150 | "\n", 151 | " At = []\n", 152 | " for i in range(0, p):\n", 153 | " row = []\n", 154 | " for j in range(0, n):\n", 155 | " val = A[j][i]\n", 156 | " row.append(val)\n", 157 | " At.append(row)\n", 158 | " return At\n", 159 | "\n", 160 | "\n", 161 | "\n", 162 | "\n", 163 | "def matmul(A, B): \n", 164 | " \"\"\"\n", 165 | " 행렬의 행렬곱\n", 166 | " 입력값: 행렬곱을 수행할 행렬 A, B\n", 167 | " 출력값: 행렬 A와 행렬 B의 행렬곱 결과인 행렬 res\n", 168 | " \"\"\"\n", 169 | " n = len(A)\n", 170 | " p1 = len(A[0])\n", 171 | " p2 = len(B[0])\n", 172 | "\n", 173 | " res = []\n", 174 | " for i in range(0, n):\n", 175 | " row = []\n", 176 | " for j in range(0, p2):\n", 177 | " val = 0\n", 178 | " for k in range(0, p1):\n", 179 | " val += A[i][k] * B[k][j] \n", 180 | " row.append(val) \n", 181 | " res.append(row)\n", 182 | " return res\n", 183 | "\n", 184 | "\n", 185 | "def qr_gram(A):\n", 186 | " \"\"\"\n", 187 | " 그램 슈미트 방법을 이용한 QR분해\n", 188 | " 입력값: 행렬 A\n", 189 | " 출력값: 행렬 A를 그램 슈미트 방법을 이용해 QR분해한 결과 행렬 Q, R\n", 190 | " \"\"\"\n", 191 | " n = len(A)\n", 192 | " p = len(A[0])\n", 193 | "\n", 194 | " At = transpose(A)\n", 195 | "\n", 196 | " U = []\n", 197 | " norm_list = []\n", 198 | "\n", 199 | " V = []\n", 200 | " Q = []\n", 201 | " R = []\n", 202 | "\n", 203 | " for i in range(0,n):\n", 204 | " if i == 0:\n", 205 | " u = At[i]\n", 206 | " norm_u = norm(u)\n", 207 | " U.append(u)\n", 208 | " norm_list.append(norm_u)\n", 209 | " else:\n", 210 | " a = At[i]\n", 211 | " dp_list = []\n", 212 | " for j in range(0,i):\n", 213 | " dp = inner_product(a, U[j])\n", 214 | " dp_list.append(dp)\n", 215 | "\n", 216 | " u = []\n", 217 | " for j in range(0,n):\n", 218 | " val = a[j]\n", 219 | " for k in range(0,i):\n", 220 | " val -= (dp_list[k]/norm_list[k]**2)*U[k][j]\n", 221 | " u.append(val)\n", 222 | " norm_u = norm(u)\n", 223 | " U.append(u)\n", 224 | " norm_list.append(norm_u)\n", 225 | "\n", 226 | " v = normalize(u)\n", 227 | " V.append(v) \n", 228 | "\n", 229 | " Q = transpose(V)\n", 230 | "\n", 231 | " for i in range(0,n):\n", 232 | " r = []\n", 233 | " for j in range(0,n):\n", 234 | " if i > j:\n", 235 | " r.append(0)\n", 236 | " else:\n", 237 | " r_ele = inner_product(At[j], V[i])\n", 238 | " r.append(r_ele)\n", 239 | " R.append(r)\n", 240 | " \n", 241 | " return Q, R" 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": 4, 247 | "metadata": {}, 248 | "outputs": [], 249 | "source": [ 250 | "def eig_qr(A):\n", 251 | " \"\"\"\n", 252 | " 이 방법은 행렬 A가 대칭행렬이여야만 사용할수있음\n", 253 | " QR분해를 이용한 고윳값, 고유벡터 구하기\n", 254 | " 인풋: 고윳값, 고유벡터를 구하고자 하는 행렬 A\n", 255 | " 아웃풋: E = 고윳값, V = 고유벡터\n", 256 | " \"\"\"\n", 257 | " n = len(A)\n", 258 | " E = deepcopy(A)\n", 259 | " V = identity(n)\n", 260 | " for i in range(0, 30):\n", 261 | " Q, R = qr_gram(E)\n", 262 | " E = matmul(R, Q)\n", 263 | " V = matmul(V, Q)\n", 264 | " \n", 265 | " return E, V" 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": 6, 271 | "metadata": {}, 272 | "outputs": [], 273 | "source": [ 274 | "# 행렬 설정\n", 275 | "A = [[3, 2, 1], [2, 1, 4], [1, 4, 2]]" 276 | ] 277 | }, 278 | { 279 | "cell_type": "code", 280 | "execution_count": 8, 281 | "metadata": {}, 282 | "outputs": [], 283 | "source": [ 284 | "E, V = eig_qr(A)" 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": 9, 290 | "metadata": {}, 291 | "outputs": [ 292 | { 293 | "data": { 294 | "text/plain": [ 295 | "[[6.712979947116968, 2.879021707040307e-12, 3.751943741394037e-16],\n", 296 | " [2.879838152436312e-12, -2.667521069617966, 0.0005353513744104396],\n", 297 | " [3.5585292802573045e-16, 0.0005353513744103792, 1.9545411225010036]]" 298 | ] 299 | }, 300 | "execution_count": 9, 301 | "metadata": {}, 302 | "output_type": "execute_result" 303 | } 304 | ], 305 | "source": [ 306 | "E" 307 | ] 308 | }, 309 | { 310 | "cell_type": "code", 311 | "execution_count": 10, 312 | "metadata": {}, 313 | "outputs": [ 314 | { 315 | "data": { 316 | "text/plain": [ 317 | "[[0.49473044880482836, -0.1606950674646186, -0.8540602310832155],\n", 318 | " [0.6079756458712265, 0.7662219231613991, 0.20801340940985225],\n", 319 | " [0.6209729438975886, -0.6221583880005057, 0.4767720033598603]]" 320 | ] 321 | }, 322 | "execution_count": 10, 323 | "metadata": {}, 324 | "output_type": "execute_result" 325 | } 326 | ], 327 | "source": [ 328 | "V" 329 | ] 330 | }, 331 | { 332 | "cell_type": "code", 333 | "execution_count": null, 334 | "metadata": {}, 335 | "outputs": [], 336 | "source": [] 337 | } 338 | ], 339 | "metadata": { 340 | "kernelspec": { 341 | "display_name": "Python 3", 342 | "language": "python", 343 | "name": "python3" 344 | }, 345 | "language_info": { 346 | "codemirror_mode": { 347 | "name": "ipython", 348 | "version": 3 349 | }, 350 | "file_extension": ".py", 351 | "mimetype": "text/x-python", 352 | "name": "python", 353 | "nbconvert_exporter": "python", 354 | "pygments_lexer": "ipython3", 355 | "version": "3.8.5" 356 | } 357 | }, 358 | "nbformat": 4, 359 | "nbformat_minor": 4 360 | } 361 | -------------------------------------------------------------------------------- /code/ch11-3.넘파이 고윳값 연산.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 넘파이 고윳값, 고유벡터(1)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 74, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import numpy as np\n", 17 | "\n", 18 | "def power_iteration(A, num_simulations: int):\n", 19 | "\n", 20 | " b_k = np.random.rand(A.shape[1])\n", 21 | "\n", 22 | " for _ in range(num_simulations):\n", 23 | " b_k1 = np.dot(A, b_k)\n", 24 | " b_k1_norm = np.linalg.norm(b_k1)\n", 25 | " b_k = b_k1 / b_k1_norm\n", 26 | "\n", 27 | " return b_k\n" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 81, 33 | "metadata": {}, 34 | "outputs": [ 35 | { 36 | "data": { 37 | "text/plain": [ 38 | "array([ 0.79156598, 0.56161828, -0.24084892])" 39 | ] 40 | }, 41 | "execution_count": 81, 42 | "metadata": {}, 43 | "output_type": "execute_result" 44 | } 45 | ], 46 | "source": [ 47 | "power_iteration(np.array([[3, 2, -3], [5, 0, 4], [0, -1, 3]]), 10)" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "# 넘파이 고윳값, 고유벡터(2)" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 1, 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "import numpy as np" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 2, 69 | "metadata": {}, 70 | "outputs": [ 71 | { 72 | "name": "stdout", 73 | "output_type": "stream", 74 | "text": [ 75 | "[[ 3 2 -3]\n", 76 | " [ 5 0 4]\n", 77 | " [ 0 -1 3]]\n" 78 | ] 79 | } 80 | ], 81 | "source": [ 82 | "A = np.array([[3, 2, -3], [5, 0, 4], [0, -1, 3]])\n", 83 | "print(A)" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 3, 89 | "metadata": {}, 90 | "outputs": [], 91 | "source": [ 92 | "e, v = np.linalg.eig(A)" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": 4, 98 | "metadata": {}, 99 | "outputs": [ 100 | { 101 | "name": "stdout", 102 | "output_type": "stream", 103 | "text": [ 104 | "[ 5.33181031 -0.48705072 1.15524041]\n" 105 | ] 106 | } 107 | ], 108 | "source": [ 109 | "print(e)" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 5, 115 | "metadata": {}, 116 | "outputs": [ 117 | { 118 | "name": "stdout", 119 | "output_type": "stream", 120 | "text": [ 121 | "[[ 0.79156677 -0.29972355 -0.17536491]\n", 122 | " [ 0.56161668 0.91706148 0.86551759]\n", 123 | " [-0.24085007 0.26299058 0.46917636]]\n" 124 | ] 125 | } 126 | ], 127 | "source": [ 128 | "print(v)" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": null, 134 | "metadata": {}, 135 | "outputs": [], 136 | "source": [] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": null, 141 | "metadata": {}, 142 | "outputs": [], 143 | "source": [] 144 | }, 145 | { 146 | "cell_type": "markdown", 147 | "metadata": {}, 148 | "source": [ 149 | "# 2x2 행렬의 고윳값, 고유 벡터" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": 24, 155 | "metadata": {}, 156 | "outputs": [ 157 | { 158 | "name": "stdout", 159 | "output_type": "stream", 160 | "text": [ 161 | "[[ 3 0]\n", 162 | " [ 8 -1]]\n" 163 | ] 164 | } 165 | ], 166 | "source": [ 167 | "A = np.array([[3, 0], [8, -1]])\n", 168 | "print(A)" 169 | ] 170 | }, 171 | { 172 | "cell_type": "code", 173 | "execution_count": 25, 174 | "metadata": {}, 175 | "outputs": [], 176 | "source": [ 177 | "e, v = np.linalg.eig(A)" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 26, 183 | "metadata": {}, 184 | "outputs": [ 185 | { 186 | "name": "stdout", 187 | "output_type": "stream", 188 | "text": [ 189 | "[-1. 3.]\n" 190 | ] 191 | } 192 | ], 193 | "source": [ 194 | "print(e)" 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": 27, 200 | "metadata": {}, 201 | "outputs": [ 202 | { 203 | "name": "stdout", 204 | "output_type": "stream", 205 | "text": [ 206 | "[[0. 0.4472136 ]\n", 207 | " [1. 0.89442719]]\n" 208 | ] 209 | } 210 | ], 211 | "source": [ 212 | "print(v)" 213 | ] 214 | }, 215 | { 216 | "cell_type": "markdown", 217 | "metadata": {}, 218 | "source": [ 219 | "# 3x3 행렬의 고윳값, 고유 벡터" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 30, 225 | "metadata": {}, 226 | "outputs": [ 227 | { 228 | "name": "stdout", 229 | "output_type": "stream", 230 | "text": [ 231 | "[[ 4 0 1]\n", 232 | " [-2 1 0]\n", 233 | " [-2 0 1]]\n" 234 | ] 235 | } 236 | ], 237 | "source": [ 238 | "A = np.array([[4, 0, 1], [-2, 1, 0], [-2, 0, 1]])\n", 239 | "print(A)" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 31, 245 | "metadata": {}, 246 | "outputs": [], 247 | "source": [ 248 | "e, v = np.linalg.eig(A)" 249 | ] 250 | }, 251 | { 252 | "cell_type": "code", 253 | "execution_count": 32, 254 | "metadata": {}, 255 | "outputs": [ 256 | { 257 | "name": "stdout", 258 | "output_type": "stream", 259 | "text": [ 260 | "[1. 3. 2.]\n" 261 | ] 262 | } 263 | ], 264 | "source": [ 265 | "print(e)" 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": 33, 271 | "metadata": {}, 272 | "outputs": [ 273 | { 274 | "name": "stdout", 275 | "output_type": "stream", 276 | "text": [ 277 | "[[ 0. 0.57735027 -0.33333333]\n", 278 | " [ 1. -0.57735027 0.66666667]\n", 279 | " [ 0. -0.57735027 0.66666667]]\n" 280 | ] 281 | } 282 | ], 283 | "source": [ 284 | "print(v)" 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": 40, 290 | "metadata": {}, 291 | "outputs": [ 292 | { 293 | "data": { 294 | "text/plain": [ 295 | "0.31622776601683794" 296 | ] 297 | }, 298 | "execution_count": 40, 299 | "metadata": {}, 300 | "output_type": "execute_result" 301 | } 302 | ], 303 | "source": [ 304 | "1/np.sqrt(10)" 305 | ] 306 | }, 307 | { 308 | "cell_type": "code", 309 | "execution_count": 37, 310 | "metadata": {}, 311 | "outputs": [ 312 | { 313 | "data": { 314 | "text/plain": [ 315 | "0.4082482904638631" 316 | ] 317 | }, 318 | "execution_count": 37, 319 | "metadata": {}, 320 | "output_type": "execute_result" 321 | } 322 | ], 323 | "source": [ 324 | "1/np.sqrt(6)" 325 | ] 326 | }, 327 | { 328 | "cell_type": "code", 329 | "execution_count": 38, 330 | "metadata": {}, 331 | "outputs": [ 332 | { 333 | "data": { 334 | "text/plain": [ 335 | "0.25" 336 | ] 337 | }, 338 | "execution_count": 38, 339 | "metadata": {}, 340 | "output_type": "execute_result" 341 | } 342 | ], 343 | "source": [ 344 | "1/4" 345 | ] 346 | }, 347 | { 348 | "cell_type": "code", 349 | "execution_count": 3, 350 | "metadata": {}, 351 | "outputs": [], 352 | "source": [ 353 | "B = np.array([[3, 2, 1], [2, 1, 4], [1, 4, 2]])\n", 354 | "E, V = np.linalg.eig(B)\n" 355 | ] 356 | }, 357 | { 358 | "cell_type": "code", 359 | "execution_count": 4, 360 | "metadata": {}, 361 | "outputs": [ 362 | { 363 | "data": { 364 | "text/plain": [ 365 | "array([ 6.71297995, 1.95454118, -2.66752113])" 366 | ] 367 | }, 368 | "execution_count": 4, 369 | "metadata": {}, 370 | "output_type": "execute_result" 371 | } 372 | ], 373 | "source": [ 374 | "E" 375 | ] 376 | }, 377 | { 378 | "cell_type": "code", 379 | "execution_count": 5, 380 | "metadata": {}, 381 | "outputs": [ 382 | { 383 | "data": { 384 | "text/plain": [ 385 | "array([[ 0.49473045, 0.85407884, 0.16059614],\n", 386 | " [ 0.60797565, -0.20810216, -0.76619782],\n", 387 | " [ 0.62097294, -0.47669994, 0.62221361]])" 388 | ] 389 | }, 390 | "execution_count": 5, 391 | "metadata": {}, 392 | "output_type": "execute_result" 393 | } 394 | ], 395 | "source": [ 396 | "V" 397 | ] 398 | }, 399 | { 400 | "cell_type": "code", 401 | "execution_count": null, 402 | "metadata": {}, 403 | "outputs": [], 404 | "source": [] 405 | } 406 | ], 407 | "metadata": { 408 | "kernelspec": { 409 | "display_name": "Python 3", 410 | "language": "python", 411 | "name": "python3" 412 | }, 413 | "language_info": { 414 | "codemirror_mode": { 415 | "name": "ipython", 416 | "version": 3 417 | }, 418 | "file_extension": ".py", 419 | "mimetype": "text/x-python", 420 | "name": "python", 421 | "nbconvert_exporter": "python", 422 | "pygments_lexer": "ipython3", 423 | "version": "3.8.5" 424 | } 425 | }, 426 | "nbformat": 4, 427 | "nbformat_minor": 4 428 | } 429 | -------------------------------------------------------------------------------- /code/ch12-3.파이썬 직교 행렬.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "def transpose(A):\n", 10 | " \"\"\"\n", 11 | " 행렬의 전치행렬\n", 12 | " 입력값: 전치행렬을 구하고자 하는 행렬 A\n", 13 | " 출력값: 행렬 A의 전치행렬 At\n", 14 | " \"\"\"\n", 15 | " n = len(A)\n", 16 | " p = len(A[0])\n", 17 | "\n", 18 | " At = []\n", 19 | " for i in range(0, p):\n", 20 | " row = []\n", 21 | " for j in range(0, n):\n", 22 | " val = A[j][i]\n", 23 | " row.append(val)\n", 24 | " At.append(row)\n", 25 | " return At\n", 26 | "\n", 27 | "\n", 28 | "def matmul(A, B): \n", 29 | " \"\"\"\n", 30 | " 행렬의 행렬곱\n", 31 | " 입력값: 행렬곱을 수행할 행렬 A, B\n", 32 | " 출력값: 행렬 A와 행렬 B의 행렬곱 결과인 행렬 res\n", 33 | " \"\"\"\n", 34 | " n = len(A)\n", 35 | " p1 = len(A[0])\n", 36 | " p2 = len(B[0])\n", 37 | "\n", 38 | " res = []\n", 39 | " for i in range(0, n):\n", 40 | " row = []\n", 41 | " for j in range(0, p2):\n", 42 | " val = 0\n", 43 | " for k in range(0, p1):\n", 44 | " val += A[i][k] * B[k][j] \n", 45 | " row.append(val) \n", 46 | " res.append(row)\n", 47 | " return res" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 3, 53 | "metadata": {}, 54 | "outputs": [], 55 | "source": [ 56 | "A = [[1/(2**0.5), -1/(2**0.5)], [1/(2**0.5), 1/(2**0.5)]]\n", 57 | "At = transpose(A)" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 4, 63 | "metadata": {}, 64 | "outputs": [], 65 | "source": [ 66 | "res = matmul(At, A)" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 6, 72 | "metadata": {}, 73 | "outputs": [ 74 | { 75 | "name": "stdout", 76 | "output_type": "stream", 77 | "text": [ 78 | "[[0.9999999999999998, 0.0], [0.0, 0.9999999999999998]]\n" 79 | ] 80 | } 81 | ], 82 | "source": [ 83 | "print(res)" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": null, 89 | "metadata": {}, 90 | "outputs": [], 91 | "source": [] 92 | } 93 | ], 94 | "metadata": { 95 | "kernelspec": { 96 | "display_name": "Python 3", 97 | "language": "python", 98 | "name": "python3" 99 | }, 100 | "language_info": { 101 | "codemirror_mode": { 102 | "name": "ipython", 103 | "version": 3 104 | }, 105 | "file_extension": ".py", 106 | "mimetype": "text/x-python", 107 | "name": "python", 108 | "nbconvert_exporter": "python", 109 | "pygments_lexer": "ipython3", 110 | "version": "3.8.5" 111 | } 112 | }, 113 | "nbformat": 4, 114 | "nbformat_minor": 4 115 | } 116 | -------------------------------------------------------------------------------- /code/ch12-4.넘파이 직교 행렬.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 3, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import numpy as np\n", 10 | "\n", 11 | "A = np.array([[1/(2**0.5), -1/(2**0.5)], [1/(2**0.5), 1/(2**0.5)]])\n", 12 | "At = np.transpose(A)" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 4, 18 | "metadata": {}, 19 | "outputs": [ 20 | { 21 | "name": "stdout", 22 | "output_type": "stream", 23 | "text": [ 24 | "[[1.00000000e+00 2.23711432e-17]\n", 25 | " [2.23711432e-17 1.00000000e+00]]\n" 26 | ] 27 | } 28 | ], 29 | "source": [ 30 | "res = np.matmul(At, A)\n", 31 | "print(res)" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [] 40 | } 41 | ], 42 | "metadata": { 43 | "kernelspec": { 44 | "display_name": "Python 3", 45 | "language": "python", 46 | "name": "python3" 47 | }, 48 | "language_info": { 49 | "codemirror_mode": { 50 | "name": "ipython", 51 | "version": 3 52 | }, 53 | "file_extension": ".py", 54 | "mimetype": "text/x-python", 55 | "name": "python", 56 | "nbconvert_exporter": "python", 57 | "pygments_lexer": "ipython3", 58 | "version": "3.8.5" 59 | } 60 | }, 61 | "nbformat": 4, 62 | "nbformat_minor": 4 63 | } 64 | -------------------------------------------------------------------------------- /code/ch13-2.파이썬 대각화.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 고윳값 분해" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 2, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "def zero_mat(n, p):\n", 17 | " \"\"\"\n", 18 | " 영 행렬 생성\n", 19 | " 입력값: 생성하고자 할 영 행렬의 크기 n행, p열\n", 20 | " 출력값: nxp 영 행렬 Z\n", 21 | " \"\"\"\n", 22 | " Z = []\n", 23 | " for i in range(0, n):\n", 24 | " row = []\n", 25 | " for j in range(0, p):\n", 26 | " row.append(0)\n", 27 | " Z.append(row)\n", 28 | " return Z\n", 29 | "\n", 30 | "\n", 31 | "\n", 32 | "def deepcopy(A):\n", 33 | " \"\"\"\n", 34 | " 깊은 복사(deepcopy) 구현\n", 35 | " 입력값: 깊은 복사를 하고자 하는 행렬 리스트 A\n", 36 | " 출력값: 깊은 복사 된 결과 행렬 리스트 res \n", 37 | " \"\"\"\n", 38 | " if type(A[0]) == list:\n", 39 | " n = len(A)\n", 40 | " p = len(A[0])\n", 41 | " res = zero_mat(n,p)\n", 42 | " for i in range(0,n):\n", 43 | " for j in range(0,p):\n", 44 | " res[i][j] = A[i][j]\n", 45 | " return res\n", 46 | " else:\n", 47 | " n = len(A)\n", 48 | " res = []\n", 49 | " for i in range(0,n):\n", 50 | " res.append(A[i])\n", 51 | " return res\n", 52 | "\n", 53 | "\n", 54 | "def norm(a):\n", 55 | " \"\"\"\n", 56 | " 벡터의 norm\n", 57 | " 입력값: norm을 구하고자 할 벡터 a\n", 58 | " 출력값: 벡터 a의 norm 결과 res\n", 59 | " \"\"\"\n", 60 | " n = len(a)\n", 61 | " res = 0\n", 62 | " for i in range(0, n):\n", 63 | " res += a[i]**2\n", 64 | " res = res**(0.5) \n", 65 | " return res\n", 66 | "\n", 67 | "\n", 68 | "\n", 69 | "def inner_product(a, b):\n", 70 | " \"\"\"\n", 71 | " 벡터의 내적\n", 72 | " 입력값: 내적할 벡터 리스트 a, b\n", 73 | " 출력값: 벡터 a, b의 내적 결과 res\n", 74 | " \"\"\"\n", 75 | " n = len(a)\n", 76 | " res = 0\n", 77 | " for i in range(0, n):\n", 78 | " res += a[i]*b[i]\n", 79 | " return res\n", 80 | "\n", 81 | "\n", 82 | "def normalize(a):\n", 83 | " \"\"\"\n", 84 | " 벡터 a의 normalization\n", 85 | " 벡터 a의 norm을 1로 만들어줌\n", 86 | " 입력값: normalization할 벡터 리스트 a\n", 87 | " 출력값: 벡터 a를 normalization한 결과 벡터 리스트 v\n", 88 | " \"\"\"\n", 89 | " n = len(a)\n", 90 | " v = []\n", 91 | " for i in range(0,n):\n", 92 | " tmp = a[i]/norm(a)\n", 93 | " v.append(tmp)\n", 94 | " return v\n", 95 | "\n", 96 | "\n", 97 | "\n", 98 | "def diag_ele(A):\n", 99 | " \"\"\"\n", 100 | " 대각 원소 구하기\n", 101 | " 입력값: 대각 원소를 구하고자 할 행렬 A\n", 102 | " 출력값: 행렬 A의 대각 원소 리스트 d\n", 103 | " \"\"\"\n", 104 | " n = len(A)\n", 105 | " d = []\n", 106 | " for i in range(0, n):\n", 107 | " d.append(A[i][i])\n", 108 | " return d\n", 109 | "\n", 110 | "def ele2diag(a):\n", 111 | " \"\"\"\n", 112 | " 대각원소 -> 대각행렬 변환\n", 113 | " 입력값: 대각 원소 리스트 a\n", 114 | " 출력값: 대각 원소 a를 이용해 생성한 nxn 대각 행렬 D\n", 115 | " n: 대각 원소 리스트 a의 길이\n", 116 | " \"\"\"\n", 117 | " n = len(a)\n", 118 | " D = []\n", 119 | " for i in range(0, n):\n", 120 | " row = []\n", 121 | " for j in range(0, n):\n", 122 | " if i==j:\n", 123 | " row.append(a[i])\n", 124 | " else:\n", 125 | " row.append(0)\n", 126 | " D.append(row)\n", 127 | " return D\n", 128 | "\n", 129 | "\n", 130 | "def identity(n):\n", 131 | " \"\"\"\n", 132 | " 항등행렬 생성\n", 133 | " 입력값: 항등 행렬의 크기 n\n", 134 | " 출력값: nxn 항등 행렬 I\n", 135 | " \"\"\"\n", 136 | " I = []\n", 137 | " for i in range(0, n):\n", 138 | " row = []\n", 139 | " for j in range(0, n):\n", 140 | " if i==j:\n", 141 | " row.append(1)\n", 142 | " else:\n", 143 | " row.append(0)\n", 144 | " I.append(row)\n", 145 | " return I\n", 146 | "\n", 147 | "\n", 148 | "\n", 149 | "def transpose(A):\n", 150 | " \"\"\"\n", 151 | " 행렬의 전치행렬\n", 152 | " 입력값: 전치행렬을 구하고자 하는 행렬 A\n", 153 | " 출력값: 행렬 A의 전치행렬 At\n", 154 | " \"\"\"\n", 155 | " n = len(A)\n", 156 | " p = len(A[0])\n", 157 | "\n", 158 | " At = []\n", 159 | " for i in range(0, p):\n", 160 | " row = []\n", 161 | " for j in range(0, n):\n", 162 | " val = A[j][i]\n", 163 | " row.append(val)\n", 164 | " At.append(row)\n", 165 | " return At\n", 166 | "\n", 167 | "\n", 168 | "\n", 169 | "\n", 170 | "def matmul(A, B): \n", 171 | " \"\"\"\n", 172 | " 행렬의 행렬곱\n", 173 | " 입력값: 행렬곱을 수행할 행렬 A, B\n", 174 | " 출력값: 행렬 A와 행렬 B의 행렬곱 결과인 행렬 res\n", 175 | " \"\"\"\n", 176 | " n = len(A)\n", 177 | " p1 = len(A[0])\n", 178 | " p2 = len(B[0])\n", 179 | "\n", 180 | " res = []\n", 181 | " for i in range(0, n):\n", 182 | " row = []\n", 183 | " for j in range(0, p2):\n", 184 | " val = 0\n", 185 | " for k in range(0, p1):\n", 186 | " val += A[i][k] * B[k][j] \n", 187 | " row.append(val) \n", 188 | " res.append(row)\n", 189 | " return res\n", 190 | "\n", 191 | "\n", 192 | "def qr_gram(A):\n", 193 | " \"\"\"\n", 194 | " 그램 슈미트 방법을 이용한 QR분해\n", 195 | " 입력값: 행렬 A\n", 196 | " 출력값: 행렬 A를 그램 슈미트 방법을 이용해 QR분해한 결과 행렬 Q, R\n", 197 | " \"\"\"\n", 198 | " n = len(A)\n", 199 | " p = len(A[0])\n", 200 | "\n", 201 | " At = transpose(A)\n", 202 | "\n", 203 | " U = []\n", 204 | " norm_list = []\n", 205 | "\n", 206 | " V = []\n", 207 | " Q = []\n", 208 | " R = []\n", 209 | "\n", 210 | " for i in range(0,n):\n", 211 | " if i == 0:\n", 212 | " u = At[i]\n", 213 | " norm_u = norm(u)\n", 214 | " U.append(u)\n", 215 | " norm_list.append(norm_u)\n", 216 | " else:\n", 217 | " a = At[i]\n", 218 | " dp_list = []\n", 219 | " for j in range(0,i):\n", 220 | " dp = inner_product(a, U[j])\n", 221 | " dp_list.append(dp)\n", 222 | "\n", 223 | " u = []\n", 224 | " for j in range(0,n):\n", 225 | " val = a[j]\n", 226 | " for k in range(0,i):\n", 227 | " val -= (dp_list[k]/norm_list[k]**2)*U[k][j]\n", 228 | " u.append(val)\n", 229 | " norm_u = norm(u)\n", 230 | " U.append(u)\n", 231 | " norm_list.append(norm_u)\n", 232 | "\n", 233 | " v = normalize(u)\n", 234 | " V.append(v) \n", 235 | "\n", 236 | " Q = transpose(V)\n", 237 | "\n", 238 | " for i in range(0,n):\n", 239 | " r = []\n", 240 | " for j in range(0,n):\n", 241 | " if i > j:\n", 242 | " r.append(0)\n", 243 | " else:\n", 244 | " r_ele = inner_product(At[j], V[i])\n", 245 | " r.append(r_ele)\n", 246 | " R.append(r)\n", 247 | " \n", 248 | " return Q, R" 249 | ] 250 | }, 251 | { 252 | "cell_type": "code", 253 | "execution_count": 3, 254 | "metadata": {}, 255 | "outputs": [], 256 | "source": [ 257 | "def eig_qr(A):\n", 258 | " \"\"\"\n", 259 | " 이 방법은 행렬 A가 대칭행렬이여야만 사용할수있음\n", 260 | " QR분해를 이용한 고윳값, 고유벡터 구하기\n", 261 | " 인풋: 고윳값, 고유벡터를 구하고자 하는 행렬 A\n", 262 | " 아웃풋: E = 고윳값, V = 고유벡터\n", 263 | " \"\"\"\n", 264 | " n = len(A)\n", 265 | " E = deepcopy(A)\n", 266 | " V = identity(n)\n", 267 | " for i in range(0, 30):\n", 268 | " Q, R = qr_gram(E)\n", 269 | " E = matmul(R, Q)\n", 270 | " V = matmul(V, Q)\n", 271 | " \n", 272 | " return E, V" 273 | ] 274 | }, 275 | { 276 | "cell_type": "code", 277 | "execution_count": 32, 278 | "metadata": {}, 279 | "outputs": [], 280 | "source": [ 281 | "# 행렬 설정\n", 282 | "A = [[1,2,3],[2,4,5],[3,5,3]]\n", 283 | "E, V = eig_qr(A)" 284 | ] 285 | }, 286 | { 287 | "cell_type": "code", 288 | "execution_count": 33, 289 | "metadata": {}, 290 | "outputs": [ 291 | { 292 | "data": { 293 | "text/plain": [ 294 | "[[9.907543212206955, -6.8732775569774905e-15, 3.474724106619529e-14],\n", 295 | " [1.0755984962622474e-20, -1.959064335867676, -3.5510377153525793e-14],\n", 296 | " [2.175605365599517e-67, -5.311047270506677e-47, 0.05152112366071964]]" 297 | ] 298 | }, 299 | "execution_count": 33, 300 | "metadata": {}, 301 | "output_type": "execute_result" 302 | } 303 | ], 304 | "source": [ 305 | "E" 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "execution_count": 34, 311 | "metadata": {}, 312 | "outputs": [ 313 | { 314 | "data": { 315 | "text/plain": [ 316 | "[[0.3676251759151289, -0.43676432026222417, 0.8210290242002757],\n", 317 | " [0.670172238377567, -0.487671520940996, -0.559504833375983],\n", 318 | " [0.6447642212013409, 0.7559189217164602, 0.1134269934788576]]" 319 | ] 320 | }, 321 | "execution_count": 34, 322 | "metadata": {}, 323 | "output_type": "execute_result" 324 | } 325 | ], 326 | "source": [ 327 | "V" 328 | ] 329 | }, 330 | { 331 | "cell_type": "code", 332 | "execution_count": 35, 333 | "metadata": {}, 334 | "outputs": [ 335 | { 336 | "data": { 337 | "text/plain": [ 338 | "[[1.0000000000000184, 1.9999999999999858, 3.000000000000059],\n", 339 | " [2.000000000000036, 3.9999999999999676, 4.999999999999968],\n", 340 | " [3.0000000000000564, 4.999999999999972, 3.0000000000000018]]" 341 | ] 342 | }, 343 | "execution_count": 35, 344 | "metadata": {}, 345 | "output_type": "execute_result" 346 | } 347 | ], 348 | "source": [ 349 | "matmul(matmul(V, E), transpose(V))" 350 | ] 351 | }, 352 | { 353 | "cell_type": "markdown", 354 | "metadata": {}, 355 | "source": [ 356 | "# 특이값 분해" 357 | ] 358 | }, 359 | { 360 | "cell_type": "code", 361 | "execution_count": 11, 362 | "metadata": {}, 363 | "outputs": [], 364 | "source": [ 365 | "def diag(A):\n", 366 | " \"\"\"\n", 367 | " 행렬의 대각행렬\n", 368 | " 입력값: 대각행렬을 구하고자 하는 행렬 A\n", 369 | " 출력값: 행렬 A의 대각행렬 D\n", 370 | " \"\"\"\n", 371 | " n = len(A)\n", 372 | " D = []\n", 373 | " for i in range(0, n):\n", 374 | " row = []\n", 375 | " for j in range(0, n):\n", 376 | " if i==j:\n", 377 | " row.append(A[i][j])\n", 378 | " else:\n", 379 | " row.append(0)\n", 380 | " D.append(row)\n", 381 | " return D" 382 | ] 383 | }, 384 | { 385 | "cell_type": "code", 386 | "execution_count": 36, 387 | "metadata": {}, 388 | "outputs": [], 389 | "source": [ 390 | "def svd(A):\n", 391 | " \"\"\"\n", 392 | " svd를 이용한 고윳값, 고유벡터 구하기\n", 393 | " 입력값: 고윳값, 고유벡터를 구하고자 하는 행렬 A\n", 394 | " 출력값: U = 고유벡터, S = 특이값, Vt = AtA의 고유벡터\n", 395 | " \"\"\"\n", 396 | " At = transpose(A)\n", 397 | " AtA = matmul(At, A)\n", 398 | " E, V = eig_qr(AtA)\n", 399 | " n = len(AtA)\n", 400 | " for i in range(0, n):\n", 401 | " E[i][i] = E[i][i]**0.5\n", 402 | " S = diag(E)\n", 403 | " Vt = transpose(V)\n", 404 | " \n", 405 | " AV = matmul(A, V)\n", 406 | " AVt = transpose(AV)\n", 407 | " Ut = []\n", 408 | " for vector in AVt:\n", 409 | " Ut.append(normalize(vector))\n", 410 | " U = transpose(Ut)\n", 411 | " return U, S, Vt" 412 | ] 413 | }, 414 | { 415 | "cell_type": "code", 416 | "execution_count": 37, 417 | "metadata": {}, 418 | "outputs": [], 419 | "source": [ 420 | "B = [[3,6],[2,3],[1,2],[5,5]]" 421 | ] 422 | }, 423 | { 424 | "cell_type": "code", 425 | "execution_count": 38, 426 | "metadata": {}, 427 | "outputs": [], 428 | "source": [ 429 | "U, S, Vt = svd(B)" 430 | ] 431 | }, 432 | { 433 | "cell_type": "code", 434 | "execution_count": 39, 435 | "metadata": {}, 436 | "outputs": [ 437 | { 438 | "data": { 439 | "text/plain": [ 440 | "[[0.6305881956601931, 0.650700514117642],\n", 441 | " [0.34294607553087336, 0.07207639573280454],\n", 442 | " [0.21019606522006434, 0.21690017137254733],\n", 443 | " [0.6637500515540449, -0.7241188781987142]]" 444 | ] 445 | }, 446 | "execution_count": 39, 447 | "metadata": {}, 448 | "output_type": "execute_result" 449 | } 450 | ], 451 | "source": [ 452 | "U" 453 | ] 454 | }, 455 | { 456 | "cell_type": "code", 457 | "execution_count": 16, 458 | "metadata": {}, 459 | "outputs": [ 460 | { 461 | "data": { 462 | "text/plain": [ 463 | "[[10.50804075992959, 0], [0, 1.606573803987307]]" 464 | ] 465 | }, 466 | "execution_count": 16, 467 | "metadata": {}, 468 | "output_type": "execute_result" 469 | } 470 | ], 471 | "source": [ 472 | "S" 473 | ] 474 | }, 475 | { 476 | "cell_type": "code", 477 | "execution_count": 17, 478 | "metadata": {}, 479 | "outputs": [ 480 | { 481 | "data": { 482 | "text/plain": [ 483 | "[[0.5811362175448531, 0.8138063016822007],\n", 484 | " [-0.8138063016822019, 0.5811362175448509]]" 485 | ] 486 | }, 487 | "execution_count": 17, 488 | "metadata": {}, 489 | "output_type": "execute_result" 490 | } 491 | ], 492 | "source": [ 493 | "Vt" 494 | ] 495 | }, 496 | { 497 | "cell_type": "code", 498 | "execution_count": 18, 499 | "metadata": {}, 500 | "outputs": [ 501 | { 502 | "data": { 503 | "text/plain": [ 504 | "[[3.000000000000032, 5.999999999999975],\n", 505 | " [2.0000000000000098, 2.9999999999999933],\n", 506 | " [1.0000000000000104, 1.9999999999999913],\n", 507 | " [4.999999999999995, 5.000000000000007]]" 508 | ] 509 | }, 510 | "execution_count": 18, 511 | "metadata": {}, 512 | "output_type": "execute_result" 513 | } 514 | ], 515 | "source": [ 516 | "matmul(matmul(U, S), Vt)" 517 | ] 518 | }, 519 | { 520 | "cell_type": "code", 521 | "execution_count": null, 522 | "metadata": {}, 523 | "outputs": [], 524 | "source": [] 525 | } 526 | ], 527 | "metadata": { 528 | "kernelspec": { 529 | "display_name": "Python 3", 530 | "language": "python", 531 | "name": "python3" 532 | }, 533 | "language_info": { 534 | "codemirror_mode": { 535 | "name": "ipython", 536 | "version": 3 537 | }, 538 | "file_extension": ".py", 539 | "mimetype": "text/x-python", 540 | "name": "python", 541 | "nbconvert_exporter": "python", 542 | "pygments_lexer": "ipython3", 543 | "version": "3.8.5" 544 | } 545 | }, 546 | "nbformat": 4, 547 | "nbformat_minor": 4 548 | } 549 | -------------------------------------------------------------------------------- /code/ch13-3.넘파이 대각화.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 고윳값 분해" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 12, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import numpy as np" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 13, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "A = np.array([[1,2,3],[2,4,5],[3,5,3]])" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 15, 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "E, V = np.linalg.eig(A)" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 17, 40 | "metadata": {}, 41 | "outputs": [ 42 | { 43 | "name": "stdout", 44 | "output_type": "stream", 45 | "text": [ 46 | "[ 9.90754321 0.05152112 -1.95906434]\n" 47 | ] 48 | } 49 | ], 50 | "source": [ 51 | "print(E)" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 18, 57 | "metadata": {}, 58 | "outputs": [ 59 | { 60 | "name": "stdout", 61 | "output_type": "stream", 62 | "text": [ 63 | "[[-0.36762518 -0.82102902 -0.43676432]\n", 64 | " [-0.67017224 0.55950483 -0.48767152]\n", 65 | " [-0.64476422 -0.11342699 0.75591892]]\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "print(V)" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "# SVD" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 36, 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "import numpy as np" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 19, 92 | "metadata": {}, 93 | "outputs": [], 94 | "source": [ 95 | "B = [[3,6],[2,3],[1,2],[5,5]]" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 24, 101 | "metadata": {}, 102 | "outputs": [], 103 | "source": [ 104 | "U, S, Vt = np.linalg.svd(B)" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": 25, 110 | "metadata": {}, 111 | "outputs": [ 112 | { 113 | "name": "stdout", 114 | "output_type": "stream", 115 | "text": [ 116 | "[[-0.6305882 0.65070051 -0.34404196 0.24613512]\n", 117 | " [-0.34294608 0.0720764 0.09856768 -0.93138466]\n", 118 | " [-0.21019607 0.21690017 0.9335582 0.19297931]\n", 119 | " [-0.66375005 -0.72411888 -0.01971354 0.18627693]]\n" 120 | ] 121 | } 122 | ], 123 | "source": [ 124 | "print(U)" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": 26, 130 | "metadata": {}, 131 | "outputs": [ 132 | { 133 | "name": "stdout", 134 | "output_type": "stream", 135 | "text": [ 136 | "[10.50804076 1.6065738 ]\n" 137 | ] 138 | } 139 | ], 140 | "source": [ 141 | "print(S)" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 27, 147 | "metadata": {}, 148 | "outputs": [ 149 | { 150 | "name": "stdout", 151 | "output_type": "stream", 152 | "text": [ 153 | "[[-0.58113622 -0.8138063 ]\n", 154 | " [-0.8138063 0.58113622]]\n" 155 | ] 156 | } 157 | ], 158 | "source": [ 159 | "print(Vt)" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": null, 165 | "metadata": {}, 166 | "outputs": [], 167 | "source": [] 168 | } 169 | ], 170 | "metadata": { 171 | "kernelspec": { 172 | "display_name": "Python 3", 173 | "language": "python", 174 | "name": "python3" 175 | }, 176 | "language_info": { 177 | "codemirror_mode": { 178 | "name": "ipython", 179 | "version": 3 180 | }, 181 | "file_extension": ".py", 182 | "mimetype": "text/x-python", 183 | "name": "python", 184 | "nbconvert_exporter": "python", 185 | "pygments_lexer": "ipython3", 186 | "version": "3.8.5" 187 | } 188 | }, 189 | "nbformat": 4, 190 | "nbformat_minor": 4 191 | } 192 | -------------------------------------------------------------------------------- /code/ch14-3.파이썬 LU분해.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 파이썬 LU분해" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 13, 13 | "metadata": {}, 14 | "outputs": [ 15 | { 16 | "name": "stdout", 17 | "output_type": "stream", 18 | "text": [ 19 | "[[2, -2, -2], [0, -2, 2], [-1, 5, 2]]\n" 20 | ] 21 | } 22 | ], 23 | "source": [ 24 | "A = [[2,-2,-2],[0,-2,2],[-1,5,2]]\n", 25 | "print(A)" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 14, 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "n = len(A)\n", 35 | "p = len(A[0])" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 15, 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "a0 = A[0]\n", 45 | "a1 = A[1]\n", 46 | "a2 = A[2]" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 16, 52 | "metadata": {}, 53 | "outputs": [ 54 | { 55 | "name": "stdout", 56 | "output_type": "stream", 57 | "text": [ 58 | "3\n", 59 | "3\n" 60 | ] 61 | } 62 | ], 63 | "source": [ 64 | "print(n)\n", 65 | "print(p)" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 17, 71 | "metadata": {}, 72 | "outputs": [ 73 | { 74 | "name": "stdout", 75 | "output_type": "stream", 76 | "text": [ 77 | "[[0, 0, 0], [0, 0, 0], [0, 0, 0]]\n" 78 | ] 79 | } 80 | ], 81 | "source": [ 82 | "L = [[0]*p for i in range(0, n)]\n", 83 | "print(L)" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 18, 89 | "metadata": {}, 90 | "outputs": [ 91 | { 92 | "name": "stdout", 93 | "output_type": "stream", 94 | "text": [ 95 | "0.5\n", 96 | "2.0\n", 97 | "=============\n", 98 | "[1.0, -1.0, -1.0]\n", 99 | "[0, -2, 2]\n", 100 | "[-1, 5, 2]\n" 101 | ] 102 | } 103 | ], 104 | "source": [ 105 | "# 1행 1열 원소 1로 만들기\n", 106 | "val = 1/a0[0]\n", 107 | "L[0][0] = 1/val\n", 108 | "a0 = [element * val for element in a0 ] \n", 109 | "print(val)\n", 110 | "print(L[0][0])\n", 111 | "print('=============')\n", 112 | "print(a0)\n", 113 | "print(a1)\n", 114 | "print(a2)" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": 19, 120 | "metadata": {}, 121 | "outputs": [ 122 | { 123 | "name": "stdout", 124 | "output_type": "stream", 125 | "text": [ 126 | "[0.0, -0.0, -0.0]\n", 127 | "0\n", 128 | "[0.0, -2.0, 2.0]\n", 129 | "=============\n", 130 | "[1.0, -1.0, -1.0]\n", 131 | "[0.0, -2.0, 2.0]\n", 132 | "[-1, 5, 2]\n" 133 | ] 134 | } 135 | ], 136 | "source": [ 137 | "# 2행 1열 원소 0으로 만들기\n", 138 | "a0_tmp = [element * -a1[0] for element in a0]\n", 139 | "L[1][0] = a1[0]\n", 140 | "print(a0_tmp)\n", 141 | "print(L[1][0])\n", 142 | "\n", 143 | "for i in range(0, len(a0)):\n", 144 | " a1[i] = a0_tmp[i] + a1[i]\n", 145 | "print(a1)\n", 146 | "print('=============')\n", 147 | "print(a0)\n", 148 | "print(a1)\n", 149 | "print(a2)" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": 20, 155 | "metadata": {}, 156 | "outputs": [ 157 | { 158 | "name": "stdout", 159 | "output_type": "stream", 160 | "text": [ 161 | "[1.0, -1.0, -1.0]\n", 162 | "-1\n", 163 | "[0.0, 4.0, 1.0]\n", 164 | "=============\n", 165 | "[1.0, -1.0, -1.0]\n", 166 | "[0.0, -2.0, 2.0]\n", 167 | "[0.0, 4.0, 1.0]\n" 168 | ] 169 | } 170 | ], 171 | "source": [ 172 | "# 3행 1열 원소 0으로 만들기\n", 173 | "a0_tmp = [element * -a2[0] for element in a0]\n", 174 | "L[2][0] = a2[0]\n", 175 | "print(a0_tmp)\n", 176 | "print(L[2][0])\n", 177 | "\n", 178 | "for i in range(0, len(a0)):\n", 179 | " a2[i] = a0_tmp[i] + a2[i]\n", 180 | "print(a2)\n", 181 | "print('=============')\n", 182 | "print(a0)\n", 183 | "print(a1)\n", 184 | "print(a2)" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": 21, 190 | "metadata": {}, 191 | "outputs": [ 192 | { 193 | "name": "stdout", 194 | "output_type": "stream", 195 | "text": [ 196 | "-0.5\n", 197 | "-2.0\n", 198 | "=============\n", 199 | "[1.0, -1.0, -1.0]\n", 200 | "[-0.0, 1.0, -1.0]\n", 201 | "[0.0, 4.0, 1.0]\n" 202 | ] 203 | } 204 | ], 205 | "source": [ 206 | "# 2행 2열 원소 1로 만들기\n", 207 | "\n", 208 | "val = 1/a1[1]\n", 209 | "L[1][1] = 1/val\n", 210 | "a1 = [element * val for element in a1 ] \n", 211 | "print(val)\n", 212 | "print(L[1][1])\n", 213 | "print('=============')\n", 214 | "print(a0)\n", 215 | "print(a1)\n", 216 | "print(a2)" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": 22, 222 | "metadata": {}, 223 | "outputs": [ 224 | { 225 | "name": "stdout", 226 | "output_type": "stream", 227 | "text": [ 228 | "[0.0, -4.0, 4.0]\n", 229 | "4.0\n", 230 | "[0.0, 0.0, 5.0]\n", 231 | "=============\n", 232 | "[1.0, -1.0, -1.0]\n", 233 | "[-0.0, 1.0, -1.0]\n", 234 | "[0.0, 0.0, 5.0]\n" 235 | ] 236 | } 237 | ], 238 | "source": [ 239 | "# 3행 2열 원소 0으로 만들기\n", 240 | "\n", 241 | "a1_tmp = [element * -a2[1] for element in a1]\n", 242 | "L[2][1] = a2[1]\n", 243 | "print(a1_tmp)\n", 244 | "print(L[2][1])\n", 245 | "\n", 246 | "for i in range(0, len(a1)):\n", 247 | " a2[i] = a1_tmp[i] + a2[i]\n", 248 | "print(a2)\n", 249 | "print('=============')\n", 250 | "print(a0)\n", 251 | "print(a1)\n", 252 | "print(a2)" 253 | ] 254 | }, 255 | { 256 | "cell_type": "code", 257 | "execution_count": 23, 258 | "metadata": {}, 259 | "outputs": [ 260 | { 261 | "name": "stdout", 262 | "output_type": "stream", 263 | "text": [ 264 | "0.2\n", 265 | "5.0\n", 266 | "=============\n", 267 | "[1.0, -1.0, -1.0]\n", 268 | "[-0.0, 1.0, -1.0]\n", 269 | "[0.0, 0.0, 1.0]\n" 270 | ] 271 | } 272 | ], 273 | "source": [ 274 | "# 3행 3열 원소 1로 만들기\n", 275 | "\n", 276 | "val = 1/a2[2]\n", 277 | "L[2][2] = 1/val\n", 278 | "a2 = [element * val for element in a2] \n", 279 | "print(val)\n", 280 | "print(L[2][2])\n", 281 | "print('=============')\n", 282 | "print(a0)\n", 283 | "print(a1)\n", 284 | "print(a2)" 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": 24, 290 | "metadata": {}, 291 | "outputs": [ 292 | { 293 | "name": "stdout", 294 | "output_type": "stream", 295 | "text": [ 296 | "[[2.0, 0, 0], [0, -2.0, 0], [-1, 4.0, 5.0]]\n", 297 | "[[1.0, -1.0, -1.0], [-0.0, 1.0, -1.0], [0.0, 0.0, 1.0]]\n" 298 | ] 299 | } 300 | ], 301 | "source": [ 302 | "U = [a0, a1, a2]\n", 303 | "\n", 304 | "print(L)\n", 305 | "print(U)" 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "execution_count": 29, 311 | "metadata": {}, 312 | "outputs": [], 313 | "source": [ 314 | "def matmul(A, B): \n", 315 | " \"\"\"\n", 316 | " 행렬의 행렬곱\n", 317 | " 입력값: 행렬곱을 수행할 행렬 A, B\n", 318 | " 출력값: 행렬 A와 행렬 B의 행렬곱 결과인 행렬 res\n", 319 | " \"\"\"\n", 320 | " n = len(A)\n", 321 | " p1 = len(A[0])\n", 322 | " p2 = len(B[0])\n", 323 | "\n", 324 | " res = []\n", 325 | " for i in range(0, n):\n", 326 | " row = []\n", 327 | " for j in range(0, p2):\n", 328 | " val = 0\n", 329 | " for k in range(0, p1):\n", 330 | " val += A[i][k] * B[k][j] \n", 331 | " row.append(val) \n", 332 | " res.append(row)\n", 333 | " return res" 334 | ] 335 | }, 336 | { 337 | "cell_type": "code", 338 | "execution_count": 30, 339 | "metadata": {}, 340 | "outputs": [ 341 | { 342 | "data": { 343 | "text/plain": [ 344 | "[[2.0, -2.0, -2.0], [0.0, -2.0, 2.0], [-1.0, 5.0, 2.0]]" 345 | ] 346 | }, 347 | "execution_count": 30, 348 | "metadata": {}, 349 | "output_type": "execute_result" 350 | } 351 | ], 352 | "source": [ 353 | "matmul(L, U)" 354 | ] 355 | }, 356 | { 357 | "cell_type": "markdown", 358 | "metadata": {}, 359 | "source": [ 360 | "# 전체 코드" 361 | ] 362 | }, 363 | { 364 | "cell_type": "code", 365 | "execution_count": null, 366 | "metadata": {}, 367 | "outputs": [], 368 | "source": [] 369 | }, 370 | { 371 | "cell_type": "code", 372 | "execution_count": null, 373 | "metadata": {}, 374 | "outputs": [], 375 | "source": [] 376 | }, 377 | { 378 | "cell_type": "markdown", 379 | "metadata": {}, 380 | "source": [ 381 | "# LU 분해 함수 만들기" 382 | ] 383 | }, 384 | { 385 | "cell_type": "code", 386 | "execution_count": 27, 387 | "metadata": {}, 388 | "outputs": [], 389 | "source": [ 390 | "def lu_decomp(A):\n", 391 | " \"\"\"\n", 392 | " LU 분해\n", 393 | " 입력값: 행렬 A\n", 394 | " 출력값: 행렬 A의 LU분해 행렬 L, U\n", 395 | " \"\"\"\n", 396 | " n = len(A)\n", 397 | " p = len(A[0])\n", 398 | "\n", 399 | " L = [[0]*p for i in range(0, n)]\n", 400 | " U = []\n", 401 | "\n", 402 | " for i in range(0, n):\n", 403 | " a = A[i]\n", 404 | " val = 1/a[i]\n", 405 | " L[i][i] = 1/val\n", 406 | " a = [element * val for element in a] \n", 407 | " U.append(a)\n", 408 | "\n", 409 | " for j in range(i+1, n):\n", 410 | " row = A[j]\n", 411 | " a_tmp = [element * -row[i] for element in a]\n", 412 | " L[j][i] = row[i] \n", 413 | " A[j] = [a_tmp[k] + row[k] for k in range(p)]\n", 414 | "\n", 415 | " return L, U" 416 | ] 417 | }, 418 | { 419 | "cell_type": "code", 420 | "execution_count": 28, 421 | "metadata": {}, 422 | "outputs": [ 423 | { 424 | "name": "stdout", 425 | "output_type": "stream", 426 | "text": [ 427 | "[[2.0, 0, 0], [0, -2.0, 0], [-1, 4.0, 5.0]]\n", 428 | "[[1.0, -1.0, -1.0], [-0.0, 1.0, -1.0], [0.0, 0.0, 1.0]]\n" 429 | ] 430 | } 431 | ], 432 | "source": [ 433 | "A = [[2,-2,-2],[0,-2,2],[-1,5,2]]\n", 434 | "\n", 435 | "L, U = lu_decomp(A)\n", 436 | "print(L)\n", 437 | "print(U)" 438 | ] 439 | }, 440 | { 441 | "cell_type": "code", 442 | "execution_count": null, 443 | "metadata": {}, 444 | "outputs": [], 445 | "source": [] 446 | } 447 | ], 448 | "metadata": { 449 | "kernelspec": { 450 | "display_name": "Python 3", 451 | "language": "python", 452 | "name": "python3" 453 | }, 454 | "language_info": { 455 | "codemirror_mode": { 456 | "name": "ipython", 457 | "version": 3 458 | }, 459 | "file_extension": ".py", 460 | "mimetype": "text/x-python", 461 | "name": "python", 462 | "nbconvert_exporter": "python", 463 | "pygments_lexer": "ipython3", 464 | "version": "3.8.5" 465 | } 466 | }, 467 | "nbformat": 4, 468 | "nbformat_minor": 4 469 | } 470 | -------------------------------------------------------------------------------- /code/ch14-4.넘파이 LU분해.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 넘파이 LU분해" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import numpy as np\n", 17 | "from scipy.linalg import lu" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": 7, 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "A = np.array([[2,-2,-2],[0,-2,2],[-1,5,2]])\n", 27 | "P, L, U = lu(A)" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 10, 33 | "metadata": {}, 34 | "outputs": [ 35 | { 36 | "name": "stdout", 37 | "output_type": "stream", 38 | "text": [ 39 | "[[ 1. 0. 0. ]\n", 40 | " [-0.5 1. 0. ]\n", 41 | " [ 0. -0.5 1. ]]\n" 42 | ] 43 | } 44 | ], 45 | "source": [ 46 | "print(L)" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 11, 52 | "metadata": {}, 53 | "outputs": [ 54 | { 55 | "name": "stdout", 56 | "output_type": "stream", 57 | "text": [ 58 | "[[ 2. -2. -2. ]\n", 59 | " [ 0. 4. 1. ]\n", 60 | " [ 0. 0. 2.5]]\n" 61 | ] 62 | } 63 | ], 64 | "source": [ 65 | "print(U)" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": null, 71 | "metadata": {}, 72 | "outputs": [], 73 | "source": [] 74 | } 75 | ], 76 | "metadata": { 77 | "kernelspec": { 78 | "display_name": "Python 3", 79 | "language": "python", 80 | "name": "python3" 81 | }, 82 | "language_info": { 83 | "codemirror_mode": { 84 | "name": "ipython", 85 | "version": 3 86 | }, 87 | "file_extension": ".py", 88 | "mimetype": "text/x-python", 89 | "name": "python", 90 | "nbconvert_exporter": "python", 91 | "pygments_lexer": "ipython3", 92 | "version": "3.8.5" 93 | } 94 | }, 95 | "nbformat": 4, 96 | "nbformat_minor": 4 97 | } 98 | -------------------------------------------------------------------------------- /code/ch16-3.파이썬 텐서.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 텐서의 기초" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 3, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "# 벡터\n", 17 | "x = [1,2]" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": 5, 23 | "metadata": {}, 24 | "outputs": [ 25 | { 26 | "data": { 27 | "text/plain": [ 28 | "1" 29 | ] 30 | }, 31 | "execution_count": 5, 32 | "metadata": {}, 33 | "output_type": "execute_result" 34 | } 35 | ], 36 | "source": [ 37 | "x[0]" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 6, 43 | "metadata": {}, 44 | "outputs": [ 45 | { 46 | "data": { 47 | "text/plain": [ 48 | "2" 49 | ] 50 | }, 51 | "execution_count": 6, 52 | "metadata": {}, 53 | "output_type": "execute_result" 54 | } 55 | ], 56 | "source": [ 57 | "x[1]" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 4, 63 | "metadata": {}, 64 | "outputs": [], 65 | "source": [ 66 | "# 행렬\n", 67 | "A = [[1,2], [3,4]]" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 8, 73 | "metadata": {}, 74 | "outputs": [ 75 | { 76 | "data": { 77 | "text/plain": [ 78 | "1" 79 | ] 80 | }, 81 | "execution_count": 8, 82 | "metadata": {}, 83 | "output_type": "execute_result" 84 | } 85 | ], 86 | "source": [ 87 | "A[0][0]" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 9, 93 | "metadata": {}, 94 | "outputs": [ 95 | { 96 | "data": { 97 | "text/plain": [ 98 | "2" 99 | ] 100 | }, 101 | "execution_count": 9, 102 | "metadata": {}, 103 | "output_type": "execute_result" 104 | } 105 | ], 106 | "source": [ 107 | "A[0][1]" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 11, 113 | "metadata": {}, 114 | "outputs": [ 115 | { 116 | "data": { 117 | "text/plain": [ 118 | "3" 119 | ] 120 | }, 121 | "execution_count": 11, 122 | "metadata": {}, 123 | "output_type": "execute_result" 124 | } 125 | ], 126 | "source": [ 127 | "A[1][0]" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": 12, 133 | "metadata": {}, 134 | "outputs": [ 135 | { 136 | "data": { 137 | "text/plain": [ 138 | "4" 139 | ] 140 | }, 141 | "execution_count": 12, 142 | "metadata": {}, 143 | "output_type": "execute_result" 144 | } 145 | ], 146 | "source": [ 147 | "A[1][1]" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": 13, 153 | "metadata": {}, 154 | "outputs": [], 155 | "source": [ 156 | "# 텐서\n", 157 | "T = [[[1,2], [3,4]], [[5,6], [7,8]]]" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": 14, 163 | "metadata": {}, 164 | "outputs": [ 165 | { 166 | "data": { 167 | "text/plain": [ 168 | "1" 169 | ] 170 | }, 171 | "execution_count": 14, 172 | "metadata": {}, 173 | "output_type": "execute_result" 174 | } 175 | ], 176 | "source": [ 177 | "T[0][0][0]" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 15, 183 | "metadata": {}, 184 | "outputs": [ 185 | { 186 | "data": { 187 | "text/plain": [ 188 | "2" 189 | ] 190 | }, 191 | "execution_count": 15, 192 | "metadata": {}, 193 | "output_type": "execute_result" 194 | } 195 | ], 196 | "source": [ 197 | "T[0][0][1]" 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": 16, 203 | "metadata": {}, 204 | "outputs": [ 205 | { 206 | "data": { 207 | "text/plain": [ 208 | "3" 209 | ] 210 | }, 211 | "execution_count": 16, 212 | "metadata": {}, 213 | "output_type": "execute_result" 214 | } 215 | ], 216 | "source": [ 217 | "T[0][1][0]" 218 | ] 219 | }, 220 | { 221 | "cell_type": "code", 222 | "execution_count": 17, 223 | "metadata": {}, 224 | "outputs": [ 225 | { 226 | "data": { 227 | "text/plain": [ 228 | "4" 229 | ] 230 | }, 231 | "execution_count": 17, 232 | "metadata": {}, 233 | "output_type": "execute_result" 234 | } 235 | ], 236 | "source": [ 237 | "T[0][1][1]" 238 | ] 239 | }, 240 | { 241 | "cell_type": "code", 242 | "execution_count": 18, 243 | "metadata": {}, 244 | "outputs": [ 245 | { 246 | "data": { 247 | "text/plain": [ 248 | "5" 249 | ] 250 | }, 251 | "execution_count": 18, 252 | "metadata": {}, 253 | "output_type": "execute_result" 254 | } 255 | ], 256 | "source": [ 257 | "T[1][0][0]" 258 | ] 259 | }, 260 | { 261 | "cell_type": "code", 262 | "execution_count": 19, 263 | "metadata": {}, 264 | "outputs": [ 265 | { 266 | "data": { 267 | "text/plain": [ 268 | "6" 269 | ] 270 | }, 271 | "execution_count": 19, 272 | "metadata": {}, 273 | "output_type": "execute_result" 274 | } 275 | ], 276 | "source": [ 277 | "T[1][0][1]" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": 20, 283 | "metadata": {}, 284 | "outputs": [ 285 | { 286 | "data": { 287 | "text/plain": [ 288 | "7" 289 | ] 290 | }, 291 | "execution_count": 20, 292 | "metadata": {}, 293 | "output_type": "execute_result" 294 | } 295 | ], 296 | "source": [ 297 | "T[1][1][0]" 298 | ] 299 | }, 300 | { 301 | "cell_type": "code", 302 | "execution_count": 21, 303 | "metadata": {}, 304 | "outputs": [ 305 | { 306 | "data": { 307 | "text/plain": [ 308 | "8" 309 | ] 310 | }, 311 | "execution_count": 21, 312 | "metadata": {}, 313 | "output_type": "execute_result" 314 | } 315 | ], 316 | "source": [ 317 | "T[1][1][1]" 318 | ] 319 | }, 320 | { 321 | "cell_type": "markdown", 322 | "metadata": {}, 323 | "source": [ 324 | "# 텐서의 기본 연산" 325 | ] 326 | }, 327 | { 328 | "cell_type": "markdown", 329 | "metadata": {}, 330 | "source": [ 331 | "## 텐서의 노름" 332 | ] 333 | }, 334 | { 335 | "cell_type": "code", 336 | "execution_count": 2, 337 | "metadata": {}, 338 | "outputs": [], 339 | "source": [ 340 | "A = [ [[1,0,1,0],[2,1,0,1],[3,4,0,2]], \n", 341 | " [[3,1,2,0],[1,0,4,2],[0,1,0,2]] ]" 342 | ] 343 | }, 344 | { 345 | "cell_type": "code", 346 | "execution_count": 3, 347 | "metadata": {}, 348 | "outputs": [ 349 | { 350 | "name": "stdout", 351 | "output_type": "stream", 352 | "text": [ 353 | "[[[1, 0, 1, 0], [2, 1, 0, 1], [3, 4, 0, 2]], [[3, 1, 2, 0], [1, 0, 4, 2], [0, 1, 0, 2]]]\n" 354 | ] 355 | } 356 | ], 357 | "source": [ 358 | "print(A)" 359 | ] 360 | }, 361 | { 362 | "cell_type": "code", 363 | "execution_count": 4, 364 | "metadata": {}, 365 | "outputs": [], 366 | "source": [ 367 | "n = len(A[0])\n", 368 | "p = len(A[0][0])\n", 369 | "q = len(A)" 370 | ] 371 | }, 372 | { 373 | "cell_type": "code", 374 | "execution_count": 5, 375 | "metadata": {}, 376 | "outputs": [ 377 | { 378 | "name": "stdout", 379 | "output_type": "stream", 380 | "text": [ 381 | "3\n", 382 | "4\n", 383 | "2\n" 384 | ] 385 | } 386 | ], 387 | "source": [ 388 | "print(n)\n", 389 | "print(p)\n", 390 | "print(q)" 391 | ] 392 | }, 393 | { 394 | "cell_type": "code", 395 | "execution_count": 6, 396 | "metadata": {}, 397 | "outputs": [], 398 | "source": [ 399 | "norm = 0\n", 400 | "for i in range(0, n):\n", 401 | " for j in range(0, p):\n", 402 | " for k in range(0, q):\n", 403 | " norm += A[k][i][j]**2\n", 404 | "norm = norm**0.5" 405 | ] 406 | }, 407 | { 408 | "cell_type": "code", 409 | "execution_count": 7, 410 | "metadata": {}, 411 | "outputs": [ 412 | { 413 | "name": "stdout", 414 | "output_type": "stream", 415 | "text": [ 416 | "8.774964387392123\n" 417 | ] 418 | } 419 | ], 420 | "source": [ 421 | "print(norm)" 422 | ] 423 | }, 424 | { 425 | "cell_type": "markdown", 426 | "metadata": {}, 427 | "source": [ 428 | "# 텐서의 내적" 429 | ] 430 | }, 431 | { 432 | "cell_type": "code", 433 | "execution_count": 51, 434 | "metadata": {}, 435 | "outputs": [], 436 | "source": [ 437 | "A = [ [[1,0,1,0],[2,1,0,1],[3,4,0,2]], \n", 438 | " [[3,1,2,0],[1,0,4,2],[0,1,0,2]] ]\n", 439 | "\n", 440 | "B = [ [[2,1,3,1],[0,2,1,3],[1,0,1,1]], \n", 441 | " [[1,2,3,1],[3,1,0,3],[0,2,3,1]] ]" 442 | ] 443 | }, 444 | { 445 | "cell_type": "code", 446 | "execution_count": 53, 447 | "metadata": {}, 448 | "outputs": [], 449 | "source": [ 450 | "n = len(A[0])\n", 451 | "p = len(A[0][0])\n", 452 | "q = len(A)" 453 | ] 454 | }, 455 | { 456 | "cell_type": "code", 457 | "execution_count": 54, 458 | "metadata": {}, 459 | "outputs": [], 460 | "source": [ 461 | "inner_product = 0\n", 462 | "for i in range(0, n):\n", 463 | " for j in range(0, p):\n", 464 | " for k in range(0, q):\n", 465 | " inner_product += A[k][i][j]*B[k][i][j]" 466 | ] 467 | }, 468 | { 469 | "cell_type": "code", 470 | "execution_count": 76, 471 | "metadata": {}, 472 | "outputs": [ 473 | { 474 | "name": "stdout", 475 | "output_type": "stream", 476 | "text": [ 477 | "39\n" 478 | ] 479 | } 480 | ], 481 | "source": [ 482 | "print(inner_product)" 483 | ] 484 | }, 485 | { 486 | "cell_type": "markdown", 487 | "metadata": {}, 488 | "source": [ 489 | "# 텐서의 행렬화" 490 | ] 491 | }, 492 | { 493 | "cell_type": "code", 494 | "execution_count": 56, 495 | "metadata": {}, 496 | "outputs": [], 497 | "source": [ 498 | "A = [ [[1,4,7,10],[2,5,8,11],[3,6,9,12]], \n", 499 | " [[13,16,19,22],[14,17,20,23],[15,18,21,24]] ]" 500 | ] 501 | }, 502 | { 503 | "cell_type": "code", 504 | "execution_count": 57, 505 | "metadata": {}, 506 | "outputs": [], 507 | "source": [ 508 | "n = len(A[0])\n", 509 | "p = len(A[0][0])\n", 510 | "q = len(A)" 511 | ] 512 | }, 513 | { 514 | "cell_type": "code", 515 | "execution_count": 58, 516 | "metadata": {}, 517 | "outputs": [ 518 | { 519 | "name": "stdout", 520 | "output_type": "stream", 521 | "text": [ 522 | "3\n", 523 | "4\n", 524 | "2\n" 525 | ] 526 | } 527 | ], 528 | "source": [ 529 | "print(n)\n", 530 | "print(p)\n", 531 | "print(q)" 532 | ] 533 | }, 534 | { 535 | "cell_type": "code", 536 | "execution_count": 61, 537 | "metadata": {}, 538 | "outputs": [], 539 | "source": [ 540 | "mode1 = []\n", 541 | "for i in range(0,n):\n", 542 | " row = []\n", 543 | " for k in range(0,q):\n", 544 | " for j in range(0,p):\n", 545 | " row.append(A[k][i][j])\n", 546 | " mode1.append(row)" 547 | ] 548 | }, 549 | { 550 | "cell_type": "code", 551 | "execution_count": 62, 552 | "metadata": {}, 553 | "outputs": [ 554 | { 555 | "data": { 556 | "text/plain": [ 557 | "[[1, 4, 7, 10, 13, 16, 19, 22],\n", 558 | " [2, 5, 8, 11, 14, 17, 20, 23],\n", 559 | " [3, 6, 9, 12, 15, 18, 21, 24]]" 560 | ] 561 | }, 562 | "execution_count": 62, 563 | "metadata": {}, 564 | "output_type": "execute_result" 565 | } 566 | ], 567 | "source": [ 568 | "mode1" 569 | ] 570 | }, 571 | { 572 | "cell_type": "code", 573 | "execution_count": 63, 574 | "metadata": {}, 575 | "outputs": [], 576 | "source": [ 577 | "mode2 = []\n", 578 | "for j in range(0,p):\n", 579 | " row = []\n", 580 | " for k in range(0,q):\n", 581 | " for i in range(0,n):\n", 582 | " row.append(A[k][i][j])\n", 583 | " mode2.append(row)" 584 | ] 585 | }, 586 | { 587 | "cell_type": "code", 588 | "execution_count": 64, 589 | "metadata": {}, 590 | "outputs": [ 591 | { 592 | "data": { 593 | "text/plain": [ 594 | "[[1, 2, 3, 13, 14, 15],\n", 595 | " [4, 5, 6, 16, 17, 18],\n", 596 | " [7, 8, 9, 19, 20, 21],\n", 597 | " [10, 11, 12, 22, 23, 24]]" 598 | ] 599 | }, 600 | "execution_count": 64, 601 | "metadata": {}, 602 | "output_type": "execute_result" 603 | } 604 | ], 605 | "source": [ 606 | "mode2" 607 | ] 608 | }, 609 | { 610 | "cell_type": "code", 611 | "execution_count": 65, 612 | "metadata": {}, 613 | "outputs": [], 614 | "source": [ 615 | "mode3 = []\n", 616 | "for k in range(0,q):\n", 617 | " row = []\n", 618 | " for j in range(0,p):\n", 619 | " for i in range(0,n):\n", 620 | " row.append(A[k][i][j])\n", 621 | " mode3.append(row)" 622 | ] 623 | }, 624 | { 625 | "cell_type": "code", 626 | "execution_count": 66, 627 | "metadata": {}, 628 | "outputs": [ 629 | { 630 | "data": { 631 | "text/plain": [ 632 | "[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],\n", 633 | " [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]]" 634 | ] 635 | }, 636 | "execution_count": 66, 637 | "metadata": {}, 638 | "output_type": "execute_result" 639 | } 640 | ], 641 | "source": [ 642 | "mode3" 643 | ] 644 | }, 645 | { 646 | "cell_type": "markdown", 647 | "metadata": {}, 648 | "source": [ 649 | "# 텐서 곱" 650 | ] 651 | }, 652 | { 653 | "cell_type": "code", 654 | "execution_count": 67, 655 | "metadata": {}, 656 | "outputs": [], 657 | "source": [ 658 | "U = [[1,3,5],[2,4,6]]\n", 659 | "\n", 660 | "A = [ [[1,4,7,10],[2,5,8,11],[3,6,9,12]], \n", 661 | " [[13,16,19,22],[14,17,20,23],[15,18,21,24]] ]" 662 | ] 663 | }, 664 | { 665 | "cell_type": "code", 666 | "execution_count": 70, 667 | "metadata": {}, 668 | "outputs": [], 669 | "source": [ 670 | "n1 = len(U)\n", 671 | "p1 = len(U[0])\n", 672 | "\n", 673 | "n2 = len(A[0])\n", 674 | "p2 = len(A[0][0])\n", 675 | "q2 = len(A)" 676 | ] 677 | }, 678 | { 679 | "cell_type": "code", 680 | "execution_count": 71, 681 | "metadata": {}, 682 | "outputs": [ 683 | { 684 | "name": "stdout", 685 | "output_type": "stream", 686 | "text": [ 687 | "2\n", 688 | "3\n" 689 | ] 690 | } 691 | ], 692 | "source": [ 693 | "print(n1)\n", 694 | "print(p1)" 695 | ] 696 | }, 697 | { 698 | "cell_type": "code", 699 | "execution_count": 73, 700 | "metadata": {}, 701 | "outputs": [ 702 | { 703 | "name": "stdout", 704 | "output_type": "stream", 705 | "text": [ 706 | "3\n", 707 | "4\n", 708 | "2\n" 709 | ] 710 | } 711 | ], 712 | "source": [ 713 | "print(n2)\n", 714 | "print(p2)\n", 715 | "print(q2)" 716 | ] 717 | }, 718 | { 719 | "cell_type": "code", 720 | "execution_count": 74, 721 | "metadata": {}, 722 | "outputs": [], 723 | "source": [ 724 | "tensor_product = []\n", 725 | "for k in range(0, q2):\n", 726 | " sub_matrix = []\n", 727 | " for i in range(0, n1):\n", 728 | " row = []\n", 729 | " for j2 in range(0,p2):\n", 730 | " val = 0\n", 731 | " for j1 in range(0,p1):\n", 732 | " val += U[i][j1]*A[k][j1][j2]\n", 733 | " row.append(val)\n", 734 | " sub_matrix.append(row)\n", 735 | " tensor_product.append(sub_matrix)" 736 | ] 737 | }, 738 | { 739 | "cell_type": "code", 740 | "execution_count": 75, 741 | "metadata": {}, 742 | "outputs": [ 743 | { 744 | "data": { 745 | "text/plain": [ 746 | "[[[22, 49, 76, 103], [28, 64, 100, 136]],\n", 747 | " [[130, 157, 184, 211], [172, 208, 244, 280]]]" 748 | ] 749 | }, 750 | "execution_count": 75, 751 | "metadata": {}, 752 | "output_type": "execute_result" 753 | } 754 | ], 755 | "source": [ 756 | "tensor_product" 757 | ] 758 | }, 759 | { 760 | "cell_type": "code", 761 | "execution_count": null, 762 | "metadata": {}, 763 | "outputs": [], 764 | "source": [] 765 | } 766 | ], 767 | "metadata": { 768 | "kernelspec": { 769 | "display_name": "Python 3", 770 | "language": "python", 771 | "name": "python3" 772 | }, 773 | "language_info": { 774 | "codemirror_mode": { 775 | "name": "ipython", 776 | "version": 3 777 | }, 778 | "file_extension": ".py", 779 | "mimetype": "text/x-python", 780 | "name": "python", 781 | "nbconvert_exporter": "python", 782 | "pygments_lexer": "ipython3", 783 | "version": "3.8.5" 784 | } 785 | }, 786 | "nbformat": 4, 787 | "nbformat_minor": 4 788 | } 789 | --------------------------------------------------------------------------------