1. 행렬의 기본연산

우리는 학교에서 방정식을 푸는 방법에 대해 배울 때, 등식에 대해 너무 당연해 보이는 원리를 배운다.
등식의 양변에 같은 수를 더하거나 빼거나 곱하거나, 나누더라도(비영) 등식은 성립한다는 거.

이건 사실 너무 당연한 얘기이다. 이미 값이 같은 두 수에다가 동일한 수로 동일한 연산을 하면 그 결과도 서로 일치할 수밖에 없다. 그런데 그 당연한 이치만 이용해서 복잡한 방정식을 푸는 게 수학의 묘미이다.
등식의 좌변과 우변을 마법 같이 변형하고 복잡한 항을 옮기거나 없애고, 궁극적으로 좌변에 x 하나만 남기니까 말이다.

그런데 행렬을 다루는 선형대수학으로 가면 이와 비슷한 방법론이 또 등장한다. 이른바 행렬을 줄 단위로 변형하는 기본 연산 말이다.
저 줄이라는 게 가로줄(row 행)인지 세로줄(col 열)인지는 중요하지 않다. 행렬에서 임의의 두 줄을 뽑아서 한 줄의 숫자를 그대로 또는 스칼라(상수)배 한 뒤, 다른 줄에다가 그대로 더해 준다. 두 벡터 A, B에 대해서 A = A + n*B 같은 셈이다.

행렬이라는 건 그냥 방정식이 아니라 변수도 여러 개, 식도 여러 개인 연립방정식을 풀기 위해 도입된 물건이다.
연립방정식을 풀기 위해서 우리가 하는 일은 식에서 변수를 하나씩 소거하는 것이다.
어떤 식은 x y z 변수가 모두 등장하지만 다음 식은 x를 소거하여 y z만 남기고, 마지막 식은 z만 남기고..
그러면 그 z를 y-z 식에다가 대입해서 y를 구하고, 이걸 x-y-z 식에다가 대입해서 x까지 모두 구하면 된다.

이 과정이 행렬로 치면 '삼각화'이다. 행렬이 나타내는 방정식의 특성(= 근)을 변형하지 않으면서 0이 아닌 숫자를 행렬의 반쪽에다가만 남기는 것이다.
그리고 그렇게 삼각화하는 수단이 바로 저 줄 단위 기본연산이다. 없애고 싶은 칸의 숫자를 스칼라배를 통해 동기화시키고 나서 빼 주면 그 칸은 0이 되어 소거된다.

행렬의 기본연산의 묘미는 바로..
한 줄 내용의 상수 배를 딴 줄에다가 아무리 더해 주더라도 행렬 내지 방정식의 전체 특성이 전혀 바뀌지 않는다는 것이다. 특히 그 행렬의 행렬식의 값이 변하지 않는다. 오로지 자기 자신을 상수 배 했을 때만 행렬식 값에도 그 배율이 반영된다.

왜? xyz축을 각각 가리키는 단위 벡터들을 생각해 보자. z축을 1만치 향하는 벡터에다가 완전히 다른 방향인 x, y축을 가리키는 벡터를 제아무리 더해 줘도 z축 방향은 영향을 받지 않는다.
커버하는 벡터 공간이 정육면체이던 것이 찌그러진 평행육면체가 될지언정, 그 육면체의 부피가 바뀌지는 않는다는 걸 생각하면 이해에 도움이 될 것이다. 오로지 z축 자체의 크기를 키워야만 육면체의 부피가 바뀔 것이다.

이 기본연산으로부터 유도 가능한 재미있는 특성이 또 있다.
행렬에서 서로 다른 임의의 두 줄을 맞바꾸는, 다시 말해 교환하는 것을 저 기본연산들의 조합으로 구현할 수 있다. 그리고 이렇게 교환을 하면 행렬식 값이 부호가 바뀐다.

  • 임의의 두 줄 (A,B)가 있는데 먼저 A줄에다가 B줄 내용을 빼서 (A-B,B)를 만든다.
  • 그 뒤 B에다가 지금 A줄의 값이 돼 있는 A-B를 더해 주면 B가 소거되어 (A-B,A)가 되고..
  • A-B가 돼 있는 A줄에다가 지금 B줄의 값인 A를 빼면 (-B,A)가 된다.
  • 이제 -B에다가 -1을 곱하면 (A,B)가 (B,A)로 교환이 완료되고.. 이때 행렬식의 부호도 -1이 곱해지면서 바뀐다. 이런 원리 때문이다. =_=;;

이 바닥에서는 피연산자의 순서가 바뀌면 결과의 부호가 달라지는 연산을 심심찮게 보는 것 같다. 벡터곱(외적)이라든가, 사원수 i,j,k끼리의 곱 같은 거 말이다. 행렬의 줄 교환 기본연산도 그런 축에 드는 셈이다.

2. 두 변수 교환

그리고 위의 저 로직은 컴퓨터 코딩깨나 하는 분들에게는 꽤 낯익을 것이다.
임시 변수를 사용하지 않고 두 변수 값을 맞바꾸는 swap 알고리즘과 개념적으로 일맥상통하기 때문이다. 즉, C 코드로 치면 아래 식을 적용한 거나 마찬가지이다. ㄲㄲㄲㄲㄲㄲㄲ

a -= b, b += a, a -= b; a=-a;

물론, 코딩을 할 때는 꼭 합성 대입 연산자에만 집착할 필요는 없으니, 피연산자의 배치 순서를 바꿔서 부호 전환을 축약시키곤 한다.

a += b, b = a-b, a = a-b;

덧셈과 뺄셈 대신, 곱셈과 나눗셈을 써도 되기는 한다. 그러나 이건 실용성이 최악이다.
그렇잖아도 임시 변수 안 쓰는 swap 자체가 실무에서는 딱히 쓰이지는 않고 "이런 테크닉도 있다" 수준으로 짚고 넘어가는 잉여이다. 근데 하물며 swap을 위해서 덧셈-뺄셈보다도 더 무거운 곱셈과 나눗셈이라고??
오버플로 가능성, 피연산자에 0이 있을 때의 문제, 부동소수점인 경우에는 오차 문제.. 정말 할 짓이 못 된다.

사실, 컴퓨터의 입장에서 이런 맞교환 용도로 덧셈· 뺄셈보다도 더 낫고 최고 적합한 연산자는 바로 비트 xor이다. 얘는 같은 피연산자를 두 번 적용하면 도로 원래 숫자로 돌아온다는 마법 같은 특성이 있기 때문이다. (A ^ B)^B = A 다시 말해 xor은 항등원이 0이고 역원은 걍 자기 자신.. 그래서 프로그래머라면 잘 아시다시피

a ^= b, b ^= a, a ^= b;

정말 매끄럽고 단순한 합성 대입 연산자 3방으로 swap이 바로 구현된다. 컴퓨터의 입장에서 xor은 산술 연산보다 속도도 더 빠르며, overflow 문제도 전무하니.. 가히 최적이다.

다만, 다시 얘기하지만 임시 변수 안 쓰는 swap은 실용성이 별로 없다.
연산이 병렬화 이념과 맞지 않으며, 실수로 a와 b에다 같거나 겹치는 메모리 주소를 줘서는 절대로 안 된다.
"하이고, swap 때 변수 하나 줄여 갖고 메모리 얼마나 절약했고 얼마나 팔짜 폈나? ㅋㅋㅋ" 이런 비아냥이 나올 만도 하다.

임시 변수 안 쓰는 swap의 자매품으로는..
O(1)을 초과하는 추가 메모리를 쓰지 않는 n log n 정렬 알고리즘(heap 정렬)이라든가 parent node가 없는 트리 자료구조를 생각할 수 있을 것 같다.
하지만 현실에서는 안정성 있는(stable) n log n인 merge sort라든가, 아예 n^2이지만 아주 가벼운 insert sort가 소규모 한정으로 선호된다. heap sort가 막 메리트가 있다고 여겨지지는 않고 있다.

그리고 parent node 없이 스스로 균형잡는 tree 자료구조의 삽입· 삭제를 구현하는 것 자체는 당연히 가능하다.
그러나 C++에서 제공하는 set, map 부류의 컨테이너들은 가벼운 포인터 기반의 iterator로 원소 순회 기능을 제공하다 보니.. 어차피 다들 node에다가 parent 포인터를 갖추고 있다.

이게 없으면 iterator가 자체적으로 스택을 가진(= 현 순회 상태를 저장) 복잡한 클래스가 돼야만 트리 내부를 순회할 수 있기 때문이다.
뭐, 노드 하나당 8바이트짜리 포인터 오버헤드가 추가됐다고 해서 요즘 세상에 컴퓨터가 메모리가 부족하다고 징징대지는 않는다. ^^

3. 여담

(1) 행렬 얘기를 하다가 프로그래밍 얘기가 너무 길어졌군..;;
아무튼 선형대수학에서 행렬을 다루는 기법을 보면 원소들을 쭉쭉 옮겨서 행렬을 \ 모양의 삼각형 형태로 가공하는 게 많다. 삼각형 모양이 된 행렬은 그 대각선상에 있는 원소만 쭈룩 곱하면 행렬식을 구할 수 있고 여러 모로 취급이 편하기 때문이다.

행렬식이나 역행렬을 구할 때는 행렬에다가 앞서 언급했던 기본연산을 적용하면서 행렬을 삼각화하게 된다. 그런데 이 과정을 기록으로 남겨서 원본 행렬을 아예 하삼각행렬과 상삼각행렬의 곱으로 일종의 분해를 할 수 있다. 단, 앞서 등장하는 하삼각행렬은 주대각 성분이 모두 1... 이걸 LU 분해라고 부른다.

(2) LU 분해 말고 PD(P^-1)이라는 세 형태로 행렬을 분해하는 더 어려운 기법도 나중에 다뤄진다. 이건 행렬의 고유값/고유벡터와 관계 있는 더 어려운 개념이어서 나중에 다뤄지는데.. 행렬식이 아니라 행렬의 거듭제곱을 단순한 형태로 표현하게 해 주는 아주 강력한 도구이다.

(a+b) 기호의 다항식을 n승 하면 항이 더덕더덕 늘어나는데, 이는 행렬도 마찬가지이다. 그런데 주대각성분에만 값이 붙어 있는 대각행렬은 n승 해도 항이 늘어나지 않고 마치 스칼라값처럼 자기 자신의 지수만 늘어난다.
PD(P^-1)은 행렬을 대각행렬 D를 포함한 형태로 분해하는 기법이다. 이에 대해서는 나중에 추가로 글로 정리하도록 하겠다.

(3) 임의의 a,b,c...꼴의 원소에 대해서 행렬의 곱셈뿐만 아니라 행렬식이나 역행렬을 구하는 일반적인 공식도 유도할 수는 있다. 그러나 행렬식 하나만 생각해 보면, n 크기 정사각행렬의 행렬식은 계수가 n인 항이 2n이나 n^2, 심지어 2^n개도 아니고 n!개씩 달라붙는다.;; 아시다시피 그 행렬식은 이전 n-1크기 행렬식들을 n개만치 더하고 쪼개는 걸 반복하는 형태로 재귀적으로 정의되기 때문이다.

그렇기 때문에 큰 행렬을 다룰 때 실무에서는 일반적인 공식은 사실상 의미를 갖지 않는다. 그냥 행렬에다 기본연산을 열나 적용한 뒤에 주대각 성분을 곱하고 말지. 이러면 O(n^3) 정도의 복잡도가 나온다. 얘들은 중간 계산 결과들이 저 복잡한 항의 개수를 줄여 주는 거나 마찬가지이다.

FM대로 재귀적으로 행렬식을 구하더라도 다이나믹 기법으로 이전 계산 결과를 적절히 저장하면 시간 복잡도를 팩토리얼에서 다항함수로 바꿀 수는 있을 것이다.
하지만 이건 쪼개진 sub행렬을 기술하는 게 생각보다 빡세고 쉽지 않다.;;; (직접 생각해 보면 이게 무슨 말인지 알 거임. ㄲㄲㄲㄲㄲ) 크기가 다양한 행렬들의 곱셈 횟수를 최소화하는 문제와는 상황이 좀 다르다. 그러니 이러나 저러나 FM은 실용성이 떨어진다는 건 어쩔 수 없어 보인다.

Posted by 사무엘

2024/02/28 08:35 2024/02/28 08:35
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/2269

일반적인 수라는 건 제곱하면 값이 폭발적으로 커지거나(>1 발산), 반대로 0으로 급격히 오그라는 것으로 여겨진다.
다만, 1은 그 양극단의 딱 중앙에서 자기 형태가 변하지 않는다. 그리고 -1이나 i 같은 건 제곱하면 다른 수가 되었다가 도로 자기 자신으로 돌아오며 순환한다.

망델브로(만델브로트) 집합이라는 게, 0부터 시작해서 더하고 제곱, 더하고 제곱을 반복했을 때 발산하지 않는 복소수의 집합인 걸 생각해 보자. 꽤 오묘한 개념이다.
리만-제타 함수도 그렇고, 평범해 보이는 함수가 복소수 범위로 가면 난이도와 복잡도가 눈 튀어나올 정도로 치솟는 것들이 좀 있다. 제곱해서 -1이 되는 수를 하나 정의함으로써 사고 체계가 이 정도로 확장된다는 것이다.

수학이란 게 발명인지 아니면 발견인지에 대한 논쟁이 있다. 대부분의 업적들은 엄밀한 논리 체계를 찾아낸 발견에 가깝겠지만, 허수와 복소수는 아무래도 발명의 범주에 넣어야 할 것 같다. "제곱해서 -1이 되는 수도 있다고 가정해 보자" 이건 아무래도 자연 세계에서 존재하는 개념을 추상화한 건 아니니까 말이다.

복소수가 그런 것처럼 행렬도 발명에 가까운 도구가 아닐까 싶다. 그리고 가로와 세로 크기가 같은 정방행렬에 대해서는 거듭제곱을 생각할 수 있다.
행렬은 거듭제곱을 하면 행렬식 값도 거듭제곱 된다.
그런데 모든 원소가 몽땅 0이 아니어도 행렬식 값은 0일 수 있으며, 이로 인해 단독 숫자의 연산에서는 생각하기 어려운 특성이 존재할 수 있다.

제일 작고 단순한 2*2 크기의 행렬의 제곱은 일반적으로 다음과 같다.
[a b]^2 = [a^2+bc  b(a+d)]
[c d]     [c(a+d)  bc+d^2]

이를 토대로 이런 행렬을 생각해 보자.
2*2 행렬이란 게 원래 2변수 연립방정식을 푸는 도구인데, 얘 분석을 위해서 4변수 연립방정식을 풀게 생겼다.;;

1. 영행렬이 아니면서 제곱하면 영행렬이 되는 행렬

원소 중 적어도 하나 이상은 0이 아닌 행렬 중에 제곱 했을 때 완전 영행렬이 되는 행렬은 원소가 이런 꼴인 녀석이다. 요러면 제곱해 보면 모든 원소들이 x^2와 -x^2가 상쇄되는 식으로 소거되어 0이 된다.
[   x     y]
[-x^2/y  -x]

y가 원소 단독과 타 원소의 분모에 동시에 존재하니, 원소 중 하나는 반드시 nonzero여야 함이 보장된다.
이걸 전치시킨 것도 동일한 속성을 지니므로, nonzero 원소가 꼭 저 자리에만 있어야 할 필요는 없다.

y에다 1을 대입해서 식을 좀 간소화시키면 이런 형태가 되며..
[  t    1]
[-t^2  -t]

t에 1을 대입하면 일례로 요런 행렬이 나온다. 이런 게 제곱하면 영행렬이 된다는 것이다.
[ 1  1]
[-1 -1]

2. 영행렬이나 단위행렬이 아니면서 제곱하면 늘 자기 자신이 되는 행렬 (멱등행렬)

이건 프로그래밍 언어로 치면 자기 소스 코드를 그대로 출력하는 콰인 같은 느낌이다.;;;
사실은 너무 어렵게 생각할 것 없이, 단위행렬뿐만 아니라 거기서 숫자 일부를 0으로 바꾼 얘라든가, 0과 1이 일렬로 나란히 늘어서 있는 행렬도 다 멱등행렬이다.
[1 0]    [1 1]
[0 0] or [0 0]

이렇게 trivial한 경우 말고, 네 원소들이 모두 nonzero라고 가정하고 식을 세워 보면.. 반드시 a+d = 1이어야 한다는 조건이 먼저 나오고, 최종적으로 답이 이렇게 나온다.
[    x+1      y]
[-x*(x+1)/y  -x]

이런 행렬의 구성 원소는 아까 제곱-영행렬의 경우와 마찬가지로, 2개의 변수만으로 원소 4개의 값이 모두 결정됨을 알 수 있다. 또한, 오른쪽의 b와 d 원소를 동기화시켰을 때 a와 c는 저런 차이가 있다는 점이 매우 흥미롭다. 왼쪽에서 x가 x+1로 바뀐 정도의 차이가 전부이다. ㄲㄲㄲㄲ

저 식은 뭔가 미묘하게 규칙성이 있어 보인다. y=1인 경우만 생각해 보면 아래 row는 위의 row에다가 단순히 -x배를 한 것일 뿐이다. 예를 들어 이런 식이다.
[-2 1]    [ 2  1]
[-6 3] or [-2 -1]

그러니 행렬식 값은 당연히 0이다. 사실, 행렬식이 0이 아닌 멱등행렬은 단위행렬 단 하나밖에 존재하지 않는다.
이렇게 행렬식이 0인 2*2 행렬에다가 평면의 궤적을 선형변환 시키면, 평면도형을 일직선 위로 다 찌그러지게 된다. 제곱 결과물의 차이(영 또는 자기 자신)는 서로 다른 점조차 동일한 점에다가 겹쳐지는지 정도의 차이만을 만들 뿐이다.

제곱했을 때 특정 원소의 값이 확 커진다 하더라도, 행렬식이 0이면 그 일직선에서 엄청 먼 점까지 선형변환을 시킬 뿐, 일직선을 벗어나서 면적을 만들어 내지는 못한다. 이것이 이런 행렬이 갖는 대수적 의미이다.
3 이상의 더 큰 정사각행렬에서는 멱등행렬의 원소 관련 공식이 당연히 훨씬 더 복잡할 것이다. 그래도 규칙성은 갖추고 있을 것이다.

Posted by 사무엘

2022/08/03 08:35 2022/08/03 08:35
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/2050

1. 평행사변형의 넓이, 평행육면체의 부피

2*2 크기의
(a b)
(c d)

행렬이 있을 때, 이 행렬의 행렬식이라고 불리는 D 값은 a*d - b*c로 정의된다. ax+by = 얼마, cx+dy = 얼마 요런 방정식의 근을 구하는 식을 세워 보면 행렬식은 x, y의 분모에 들어가 있다. 그러니 이 값이 0이면 근은 부정이나 불능으로 빠지게 된다.

한편, 행렬식에는 기하학적인 의미가 있다. 원점에서 (a,b)를 잇는 선분이 가로변, 원점에서 (c,d)를 잇는 선분이 세로변인 평행사변형의 넓이를 나타내기 때문이다.

그도 그럴 것이 이 행렬은 한 변의 길이가 1인 (0,0), (1,0), (1,1), (0,1)이라는 정사각형을 (a,b), (a+c, b+d), (c,d)라는 평행사변형으로 옮긴다. (a+b)*(c+d)라는 전체 직사각형에다가 주변의 합동인 삼각형 두 쌍의 넓이를 빼면, 평행사변형의 넓이로 남는 것은 ad-bc뿐이다. 아래 그림을 보시라.

(a+c)(b+d) - b(a+c) - c(b+d) = d(a+c) - c(b+d) = ad + cd - bc - cd = ad-bc

사용자 삽입 이미지

이 평행사변형에서 대각선을 구성하는 (a,b)와 (c,d)를 연결하면 사각형을 반으로 쪼갤 수 있다. 다시 말해 원점과 (a,b), (c,d)를 꼭지점으로 하는 삼각형의 넓이는 ad-bc의 절반이 된다.

다음으로..
저렇게 두 점 A(ax, ay)와 B(bx, by)가 있을 때, A-원점-B 자취의 방향을 판단하는 공식이 있다(시계 방향인지 반시계 방향인지). bx*ay - by*ax이며, 여기에는 배후에 삼각함수 sin( alpha-beta )가 숨어 있다.

그런데 위의 두 점 (a,b), (c,d)도 코싸인/싸인 alpha와 코싸인/싸인 beta라는 극좌표 형태로 표현하면, 행렬식 a*d-b*c 역시 결국은 sin( alpha-beta )과 패턴이 동일함을 발견할 수 있다. 두 쌍의 숫자를 각각 서로 엇갈리게 곱해서 빼는 것 말이다.
이렇듯, 행렬식에 두 벡터의 사잇각에 대한 삼각함수 값이 들어있으니, 벡터의 길이만 정규화하면 각도를 구할 수 있다. 또한 두 변의 길이와 그 사이의 끼인각을 알고 있는 삼각형의 넓이는 A*B*sin(theta)/2로 간단하게 결정된다.

그리고 이 식을 확장하면 삼각형뿐만이 아니라 여러 삼각형들로 분해 가능한 단순다각형(선분들이 서로 만나지만 않으며 볼록하거나 오목할 수 있음) 넓이 내지 폴리곤 패스 방향을 구할 수도 있다. 넓이와 방향(넓이의 부호)이 같이 구해진다.

2차원에서는 이 정도로 분석이 되고, 3차원으로 가면 어떨까?
짐작했겠지만 3*3 행렬의 행렬식은 그 행렬을 구성하는 3개의 벡터들을 축 내지 기저로 삼는 평행육면체의 부피와 같다. 직교좌표에서 모든 점들의 최대치에 해당하는 직육면체의 부피에다가 또 모서리 주변의 온갖 사면체들의 부피를 빼야 하니 식이 굉장히 복잡할 것이다. 3*3 행렬의 행렬식이 항이 6개나 되고 2*2의 것보다 훨씬 더 복잡한 것은 이 때문이다.

하지만 3차원에서도 언제나 부피만 구하는 건 아니다.
차원만 2차원이 아닌 3차원으로 확장한 뒤, 원점에서 출발하는 두 벡터를 가로변 세로변 축으로 삼는 평행사변형의 넓이는 어떻게 구하면 좋을까? (삼각형의 넓이도 당연히 자동으로 포함) 즉, 3차원 공간 안에서의 2차원 평면인 것이다. 이건 2*2 행렬식보다는 어렵겠지만 3*3 행렬식보다는 쉬울 것이다.

그리고 이것이 바로 벡터의 '외적'(벡터곱) 연산이 하는 일이다. 아마 고등학교에서는 내적까지만 하지 외적은 안 배우지 싶다. 단, 내적부터 먼저 개념을 좀 복습해 보자.

2. 벡터의 내적

왜 각 성분을 차례대로 곱한 것을 더하면 내적이 나오는 걸까?
이 원리의 배후에는 코싸인 제2법칙이 있다.
아까 두 변의 길이(두 선분의 길이를 각각 A와 B라 하자)와 그 사이의 끼인각을 아는 삼각형의 넓이를 구했는데, 이 경우 삼각형이 유일하게 결정되었으므로 나머지 한 변의 '길이' C도 당연히 구할 수 있다. 그 삼각형의 모든 특성이 파악 가능한 것이다. C^2 = A^2 + B^2 - 2*A*B*cos(theta) 이다.

이건 피타고라스의 정리의 일반적인 경우이며, 증명하는 방법이 상당히 많다. 여기에서는 제일 직관적인 해석학적 방법 하나만 소개하고 넘어가겠다.
선분 A와 B가 원점을 지나고 선분 A는 x 축에 평행하다고 한다면 선분 A는 (0,0)과 (a,0)을 지나게 될 것이며, 0도인 선분 A로부터 theta도만치 떨어진 선분 B는 선분 B는 (0,0)과 (b*cos(theta), b*sin(theta))를 지난다. 임의의 차원의 임의의 위치에 있는 어떤 삼각형 ABC라도 변환을 통해 그렇게 2차원 평면에서의 일반화가 가능하기 때문이다.

그럼 선분 C의 길이는 저 (a,0)과 (b*cos(theta), b*sin(theta)) 사이의 거리와 같다. 그러므로 길이의 제곱은 (a - b*cos(theta)^2 + (b*sin(theta))^2 가 된다.
이 식을 풀면 a^2 - 2*a*b*cos(theta) + b^2*cos(theta)^2 + b^2*sin(theta)^2 가 된다.
b^2항은 cos(theta)^2 + sin(theta)^2 이므로 1로 약분돼 없어지고, 결국 코싸인 제2제곱 공식이 고스란히 나온다.

그럼, A, B, C를 이제 벡터라고 생각하고 2차원이 아니라 각 축별 좌표를 코싸인 제2제곱 공식에다 대입해 보자.
A=(a1,...,an), B=(b1,...,bn) 같은 식이다. C는 두 벡터의 차이 A-B와 같다.
벡터의 절대값의 제곱은 잘 알다시피 거리의 제곱과 같기 때문에 각 성분들의 제곱을 모두 더한 것과 같다. 그러므로

∑ [i=1..n] (ai^2 + bi^2 - 2*ai*bi) = ( ∑ [i=1..n] (ai^2 + bi^2) ) - 2*A*B*cos(theta) 로 식이 대충 떨어진다.

A와 B에서 각 성분들의 제곱을 합을 구하는 부분은 좌우변 공통이므로 소거되고.. 남는 것은
2*A*B*cos(theta) = ∑ [i=1..n] 2*ai*bi 이다. 여기서 양변을 2로 나눠 주면 내적 공식이 아주 깔끔하게 유도된다. 콜?

벡터의 내적은 그냥 숫자 하나(스칼라)만으로 답이 떨어지며, 벡터의 각 성분들을 차례대로 곱해서 더하기만 하면 된다. 내적에는 두 벡터의 사이각의 '코싸인' 값이 들어있기 때문에, 두 벡터가 서로 수직인지를 벡터의 길이와 무관하게(= 정규화 안 하고도) 간편하게 판별할 수 있다. 코싸인 90도는 0이므로!

내적은 계산이 딱히 어렵지 않을 뿐만 아니라, 2차원이고 3차원이고 어느 차원이든지간에 계산법이 동일하다는 것도 큰 장점이다. 두 벡터의 사이각을 구하는 용도로는 완전 딱이다. cos(alpha-beta) = cos(alpha) cos(beta) + sin(alpha) sin(beta) 인 것에도 2차원일 때의 내적 공식이 숨어 있다는 걸 발견할 수 있다.
또한, 생긴 모양 덕분에 벡터의 내적을 행벡터(행이 하나. 수평선-_-)와 열벡터(열이 하나. 수직선)의 곱으로 표기하기도 한다. (행과 열뿐만이 아니라 횡과 종도 어느 게 어느 건지 종종 헷갈릴 때가 있다만..;;)

3. 벡터의 외적

그에 반해 외적은 결과값도 벡터이다. 그리고 3차원일 때에만 정의된다. 계산값의 각 차원과 피연산자들이 일대일로 딱 밀착해 있는 관계로 3차원 말고는 선택의 여지가 없기 때문이다.

성분이 (a1,a2,a3)인 벡터 A와, 성분이 (b1,b2,b3)인 벡터 B의 외적은
(a2*b3-a3*b2, a3*b1-a1*b3, a1*b2-a2*b1)이라고 정의된다.
어 그런데 이거, 두 쌍의 숫자를 각각 서로 엇갈리게 곱해서 빼는 게 2*2 행렬식을 구하는 것과 비슷해 보인다. 맞다.
그래서 벡터 A, B가 동일 평면상에 있어서 a3와 b3 같은 게 동시에 0이기라도 하면, 해당 변수가 포함된 항은 모두 소거된다. 이 경우 외적은 그냥 2*2 행렬식과 동일해진다.

또 생각할 점은.. 3*3 행렬식을 구하는 것도 특정 row와 col을 제외한 2*2 행렬식을 구하는 것의 연속이라는 점이다. 그래서 외적 구하는 공식을
(i  j  k )
(a1 a2 a3)
(b1 b2 b3)

의 행렬식이라고 표현하기도 한다. 물론 여기서 i~k는 스칼라값이 아니라 각각 (1,0,0), (0,1,0), (0,0,1)에 해당하는 단위벡터이다. 그러니 스칼라와 벡터가 뒤섞여 있는 저 행렬은 대수적인 의미는 딱히 없다. 외적 구하는 공식을 좀 더 뽀대나게 표현하는 용도로만 쓰이는 셔틀일 뿐이다. 그래도 결국은 3*3 행렬식과 닮긴 닮았다.

행렬식을 구하는 공식에서 j에 해당하는 부분은 더하는 게 아니라 뺀다. 그렇기 때문에 외적 공식에서는 1,3이 아니라 3,1 순서로 쓴 뒤에 더하는 것으로.. 다시 말해 양수를 빼는 게 아니라 음수를 더한다고 표현을 달리 했다. 둘 다 동일한 의미이므로 부호에 주의하기 바란다.

벡터는 스칼라와는 달리 '크기'뿐만 아니라 '방향'이라는 정보가 추가로 들어있다.
외적 연산을 통해 구해진 벡터는 일단 크기는 두 벡터의 크기의 곱에다가 사잇각의 sin값을 곱한 것과 같다. 그러므로 3차원 공간에서 두 3차원 벡터가 만드는 평행사변형/삼각형의 넓이를 구할 수 있다.

외적 식을 전개해서 크기의 제곱을 해 보면, 각각의 두 벡터의 크기의 제곱을 곱하고 거기에다 벡터의 내적값(양 벡터의 각 성분들을 서로 곱해서 더함)의 제곱을 뺀 것과 같다고 식이 전개된다. A^2 - B^2 꼴이 되기 때문에 (A+B)(A-B)로 인수분해를 하고 싶은 충동이 느껴지지만 여기서는 식을 다른 형태로 바꿔야 된다.

내적에는 역시 두 벡터의 크기의 곱에다가 사잇각의 cos이 들어 있으니 이것의 제곱이라면 두 항이 결국 |A|^2 * |B|^2를 공통으로 갖고 있고 (1  - cos^2 )가 남는다. 그리고 이것이 sin^2과 같다는 건 두 말하면 잔소리이고.

외적의 크기에 벌써 이렇게 유용한 정보가 들어있는데, 방향은 더욱 흥미롭다.
짐작하겠지만 두 벡터의 외적의 방향은 두 벡터와 수직이다. 물론 위쪽도 수직이고 아래쪽도 수직인데, 해당 좌표계의 동일 부호가 향하는 쪽으로 방향이 결정된다. 두 기저 벡터에 대한 외적을 구하면 나머지 기저 벡터가 튀어나온다.

애초에 두 벡터의 외적은 그 두 벡터와의 내적이 모두 0인 벡터 중에 크기가 저렇게 AB sin(theta)로 나오는 놈을 구한 것이다. a1*c1 + a2*c2 + a3*c3 = 0과 b1*c1 + b2*c2 + b3*c3 = 0을 만족하는 (c1,c2,c3)을 직접 구해 보면 안다. 저것만으로는 식보다 미지수 개수가 더 많으니 (c1,c2,c3)가 하나로 딱 떨어지지 않고 c1과 c2가 c3의 배수인 것처럼 관계식만 나온다. 그런데 c3의 특정값일 때 c1,c2에 있던 분모가 싹 소거되고 c1~c3이 저렇게 아주 대칭적이고 깔끔하게 나오는데 그게 바로 외적값이다.

이런 유용함 때문에 외적이 3차원에서의 전유물이라고 여겨지는 것이다. 이항연산에 딱 최적화돼 있지 않은가.
물론, 외적은 수직이라는 게 위아래가 모두 존재한다는 특성상 교환 법칙이 성립하지 않고 A×B=-B×A이다. 뭐, 4차원 이상에서는 두 벡터와의 내적이 모두 0인 벡터는 3차원일 때처럼 일직선상의 형태로 유일하게 떨어지지가 않는다. 그러니 외적과 같은 접근 방식이 큰 의미가 없어져 버린다.

끝으로, 3차원에서 벡터의 내적과 외적은 삼중곱이라는 연산을 통해 한데 만난다. 3개의 벡터 A,B,C를 축으로 하는 평행육면체의 부피를 구하고 싶으면 아까처럼 벡터들을 3차원 행렬의 행렬식으로 표현해도 되지만, 밑면에 속하는 두 벡터 A×B의 외적을 구한 뒤 거기에다 C와 내적을 구하면 된다. (A×B)·C! 그게 결과적으로 행렬식을 구한 것과 같은 계산 결과가 도출된다. 왜 그런지는 아까 그 외적 구하는 행렬과 일반 행렬의 행렬식을 늘어놓고, 거기에다가 내적을 구하는 공식까지 적용한 뒤 서로 비교하며 생각해 보면 된다.

Posted by 사무엘

2015/08/23 08:25 2015/08/23 08:25
, , , , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1130

행렬 기초 이야기

a*x + b*y + M = 0
c*x + d*y + N = 0

이라는 두 개의 이원(x, y) 일차방정식이 있다고 치자. 흔히 연립방정식이라고도 불린다.
이 방정식을 풀려면 x, y 중 하나의 계수를 a나 c, 아니면 b나 d로 맞춰 줘서 한 변수를 소거해야 한다. 그래서 일원 일차방정식으로 바꿔서 반대편 변수의 근을 구한 뒤, 그 값을 대입하여 원래 변수의 근까지 구하면 된다.

이를 일반화하여 위의 방정식의 '근의 공식'을 구하면 다음과 같다. 뭔가 규칙성이 있는 것 같으면서도 미묘하게 잘 안 외워진다.

x = (N*b-M*d) / (a*d-b*c)
y = (N*a-M*c) / (a*d-b*c)

분모를 보니 생각나는 게 없는가?
그렇다. 이것은

[ a b ]
[ c d ]

라는 원소로 구성된 2*2 정방행렬의 행렬식을 구하는 공식이다.
이 행렬식의 값이 0이라는 건 a:b와 c:d의 비율이 동일하다는 뜻이다. 따라서 이 행렬을 구성하는 벡터들은 서로 일차(선형) 독립을 이루지 못하며, 상수항이 어떻냐에 따라서 이 방정식은 근이 무수히 많거나 근이 존재하지 않게 된다.

이런 행렬을 거친 일차변환은 2차원 평면을 1차원 선이나 점으로 찌그러뜨린다. 이런 행렬은 영벡터(모든 원소의 값이 0)가 아닌 벡터 중에서도 자신과의 곱을 영벡터로 만드는 물건이 무수히 존재하게 된다(Ax=O).
예를 들어 연립방정식 x+2*y = 0 과 3*x+5*y = 0의 근은 x와 y가 모두 0인 trivial solution 단 하나밖에 없으나, x+2*y = 0과 3*x+6*y = 0은 두 식이 동치나 마찬가지이기 때문에 x = -2*y이기만 하면(가령 2와 -1) 식이 성립한다. non-trivial solution들이 존재한다는 뜻이다. 결국, 근이 무수히 많을 수 있다는 말과 본질적으로 동일하다.

이들은 모두 필요충분조건 관계에 있으며, 이외에도 이런 행렬의 엄밀한 특성에 대해서는 선형대수학 시간에 많이 배우게 된다.

말이 길어졌는데, 그럼 변수가 세 개 이상이 되면 근을 구하는 양상이 어떻게 바뀔까?
그야말로 폭발적으로 복잡해진다.

변수가 2개일 때는 x, y 근에 최대 두 변수의 곱(최대 2차)으로 이뤄진 항이 분자와 분모에 2개씩 있었다.
그러나 3개일 때는 세 변수의 곱으로 이뤄진 항이 분자와 분모에 6개씩 들어간다.
그리고 이를 일반화하면, n원 1차 연립방정식의 근은 n개의 변수의 곱으로 이뤄진 항이 분자와 분모에 무려 n! (팩토리얼)개씩 들어간다!
이것이 '폭발적'이라는 단어의 의미이다. 예를 들어,

[ a b c ]
[ d e f ]
[ g h i ]

라는 3*3 정방행렬의 행렬식은 다음과 같다. 어떤 규칙성이 있는지, 어떻게 하면 잘 외울 수 있겠는지 한번 생각해 보시라.;;

a*e*i - a*f*h - b*d*i + b*f*g + c*d*h - c*e*g

a가 속한 행과 열을 제낀 2*2 행렬(e f / h i)의 행렬식에다가 a를 곱해서 더하고,
다음으로 b가 속한 행과 열을 제낀 2*2 행렬(d f / g i)의 행렬식에다가 b를 곱해서 빼고,
끝으로 c가 속한 행과 열을 제낀 2*2 행렬(d e / g h)의 행렬식에다가 c를 곱해서 더하면.. 이 행렬 전체의 행렬식이 나오긴 한다. 2*2 행렬식이 2개의 항으로 구성돼 있는데 그런 식이 3개가 늘어나니 총 6개가 되는 게 맞다.

이런 방식으로 행렬을 쪼개면 그 어떤 크기의 행렬의 행렬식도 구할 수는 있다. 하지만 크기가 3을 넘어가는 행렬에 대해 행렬식 내지 방정식을 푸는 일반적인 공식을 구하려는 생각은 포기하는 게 좋다. 머리 터진다..;;

참고로 1변수 n차 방정식의 경우를 생각해 보자. 2차 방정식은 잘 알다시피 비교적 외우기 쉬운 근의 공식이 존재하는 반면 3차와 4차는 근의 공식이 있기는 하나 인간의 머리로 도저히 외울 수 없을 수 없을 정도로 미치도록 복잡한 형태이다. 게다가 서로 인접한 차수끼리 규칙성 같은 것도 아예 존재하지 않는다. 5차 이상부터는 대수적인 방법만으론 깔끔하게 풀 수조차 없다.
그에 반해 n변수 1차 연립방정식은 비록 그 정도로 카오틱하게 복잡한 건 아니지만, 그래도 좀 다른 양상으로 복잡해진다는 게 오묘한 점이다.

그리고, 이건 일반적인 공식을 구하려 할 때 딸려 나오는 식이 지수함수 급으로 복잡해진다는 소리다. 일반적인 경우가 아니라 그때 그때 특정 숫자가 주어진 행렬의 행렬식을 구하는 알고리즘의 시간 복잡도가 지수함수라거나 NP 완전 문제 급이라는 뜻은 아니다. 둘은 서로 다른 개념이다.

변수가 3개를 넘어가는 방정식은 어떻게 풀어야 할까?
가령, 변수가 x, y, z라고 치면 일단 모든 방정식의 x의 계수를 1이든, 맨 위의 식의 계수로든 어쨌든 하나로 일치시켜야 한다. “등식에서 같은 수를 더하거나 빼도 등식은 성립한다.” / “등식에서 같은 수를 곱해도 등식은 성립한다” 라고.. 초등학교 산수 시간에 배우는 지극히 당연하고 기본적인 원리를 이용해서 방정식을 푸는 것이다.

그렇게 해서 x 변수를 없는 놈 취급할 수 있게 만든 뒤, 다음 방정식에 대해서 y 변수의 계수를 일치시킨다.
이런 절차를 반복하여 변수를 z만 남겨서 z 값을 구하고, 다음으로 y, x의 순으로 재귀적으로 근을 구하면 된다.
행렬이라는 물건 자체가 이런 연립방정식을 푸는 동작을 간략하게 모델링하는 과정에서 고안되었다.
앞서 말한 절차를 행렬 용어로 표현하자면, 가우스-조던 소거법으로 행렬을 대각화하는 것과 같다.

행렬이 대각화가 되고 나면 방정식을 다 푼 것이나 다름없을 뿐만 아니라, 행렬식의 값은 그 행렬의 대각선 원소들의 곱으로 쉽게 구할 수 있게 된다.
행렬을 대각화하는 데 드는 시간 복잡도는 일반적으로 O(n^3)으로, 행렬 곱셈의 비용과 같다.
이 작업을 숫자를 대상으로 곧장 곧장 업데이트하는 게 아니라, 기호를 이용해서 일반적인 경우를 다 고려하여 표현하려다 보면 항 개수가 아까 같은 팩토리얼 급으로 증가하게 되는 것일 뿐이다.

연립방정식 하니까 응용수학 내지 산업/경영공학 같은 데서 다루는 그 이름도 유명한 선형 계획법(LP)이 생각난다.
이런 데서 다루는 문제는 대체로 변수의 개수가 식의 개수보다 더 많고, 식도 등식이 아니라 부등식이다. 애초에 해 자체는 무한히 많을 수밖에 없는데 그래프의 능선을 따라다니면서 주어진 조건을 최대한 만족하는 영역을 찾는 게 목적이다. 이런 문제는 실용적인 가치도 무진장 높다.

이런 걸 푸는 제일 간단한 알고리즘으로는 simplex method가 있는데, 그 이상의 디테일은 본인도 비전공자인 관계로 잘 모른다. 변수의 차원이 최대 2차원 정도일 때나 그래프를 그려서 생각할 수 있지, 이 역시 3차원 이상으로 가면 머리에 쥐 난다. 고등학교에서 행렬을 2*2까지밖에 다루지 않는 것, 그리고 전산학에서 간단한 bool 대수 연산을 다룰 때 변수를 3개까지밖에 넣지 않는 게 다 이유가 있어서 그런 것이다.

Posted by 사무엘

2013/10/26 19:25 2013/10/26 19:25
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/891

최소자승법에 의한 그래프 근사

수치로 표현된 실험 데이터로부터 규칙를 추출하여 추세를 예측하는 것은 과학과 공학에서 아주 유용하게 쓰이는 통계 기법이다.
“input이 x1과 x3일 때 실험으로부터 얻어진 output이 각각 y1과 y3이었으니, 중간에 직접 실험을 해 보지 못한 x2에서는 결과가 아마 y2가 될 것이며(내삽), 더 나아가 범위를 벗어난 x5일 때는 결과가 y5 정도로 나올 것이다(외삽).”

n개의 실험 데이터 (x_1, y_1) 부터 (x_n, y_n)이 있다고 치자. x는 input이요, y는 output을 가리킨다. x_1...n은 꼭 균일한 등차수열 간격으로 분포해 있을 필요는 없다.
우리는 이 실험 데이터의 추세를 잘 나타내는 함수 F(x)를 얻고 싶다. F는 간단히는 그냥 직선을 나타내는 일차함수일 수도 있고 이차나 삼차, 혹은 임의의 계수를 지니는 지수나 로그 함수일 수도 있다.

그 디테일이 어떠하든 F(x_1)은 y_1과 최대한 비슷한 값이 나오고 그런 식으로 1부터 n 사이에 있는 자연수 i에 대해서 F(x_i)는 y_i와 최대한 비슷한 값이 나오면 된다. 그럼 그 F는 실험 데이터의 특성을 잘 나타내는 좋은 함수로 여겨질 것이며 내삽과 외삽에 활용될 수 있다.

최대한 비슷하다는 걸 수학적으로 어떻게 엄밀하게 표현할 수 있을까? i=1...n에 대해,  함수값과 실제 데이터의 차이인 F(x_i)-y_i가 작아야 할 것이다. 오차라는 건 양이든 음이든 절대값이 중요한데 절대값은 미분 같은 수치해석적인 처리가 어려운 연산이니 이럴 때 제곱이 쓰인다. 데이터의 분산을 구할 때와 같은 접근 방식이다. 결국 문제는

각 데이터들에 대한 오차들의 제곱의 합 = (F(x_1)-y_1)^2 + (F(x_2)-y_2)^2 + (F(x_3)-y_3)^2 … (F(x_n)-y_n)^2

이것을 최소화하는 F를 구하는 것으로 귀착된다.
그래서 이 계산법의 이름이 최소자승법/최소제곱법(least square method)인 것이다.

최소자승법이 하는 일은, 그 F(x)가 여러 함수들의 합으로 이뤄질 때, 각 함수들에 들어가는 적절한 계수를 구해 준다.
가령 F(x)가 계수가 3개 존재하는 2차함수여서 a*x^2 + b*x + c 의 형태라면, F(x) = a*f(x) + b*g(x) + c*h(x) 의 세 계수를 생각할 수 있다. 하지만 f, g, h가 실제로 무슨 함수인지는 최소자승법에서 중요하지 않다.

오차의 제곱의 합 함수를 이를 기준으로 다시 써 보면,
∑ i=1..n에 대해 ( a*f(x_i) + b*g(x_i) + c*h(x_i) - y_i )^2 가 된다.

이 식을 전개하면 제법 복잡한 항들이 줄줄이 나오겠지만, 겁먹을 필요 없다.
f, g, h는 언제든지 값을 집어넣어서 계산할 수 있는 함수이고, x_i와 y_i는 전부 상수일 뿐이다.
식에서 변수는 a, b, c이며, 제곱 버프 덕분에 오차의 제곱의 합은 a, b, c에 대한 이차식이 된다.

식의 값이 최소가 되려면, a, b, c에 대해 제각기 따로 생각했을 때, 해당 이차식의 미분계수가 0이 되는 지점에 a, b, c가 있어야 한다. 이것이 우리가 구하고자 하는 F(x)의 정체이다.
가령, x^2 + 2*x - 3 이라는 이차식을 생각해 보면, 이건 (x-1)(x+3)으로 인수분해가 되기 때문에 식의 값을 0으로 만드는 근은 1과 -3이다. 그러나 식을 x에 대해 미분하면 2*x+2가 되고 1과 -3의 중간 지점인 -1이 바로 도함수의 값을 0으로 만들어서 최소값 -4를 만들어 낸다.

우리가 풀고자 하는 문제가 다루는 식은 a, b, c 같은 여러 변수들이 존재하기 때문에, 동일한 식을 각 변수별로 편미분을 해야 한다. 그러면 다음과 같이 규칙성이 있는 3개의 연립 일차방정식이 완성된다. 세 개의 변수의 계수에 다른 변수가 포함되어서 서로 얽혀 있기도 하기 때문에, 각 변수별로 미분계수를 모두 0으로 만들 수 있는 변수들의 값은 이런 방정식을 풀어야 구할 수 있다.

2*f(x_i)*f(x_i)*a + 2*f(x_i)*g(x_i)*b + 2*f(x_i)*h(x_i)*c - 2*f(x_i)*y_i = 0 (a에 대해서)
2*g(x_i)*f(x_i)*a + 2*g(x_i)*g(x_i)*b + 2*g(x_i)*h(x_i)*c - 2*g(x_i)*y_i = 0 (b에 대해서)
2*h(x_i)*f(x_i)*a + 2*h(x_i)*g(x_i)*b + 2*h(x_i)*h(x_i)*c - 2*h(x_i)*y_i = 0 (c에 대해서)

변수가 3개보다 더 많더라도 결국은 이런 패턴의 식이 나온다! _i로 표현된 건 합계를 다 해 줘야 한다는 걸 잊지 말고.
고맙게도 양변은 2로 나눠 버리기 딱 좋게 돼 있으며, 상수항은 음수로 나와 있으니 우변으로 옮기기도 좋다.
위의 식은 결국 다음과 같은 Ax=b 꼴의 행렬로 너무나 깔끔하게 나타낼 수 있다. (행렬은 전치행렬과 자신이 서로 동일한 대칭행렬이다.)

[ F*F F*G F*H ] [ a ]   [ F*y ]
[ G*F G*G G*H ] [ b ] = [ G*y ]
[ H*F H*G H*H ] [ c ]   [ H*y ]

그리고 우리가 구하고자 하는 계수 벡터 x는 A의 역행렬에다가 b를 곱하면 구할 수 있다. 참 쉽죠?

이것이 행렬의 힘이다.
<날개셋> 타자연습에서 타자 속도 그래프를 얼추 비슷한 곡선 함수로 표시해 주는 기능,
그리고 엑셀에서 추세선을 그어 주는 기능들도 다 이 최소자승법 알고리즘을 써서 구현되어 있다.

아래의 그림은 지난 5년간 <날개셋> 한글 입력기의 전체 소스 코드 라인 수의 증가 추이와, 이를 토대로 최소자승법으로 구한 추세선(직선) 그래프이다. 2009년 상반기에 5.3 버전이 개발되었을 때 약간 가파르게 소스 코드가 증가했지만, 그 후로는 증가가 비교적 원만했음을 알 수 있다. 1년에 약 4천 줄 꼴로 코드가 증가한 것인지?

사용자 삽입 이미지

Posted by 사무엘

2012/06/21 08:41 2012/06/21 08:41
,
Response
No Trackback , 8 Comments
RSS :
http://moogi.new21.org/tc/rss/response/698

삼각함수와 회전 변환

사용자 삽입 이미지
요 그림이 고등학교 수학 II에서 배우는 진정한 묘미 중 하나입니다.

(0, 0), (x, 0), (0, y)의 직각삼각형을 원점을 축으로 θ만큼 돌리니까 원점은 그대로고 밑변은 (x cosθ, x sinθ)가 됩니다.
그런데 밑변보다 y만치 위로 떠 있던 점은, 회전 과정에서 가로로는 높이 y의 sin값만치 “감소”(왼쪽으로)하고, 세로로는 cos값만치 증가합니다.

그러니 (x cosθ - y sinθ, x sinθ + y cosθ)의 형태가 되는데, 이는 원래 점인 x, y에 대한 일차변환으로 일반화할 수 있습니다. 결국

(cosθ, -sinθ)
(sinθ,  cosθ)


가 됩니다. “꼬마신 신꼬”라고 외우는 그 유명한 회전변환 행렬입니다.
이걸 모르면 특히 컴퓨터그래픽에서 현란한 벡터 조작이나 3차원 그래픽 같은 건 상상도 할 수 없습니다.

이 행렬식의 값은 1 (임의의 각도의 cos 제곱과 sin 제곱의 합은?), 따라서 이렇게 도형을 일차변환 시키더라도 원래 도형의 넓이를 바꾸지 않는다는 걸 알 수 있습니다. 역행렬은 sin 쪽 부호만 맞바꾸면 됩니다. 기하학적으로, 상식적으로, 역행렬 공식에 맞춰 생각해도 전부 명확합니다.

공통수학에서는 삼각함수란 게 있다는 것, 그리고 한 삼각형의 세 변과 세 각이 주어졌을 때 삼각함수가 이런 특성을 갖는다는 것을 배웁니다. 기하학인지 대수학인지 감을 못 잡는 이 괴상한 함수는 흥미보다는 학생들에게 어마어마한 암기를 강요하면서 악몽 같은 기억으로 남아 있을 것 같습니다.

그러다가 수학 II로 오면서 단순히 삼각형과 관련된 것이 아닌 삼각함수 자체의 특성을 더 깊게 공부하게 됩니다. 이 회전행렬은 삼각함수의 덧셈 정리를 유도시킵니다.
특히, 저 행렬에다가 회전 행렬과 같은 각인 (cosθ, sinθ) 열벡터를 뒤에 곱해 주면 cosθ와 sinθ 값으로부터 cos 2θ, sin 2θ의 값을 얻을 수 있게 되고, 그 값으로는 아예 cos²θ, sin²θ의 값도 구할 수 있게 됩니다.

  cos 2θ = cos²θ - sin²θ,  cos²θ = (cos 2θ + 1)/2
  sin 2θ = 2 cosθ sinθ

공을 공중을 향해 몇 도로 던져야 가장 멀리 날아가는지를 삼각함수를 계수로 하는 이차방정식으로 풀어 보면, 결국 cosθ sinθ 값(곱)을 최대로 하는 θ 값을 구하는 문제로 귀착됩니다. 이는 sin 2θ의 값을 최대화하는 것과 같으므로 θ는 45도임이 명확해집니다.

sin과는 달리 cos은 양 함수의 제곱의 합으로 바뀐다는 점도 흥미롭습니다. 2θ보다 더 일반적인 α와 β의 경우를 생각해 보면 더욱 흥미로운 결과가 나오는데요, 덧셈 대신 두 각의 차이를 나타내는 뺄셈만을 예로 들어 보겠습니다.

  cos(α-β) = cosα cosβ + sinα sinβ
  sin(α-β) = sinα cosβ - cosα sinβ

cos을 보면 이는 정확하게 벡터 내적과 관련이 있음을 알 수 있습니다. x, y 성분인 벡터를 거리와 각도로 바꿔서 표현해 보면, Ax·Bx + Ay·By가 왜 |A||B| cosθ인지가 명확해집니다. 공통수학 때 배운 코사인 제 2법칙과도 이미 관련이 있고요.
cos은 90도일 때 0이 되기 때문에 두 벡터가 기하학적으로 직각인지 판단할 때 유용히 쓰일 수 있습니다. 부호가 갈리는 기점이 직각이죠. 시계에서 3시를 향하고 있는 벡터가 있다면, 5시나 1시를 향하는 벡터와는 양수이고, 7시나 11시 벡터와는 음수가 되는 셈입니다.

그럼 sin은 무슨 관련이 있는 걸까요? sin은 90도가 아닌 0도를 기점으로 부호가 바뀝니다. 3시를 향하는 벡터 기준으로 5시나 7시를 향하는 벡터의 부호가 서로 같고, 1시, 11시 벡터와는 서로 다릅니다.
정보 올림피아드 대비하여 기하 알고리즘 공부할 때, 특히 convex hull 같은 거 구할 때 단골로 등장하는 게 세 점이 시계 방향인지 반시계 방향인지 판단하는 공식인데요, 그게 바로 sin과 관련이 있습니다. Bx·Ay - By·Ax입니다. 이 식은 두 벡터가 일직선상에 있을 때 값이 0이 됩니다.

그러나 cos 계열인 벡터의 내적은 sin과는 달리 3차원 이상에서도 일관되게 구하는 공식이 있고 임의의 차원에서도 의미를 갖는다는 점에서 더욱 의미 깊다고 할 수 있습니다. 시계 방향 여부는 2차원 평면에서만 의미를 가지며, sin과 관련이 있는 벡터의 외적 역시 3차원 공간에서만 정의됩니다.

이렇게 한바탕 수학 II 초· 중반에서 홍역을 치른 삼각함수는 나중에 아예 sin(x)/x의 0 극한을 구하고 삼각함수를 미· 적분함으로써 더욱 해석학적으로 접근하게 됩니다. 고등학교 수학 교육 테크트리에서 맨 마지막으로 지어지는 최고급 건물 내지 유닛은 단연 미적분이라 할 수 있습니다.

Posted by 사무엘

2011/11/02 19:31 2011/11/02 19:31
, , , , ,
Response
No Trackback , 15 Comments
RSS :
http://moogi.new21.org/tc/rss/response/592


블로그 이미지

그런즉 이제 애호박, 단호박, 늙은호박 이 셋은 항상 있으나, 그 중에 제일은 늙은호박이니라.

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2024/04   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        

Site Stats

Total hits:
2667129
Today:
2367
Yesterday:
1937