어데이드 2018. 6. 2. 14:25

4.행렬

4.1 행렬의 정의

4.1.1 정의

- 행렬(matrix): 행(row)과 열(column)이 있는 격자모양 배열 안에 스칼라를 나열한 것

- 요소(element): 행렬 안에 나열된 스칼라

- 대각 요소(diagonal element): 행렬요소 mij에 대해 i=j인 요소

4.1.2 행렬의 종류

- 정사각행렬(square matrix): 행과 열의 수가 같은 행렬

- 대각행렬(diagonal matrix): 정사각행렬이고 대각 요소 이외의 요소가 모두 0인 행렬

- 단위행렬(identity matrix): 대각요소가 모두 1인 대각행렬

- 영행렬(zero/null matrix): 모든 성분이 0인 행렬

- 열벡터와 행백터는 벡터로서는 같음, 행렬로서는 다름

4.2 행렬의 연산

4.2.1 행렬과 행렬의 연산

- 유니티 Matrix4x4 클래스는 행렬 곱 계산만 지원

- 행렬의 곱셈은 A의 열수와 B의 행수가 같은 경우만 정의 됨

- M=AB의 요소 eij는 다음과 같이 정의

  

- 행렬의 곱은 각각의 행벡터와 열벡터의 내적이 되는 형식으로 나타낼 수 있음

- 교환법칙X, 결합법칙O

- 단위행렬은 다른 행렬과 곱해도 곱해진 행렬이 변화하지 않는다는 특별한 성질 만족

  AI = IA = A

4.2.2 전치행렬

- 전치행렬(transpose): M의 mij와 mji를 바꿔넣은 행렬 M^T

- M이 대각행렬인 경우 M^T=M

- (M^T)^T = M

- (MN)^T = N^T M^T

- 행벡터와 열벡터를 서로를 전치한 것

- 열벡터 v와 열벡터 w의 내적을 행렬끼리의 곱 v^T w로 표현가능

4.2.3 역행렬

- 역행렬(inverse): MM^-1 = M^-1 M = I

- 정사각행렬로만 구할 수 있음

- 단위행렬 I의 역행렬의 자기 자신

- 가역행렬(invertible~) / 정칙행렬(regular~): 역행렬이 존재하는 행렬

- (M^-1)^-1 = M

- (MN)^-1 = N^-1 M^-1

- (M^T)^-1 = (M^-1)^T

4.2.4 행렬과 벡터의 곱셈

- (vM)^T = M^T v^T

- (u+v)M = uM + vM

- (((vM)N)P)^T = P^T (N^T (M^T v^T))

4.2.5 스위즐 연산

- 스위즐(swizzle) 연산: 행렬과 벡터의 곱으로 벡터의 성분을 변경하는 연산

- 부울 행렬(boolean matrix): 0과 1요소만으로 구성된 행렬

- 산포 스위즐(broadcast swizzle): 성분 중 하나를 벡터 전체에 벌여놓는 스위즐 연산

- 벡터 연산을 위해 CPU에 내장된 SIMD (single instruction multiple data) 명령 세트와

   GPU 프로그래밍을 위한 셰이딩 언어에 구현된 경우가 많음

4.2.6 행우선과 열우선

- 행우선(row major) 방식: 행렬의 1행씩 1차원 배열에 채워짐

- 열우선(column major) 방식: 1열씩 1차원 배열에 채워짐

- Unity의 matrix4x4는 열우선

- C/C++은 행우선

- Mv에서 M의 각 행과 v와의 내적으로 Mv의 각 성분을 구한 경우 M의 각 행에 엑세스가 발생하므로 행우선이 유리

- Mv를 M과 v^T 산포 스위즐 연산의 아다마르 곱(Hadamard product)으로 구하면

  Mv = v1^T c1 + v2^T c2 + ... + vn^T cn

  이 방법을 사용할 때는 열우선이 유리

4.2.7 AoS와 SoA

- AoS(Array of Structures), SoA(Structure of Array)

- 멤버 변수 x, y, z, w를 가진 구조체 4개가 있다고 했을 때

- 구조체의 배열(AoS): 행우선으로 처리하면 x0, y0, z0, w0이라는 

  4가지 다른 종류의 데이터를 가진 구조체를 요소로 하는 배열의 요소를 차례로 처리해나가게 됨

  벡터 연산을 적용하려면 처리 커널이 분산된 메모리 주소를 

  읽기/쓰기(gather/scatter) 해야 하므로 메모리에 랜덤하게 엑세스함

  처리를 요청하고 나서 결과가 돌아오기까지의 레이턴시(latency)가 늘어나 성능저하

  CPU에 구현된 SIMD 연산명령 때문에 메모리 패딩과 얼라인먼트 조정이 필요하므로 불필요한 공간 발생가능

- 배열의 구조체(SoA): 열우선으로 처리하면 x0, x1, x2, x3 처럼 배열/벡터로서

  각 성분에 같은 연산을 적용하여 일괄 처리하므로 그 배열을 멤버로서 여러 개 묶은 구조체를 전체로 봄

  그리고 구조체의 각 멤버를 차례로 처리

  최근 CPU는 스트림 프로세싱 기법으로 대량의 데이터를 처리하기 위해 

  1명령으로 복수의 같은 종류 데이터(벡터)를 처리하는 SIMD 명령 구현

  단 SoA데이터에 랜덤 엑세스가 많이 발생하면 같은 캐시 라인에 관련 데이터를 두기 어려워

  공간적 소속성이 낮아지며 캐시스래싱이 일어나기 쉬워져 성능 저하

- 캐시스래싱(cache thrashing): 캐시 내용의 교체가 빈번히 일어나 캐시를 사이에 두는 의미가 손상되는 것

4.2.8 행렬식

- 행렬식(determinant): 행렬을 수식으로 간주해 스칼라 값을 얻는 것

  정사각행렬만 정의

- det(A) 또는 | A |로 표기

- 두 행 또는 열을 교환하면 부호 반전

- 어떤 행 또는 열을 상수배하면 행렬식이 같은 상수배 됨(다중선형성)

- | I | = 1

- |A^T| = |A|

- |A^-1| = 1/|A| = |A|^-1

- |A| |B| = |AB|

- 여인수(cofactor)전개: 임의의 정사각생렬의 행렬식을 구하는 식

- 소행렬식(minor) Mij: n x n 행렬 A에서 i행과 j열을 제거한 (n-1) x (n-1) 행렬의 행렬식

- 여인수 Cij: (-1)^(i+j) Mij

- 여인수를 이용한 A의 행렬식

  i와 j는 어떤 행이나 열을 선택해도 결과가 바뀌지 않음

- 2, 3차원 정사각행렬은 미리 식을 준비하는 것이 좋음

- 행렬식의 기하학적 의미

  2 x 2 행렬식: (0,0), (a,b), (c,d), (a+c,b+d)를 정점으로 하는 평행사변형의 면적

  3 x 3 행렬식: 스칼라 삼중적(scalar triple product): a · (b x c)

- 스칼라 삼중적 vs 벡터 삼중적: 스칼라 삼중적은 벡터 a, b, c를 어느 순서로 끼워넣든 값이 변하지 않음

  a · (b x c) = b · (c x a) = c · (a x b)

- 행렬식으로 얻는 것은 부포가 있는 체적이고, 유사벡터처럼 좌표계에 따라 부포를 바꾸므로

  유사스칼라(pseudo scalar)로 불림

- a,b,c가 선형종속인지 행렬식=0 여부로 판별 가눙

4.2.9 직교행렬

- 직교행렬(orthogonal matrix): 자신과 전치행렬의 곱이 I인 행렬

  M^T M = M M^T = I

  M^T = M^-1

- 즉 직교행렬을 단순히 전치하면 역행렬을 얻을 수 있음

- 어느 열벡터/행벡터를 두 개 추출하더라도 두 내적은 0(=직교한다)

- |M^T M| = |M|^2 = 1

  즉 |M| = 1 또는 -1

- 특수직교행렬(special orthogonal matrix): 행렬식이 1이 되는 직교행렬

  어떤 행과 열도 정규화된 크기 1인 단위벡터로서 다룰 수 있음

  또한 행끼리, 열끼리는 수직

- 서로 수직인 단위벡터라는 의미에서 특수직교행렬의 각 행과 열은 정규직교기저(orthogonal basis)라 불림

  정규직교기저는 직교좌표계의 기저