Chapter 1, 벡터와 점 #1

게임&인터렉티브 애플리케이션을 위한 수학 2012. 2. 7. 14:09
1. Vectors

1.1 기하학에서의 벡터

기하학에서 벡터란 크기(길이)와 방향을 갖는 실체(entity) 를 말합니다.
크기가 0 이고 방향이 없는 벡터를 영벡터(zero vector) 라고 하고,
크기가 1 인 벡터를 unit 또는 normalized 벡터라고 부릅니다.

벡터는 그림으로 그리면 한쪽 끝에 화살표가 표시된 선분이며,
벡터는 위치의 개념이 없기 때문에 크기와 방향이 동일하면 같은 벡터입니다.
따라서 다음 4개의 벡터중 처음과 마지막은 동일한 벡터입니다.



벡터는 다음과 같은 대수학적 성질을 갖습니다.

1) v + w = w + v
 

 

2) u + (v + w) = (u + v) + w


3) v + 0 = v
4) 모든 벡터 v 에 대해서 v + (-v) = 0 이 되는 -v 가 존재.
5) (ab)v = a(bv)
6) (a+b)v = av + bv 
7) a(v + w) = av + aw
8) 1 · v = v

1.2 선형 결합 (Linear Combinations)

n 개의 벡터로 구성된 S 를 가정 할 때 다음과 같이 임의의 스칼라 a0~an-1 를 곱하여 더함으로써
새로운 벡터 v 를 만들어내는 것을 선형 결합 이라고 합니다.
 

v = a0v0 + a1v1 + ... + an-1vn-1



그림 처럼 S 로 부터 가능한 모든 선형 결합을 통해 새로운 벡터셋 T 를 만들게 되면
이 T 는 S 의 span 이 됩니다.

span 의 정의(위키백과) :
Given a vector space V over a field K, the span of a set S (not necessarily finite) is
defined to be the intersection 
W of all subspaces of V which contain S
W is referred to as the subspacespanned by S, or by the vectors in S.
Conversely, 
S is called a spanning set of W 
더하기(addition)와 곱하기(multiplication) 에 닫힌 영역(field) k 위의 벡터 공간 V 가 주어졌을 때,
벡터셋 S(꼭 유한할 필요는 없음)의 span 은 S 를 포함하는 V 의 모든 부분공간 W 의 교집합으로
정의됩니다.

(x축과 y축으로 구성되는) 2 차원 평면을 예로 들어 보면
평면상의 벡터들로 어떤식으로 지지고 볶든간에 선형결합의 결과 벡터는
결국 평면 안의 벡터라는 말입니다.


선형 결합 시 스칼라 조합 당 단 한개의 새로운 벡터 vi (0 벡터를 제외)가 만들어 질 때,
우리는 vi 로 이루어진 벡터 셋 S 를 선형 종속적이라고 합니다.

vi = a0 v0 +· · ·+ai−1 vi−1 + ai+1 vi+1 +· · ·+an−1 vn−1  

달리 말하면, 위 식을 만족하는 어떤 vi 도 찾을 수 없다면
v0, ... , v
n-1
벡터셋은 선형 독립적이라고 합니다.

1.3 벡터의 표현 (Vector Representation)

symbolic mathematics ( 회로도 같은 모형으로 함수를 표현하거나 하는 그런.. ) 와
컴퓨터에서 벡터를 그림으로 표현하는 것은 다루기가 불편합니다.
컴퓨터에서 우리가 벡터를 잘 다루기 위해서 3차원의 경우 다음과 같은 표현 방식을 고안해 냈습니다.

v = xi + yj + zk

여기서 i, j, k 는 서로 직교하는 유닛 벡터이고
x, y, z 는 각 방향에 대한 벡터의 크기를 나타냅니다.
그림으로 보면 다음과 같습니다.


이런 식으로 3D 공간 상의 임의의 벡터 v 는 x,y,z 의 순서쌍으로 표현될 수 있습니다.
잘 알려진 바와 같이 여기서 사용하는 기저 벡터 i, j, k 는  (1,0,0) , (0,1,0) , (0,0,1) 로
나타낼 수 있습니다. 


이와 같은 표현을 통해서 우리는 기하적 벡터들을 대수적으로 표현해 낼 수 있게 됩니다.
3D 공간 상의 벡터 v0v1 의 합은 다음과 같습니다.


두 벡터를 더하는 것은 다음과 같이 각각의 요소를 합하는 것과 같습니다.


벡터의 스칼라배 역시 비슷하게 생각할 수 있습니다.



Continue to Next..
 
:

C++11, Lambda Expressions #2

Short Articles 2012. 2. 1. 18:52
앞 글에 이어 우선 lambda-declarator 부분을 잠시 보고, capture 와 관련된 부분들을 다시 살펴 보겠습니다.

+ lambda-declarator
lambda-declarator 는

(파라미터 선언 절) mutable exception-specification attribute-specification trailing-return-type


의 형식으로 작성되고,
이 중에서 (파라미터 선언 절) 외의 부분들은 필요에 따라 적어주면 되는 부분들입니다.
lambda-declarator 에 포함된 사항들은 C++ lambda 의 새롭게 추가된 사항이 아닌 기존 C++ 에 이미 정의된 사항들 이므로 자세한 내용은 생략 하겠습니다.

간단한 예시 코드,
이 람다식이 포함하는 closure object 는 ecode 변수를 copy 로 capture 합니다.
mutable 키워드는 capture 를 compound-statement 내에서 수정 가능함을 나타내고,
뒤따라오는 throw(int) 는 int type 의 예외를 던진다는 것을 알립니다. ->int 는 compound-statement 의
리턴 타입이 int 형임을 지정합니다.

[=](char const *s) throw(int) ->int ...  와 같이 mutable 키워드를 지정하지 않는 경우
closure 에서 public 으로 선언(정의)되는 function call operator 는 기본 const 입니다.

다시 capture 관련 이야기로 돌아가서...

local-lambda expression
block scope 바로 아래 범위에 닿아 있는 람다 표현식을 local lambda expression 이라고 합니다.
local lambda expression 의 영향 범위는 자신의 한겹 위쪽 블럭과 아래쪽으로 포함되는 영역 입니다.
(함수와 함수의 파라미터를 포함해서..)
이 유효 범위 사이에는 또다른 람다 표현식이 끼어들 수도 있습니다.


위 코드에서 람다 표현식의 범위는 PrintPoint 함수의 블럭과 표현식이 포함하고 있는 출력 코드 부분입니다.
이 경우  name 은 local lambda expression 의 유효 범위 밖에 있기 때문에 에러가 납니다.
이 때에는 명시적으로 this 를 capture 하거나 PrintPoint 의 지역 변수로 const char* 하나를 선언해서
name 의 값을 받은 후 이것을 명시적으로 capture 하는 식으로 에러를 피할 수 있습니다.

lambda 표현식의 capture-list 에 대한 name look up 은 일반적인 unqualified name look up
(:: , std:: , boost::  등으로 특정 짓지 않은 entitiy 에 대한 name look up) 에 따릅니다. 
각각의 룩업은 local lambda expression 의 유효 범위 내에서 automatic storage duration 으로
선언된 변수를 찾습니다.

automatic storage duration :
자동으로 생명주기가 관리되는 것들을 말한다. variable with automatic storage duration 이라 하면,
C++ 에서는 주로 stack 에 생성되는 지역 변수등을 일컫는다.

 
ODR & lambda-expression

(참고. cl.exe 는 아직 implicitly capture 를 제대로 지원하지 못 하고 있습니다. )

람다 표현식이 capture-default 를 포함하고 표현식의 odr 사용이 this 나 automatic storage duration
변수 그리고 odr이 사용된 entity 가 명시적으로 캡처(explicitly capture)되지 않았다면,
odr이 사용된 entity 는 임시적으로 캡처(implicitly capture) 되었다고 합니다.

다음은 표준 문서에 나오는 implicitly capture 에 대한 예제 코드 입니다.
코드 작성과 테스트는 eclipse with g++4.6.2 로 했습니다.
이 코드를 컴파일하면 다음과 같은 에러를 보게 됩니다.

../src/hello.cpp: In lambda function:

../src/hello.cpp:38:18: error: 'j' is not captured

../src/hello.cpp: In lambda function:

../src/hello.cpp:39:14: error: 'n' is not captured

../src/hello.cpp:43:11: error: 'i' is not captured

../src/hello.cpp: In lambda function:

../src/hello.cpp:45:5: error: unable to deduce 'auto' from '<expression error>'


N 과 M 은 m1 에 의해서 implicitly capture 되었기 때문에 괜찮지만,
j 는 m3 에 의해서 캡처 되지 않았고 n 은 m4 에 의해서는 implicitly capture 되지만
m4 를 둘러싸고 있는 m3 가 n 을 캡처 하지 않았기 때문에 에러입니다.
그리고 i 는 유효범위 밖에 있으므로 역시 에러가 나고 있습니다.

다음과 같이 명시적으로 n, j 를 캡처하고 x += i; 를 주석 처리 하면
에러없이 컴파일 되는 것을 확인할 수 있습니다.
 
기본 인자로 lambda-expression 이 올 때, 어떤 entity 도 명시적이든 암시적이든 캡처할 수 없습니다.
이 부분은 개인적으로 그다지 중요한 부분은 아니라고 생각하는데,
아무튼 람다 표현식이 기본인자로 쓰일 경우 

void foo(int = ( []{ return 0;}() ));

처럼 상수식이 반환되는 경우는 ok 지만 어떤 것이든 캡처를 하는 경우는 에러입니다.
별다른 내용은 없습니다.

entity - captured by copy
entity 가 implicitly capture 되었고 capture default 가 '=' 이거나
entity 가 explicitly capture 되었고 '&' 를 포함하지 않으면,
이 entity 는 copy 로 캡처 되었다고 합니다.

by copy 로 capture 캡처된 entity 는 closure 의 non-static unnamed 데이터 멤버로 선언됩니다.
이 때, 선언되는 순서에 정해진 규칙은 없습니다. entity 가 객체나 그 밖의 타입에 대한 참조가
아닐 경우 이렇게 되며, int &p = value; 에서의 p 같은 참조 변수는 captured by copy 되지 않습니다.

entity - captured by reference 
명시적으로 또는 암시적으로 캡처되지만 copy 로 캡처되지 않는 entity 는 reference 로 캡처됩니다.

nested lambda expressions 에서 한 표현식을 다른 표현식이 바로 둘러 싸는 경우
표현식 m1이 m2 를 둘러 싸고 있다고 할 때,
m1 이 by copy 로 캡처한 entity 는 m1 의 closure 타입의 non-static data member 에 대응되는 것으로
m2 에 캡처됩니다. 그리고 m1 이 by reference 로 캡처한 entity 는 m1 이 캡처한 것과 동일한 entity 로
m2 가 캡처합니다.
이 코드의 결과 값은 다음과 같습니다.

123234



 
람다 표현식에 대한 글은 여기서 이만 줄이겠습니다.
표준 문서에 몇 가지 추가적인 사항에 대한 설명이 나오므로 더 자세한 사항을 원하시는 분은
표준 명세를 찾아보시기 바랍니다.
 
:

Chapter 2, 선형 변환과 행렬

게임&인터렉티브 애플리케이션을 위한 수학 2012. 1. 30. 23:13








이 챕터 에서는 행렬이 어떻게 벡터를 다른 공간으로 변환하는 것이 가능한지를 알아보고 반대로 변환하는 역행렬에 대해서 배웁니다. 개인적으로 이 챕터는 이해하기 너무 어렵기 때문에 차라리 넘어가는 것을 추천 드립니다.(ㅎㅎ...)

이 챕터의 순서는 이렇습니다.

1. 용어를 배웁니다.
   - 기저 벡터
   - 정의역, 치역
   - 영공간
   - 변환 = n차원에서 m차원으로 이동 시킬 수 있는 함수
2. 행렬의 모양에 대해서 배웁니다.
   - 행렬은 2차원 숫자들의 배열
   - 주대각
   - 상삼각, 하삼각
   - 대각 행렬
   - 대칭 행렬(전치)
3. 행렬의 연산에 대해 배웁니다.
   - 덧셈
   - 스칼라와 곱셈
   - 행렬 과 행렬의 곱셈
   - 전치
   - 블록행렬
   - 행렬끼리 곰셈에서는 교환법칙이 성립하지 않는다.
4. 벡터 역시 행렬이라는 것은 배웁니다.
5. 선형 방정식을 행렬로 표현하는 방법을 배웁니다.
6. 역행렬을 구하는 방법을 배웁니다.
   - 역행렬의 정의 : 항등 행렬을 사용합니다.
   - 가우스 소거법을 이용
   - 판별식과 여인수 행렬을 이용
7. 부록CD 의 Matrix33, Matrix44 의 Invers() 를 참고 하면서 편리함에 감동을 먹습니다.
   - 결과는 알지만 설명할 수 없습니다. OTL

좌절하지마시고
다음 챕터로 넘어갑니다.

: