우리는 지난 포스팅에서 영공간(Null Space)에 대해 공부하였다. 또한 벡터 공간(Vector Space)과 임의의 행렬 A의 Column space에 대해서도 공부하였다. 이번 포스팅에선 Null space를 구하는 절차, 즉 Ax=0의 해를 구하기 위한 알고리즘(algorithm)을 공부해 보도록 하겠다. 또한 특별한 형태의 솔루션인 기약행 사다리꼴(Reduced row-echelon form)에 대해서도 공부해 보도록 하겠다. 

 

지난 포스팅에서 배웠듯이 Null space는 Ax=b의 선형방정식(Linear equation)에서 우변의 b가 영벡터(zero vector)일 때, 즉 Ax=0의 해에 대한 집합을 의미한다. 이 Null space는 벡터 공간이며 또한 부분 공간(subspace)이기도 하다. 벡터 공간에 대한 강의(Lecture 5, 6)내용을 잘 이해하도록 하자. 

 

 

 

1. Ax=0의 해(Null space)를 계산하기 위한 알고리즘

 

3x4크기의 직사각 행렬(Rectangular Matrix) A를 아래와 같이 정의하자. 행렬 A의 row와 column을 자세히 살펴보자. 뭔가 특이점이 보이는가? 앞선 포스팅의 내용을 성실히 공부했다면 특이점이 보일 것이다.  

 

 

우선 A의 column을 살펴보자. column 2는 column 1의 2배에 해당하는 것을 눈치 챘는가? 즉 column 1과 column 2는 같은 방향을 나타내므로 상호 종속적이다(dependent)

다음은 row를 살펴보자. row 1과 row 2를 더하면 row 3가 된다. 따라서 row 3는 독립적이지 않다(not independent)

 

우리가 이렇게 눈으로 찾은 행렬 A의 특이점들은 A의 소거(Elimination) 과정에서 나타날 것이다. 우리는 지난 포스팅에서 소거법에 대해 공부했다. 지금까지의 소거법은 정방행렬(square matrix)에 대해서만 공부하였지만, 이번에는 직사각 행렬(Rectangular matrix)에 대해 진행할 것이다. 또한 소거 과정에서 pivot의 위치에 0이 나왔을 때 어떻게 진행하는지에 대해서도 알아보자. 

 

다시 한 번 정리하자면 지금 우리의 목표는 Ax=0의 해, 즉 Null space를 구하는 것이다. 이 Null space를 구하는 방법은 행렬 A를 소거(Elimination)하는 것이다. 여기서 중요한 포인트는 소거를 하는 과정에서 우리는 Null space를 변화시키지 않는다는 것이다. 소거 과정에서 사실은 column space는 바꾸겠지만 결과적으로 봤을 때 그 과정에서 해의 집합인 Null space는 바뀌지 않는다. 

 

Ax=0의 방정식을 봤을 때 Null space라는 것은 좌변의 A행렬과 우변의 영벡터 b에 대한 방정식을 만족시켜야만 하는 해의 집합인 것이다. 따라서 소거 과정에서 행렬 A의 column space는 변할 수 있으나 본래의 A와 영벡터 b에 대한 방정식을 만족시키는 해의 집합 자체는 변하지 않는 것이다. 

지금 당장은 이 말이 잘 이해가 가지 않겠지만 앞으로의 과정을 잘 살펴보고 이 말을 다시 한 번 생각해보자. 

 

자 이제 소거를 시작해보자. 

 

A의 첫 번째 pivot은 1이다. pivot 바로 아래의 원소인  A(row2, col1)=2를 소거해야 하므로 row2 = row2 - 2*row1 를 계산하면 식 (2)의 step1과 같이 된다. row3도 역시 소거를 하려면 row3 = row3 - 3*row1 를 계산하면 step2와 같이 된다. 

 

 

 

이것이 소거 과정의 첫 번째 stage다. 첫 번째 pivot의 아래에 있는 원소는 모두 0으로 만들어 소거하였다. 이제 다음 stage인 column 2를 살펴보자. 원래 같았으면 두 번째 pivot은 A(row2, col2)인데, 식(3)과 같이 값이 0이다. Lecture 2에서 배웠듯이 0인 원소는 pivot이 될 수 없다. 

 

만약 이 두 번째 pivot의 아래의 원소 A(row3, col2)가 0이 아닌 값을 가진다면 행 교환(row exchange)을 통해 pivot값을 바꿔서 설정해주면 된다. 그러나 이 역시 0이기 때문에 결과적으로 column 2에서의 소거는 더이상 진행되지 않는다. 즉 두 번째 pivot은 column 2에 없다. 

이것이 의미하는 것이 무엇일까? column 2에 원래 존재해야 할 pivot이 없는 이유는 무엇일까? 바로 A의 column 2는 column 1에 종속적(dependent)이기 때문이다. 식 (2)의 행렬 A를 보면 col1의 2배가 col2인 것을 알 수 있다. 즉 두 column이 같은 선상에 위치한다는 의미이다. 

 

 

 

여기서 멈추지 않고 이제 세 번째 column을 보자. 세 번째 column의 두 번째 row부터는 0이 아닌 값이 존재한다. 결국 두 번째 pivot은 A(row2, col3)=2가 될 것이다. 두 번째 pivot을 기준으로 아래의 원소들을 0으로 만들자. 이때 아래의 row3와 pivot이 있는 row2는 같다. 따라서 row3=row3-1*row2가 될 것이다. 결과는 식 (4)의 step1이 된다. 

 

 

 

이제 소거는 모두 끝났다. 결국 이 행렬이 U행렬인데, 알다시피 U행렬은 상삼각행렬(Upper triangular matrix)를 의미한다. 그러나 이 결과 행렬은 삼각형 모양이 아니라 계단 형태이다. 이를 echelon form이라 한다. 

 

여기서 우리는 행렬 A에 대한 굉장히 중요한 숫자 한 가지를 발견했다. 바로 "pivot의 개수(number of pivots)"이다. 소거를 통해 알아낸 행렬 A의 pivot의 개수는 2이다. pivot 개수 2가 의미하는게 무엇일까? 바로 행렬 A의 Rank이다. 

 

행렬 A의 Rank는 2이다. 

 

 



 임의의 행렬 A에 대해 U행렬을 얻기 위해 행렬 A를 소거(Elimination)한다. 소거 과정에서 pivot의 개수를 알아낼 수 있는데 이때 pivot의 개수가 바로 행렬 A의 Rank이다. 


 Rank는 시스템 행렬 A의 선형 독립(Linearly independent)인 row혹은 column vector의 수를 나타낸다. 이 Rank는 소거 과정에서 나타나는 pivot의 개수와 일치한다. 


Rank of A = number of pivots

 

 

 

 

 

 

 

우리는 지금까지 Ax=0에 대한 해를 구하고자 했다. 그런데 이번에는 위에서 계산한 식(4)의 A를 소거한 행렬인 U에 대한 해, 즉 Ux=0를 구하고자한다. 여기서 한 가지 염두해둬야 할 것은 Ax=0와 Ux=0의 해가 똑같은 Null space에 존재한다는 것이다. A를 소거하여 만든 행렬 U는 비록 A와 비교했을 때 column space는 변했겠지만 해는 동일한 Null space에 존재한다. 이것이 앞단에서 말했던 소거과정에서 Null space는 바뀌지 않는다는 것이다. 

 

결국 Ax=0와 Ux=0의 해는 같은 Null space이다. 

 

그렇다면 Ux=0의 해는 어떻게 기술할 수 있을까? 물론 Ax=0를 계산할때와 같이 해는 존재하겠지만 이 경우엔 조금 다른 관점으로 바라봐야한다. 이를 위해 제목에서도 나와있듯이 이번 포스팅에서 중요한 것 중 하나인 pivot variablefree variable에 대해서 공부해보겠다. 우선 아까 계산한 U행렬을 다시 보자. 

 

 

 

 

U행렬에서 우리는 pivot column과 free column을 찾아야한다. 소거 과정에서 찾았던 pivot이 있는 column이 pivot column이고, 이를 제외한 나머지 column이 free column이다. 

그렇다면 여기에 왜 free라는 단어를 사용했을까? 이는 우리가 Ux=0의 해를 구할 때 free column에 대응되는 변수에 우리가 원하는 임의의 값을 자유롭게 설정할 수 있기 때문이다. 식(5)에서 free column은 2번째와 4번째이므로 solution 벡터 x에서 column2와 column4에 각각 곱해지는 x2와 x4는 우리가 원하는 값으로 설정할 수 있다. 그런 다음 x1과 x3에 대해 해를 구하면 된다. 이해가 잘 안갈테니 바로 예를 들어 설명해보자. 

 

아래는 Ux=0에서 해(solution) x벡터를 나타낸다. 앞서 말했듯이 x2와 x4에 임의의 값을 설정해보자. 일단 계산하기 가장 편리하도록 x2=1, x4=0으로 설정해보자. 100이던 -3891이던 어떤 값을 넣어도 상관없다. 

 

 

x의 free variable값을 설정했으니 이제 Ux=0에 대해서 풀어보자. 행렬로 자세히 풀어서 표현하면 아래 식 (7)과 같다. 

 

 

식 (7)을 다시 방정식으로 표현해보자. U의 row3는 모두 0이기 때문에 제외하면 총 2개의 방정식을 가진다. U의 row1과 row2를 각각 방정식으로 정리하면..

 

 

 

x2와 x4는 1과 0으로 각각 설정해서 값을 알고 있다. 나머지 x1과 x3는 Lecture 2에서 배웠던 후방대입법(Back substitution)을 통해 값을 찾을 수 있다. 이제 값을 찾아보자. 

 

x2=1, x4=0일 때, x3는 값이 얼마인가? 식 (8)의 두 번째 식에 후방대입법을 통해 x3=0임을 알 수 있다. 이제 x2=1, x3=0, x4=0이 되었다. 그렇다면 x1은 얼마인가? x1=-2임을 쉽게 계산할 수 있다. x를 다시 써보면..

 

 

 

 

x가 바로 Ux=0의 해(solution)이며 Null space이다. 또한 Ax=0의 해 이기도 하다. Ux=0와 Ax=0에서 위 x의 의미는 각 행렬에서 -2*col1 + 1*col2 = 0를 의미한다. 즉 column picture형식으로(Lecture 2) 정리하면 아래와 같다. 

 

 

 

Ux=0에서 구한 해 x를 Ax=0에도 똑같이 적용해도 식이 성립하는것을 볼 수 있다. 따라서 맨 처음 말했던 column space는 바뀔지언정 해(solution)인 Null space이는 변하지 않는다는 말이 이제 조금 이해가 될 것이다. 

 

 

 

 

 

 

- More solutions in Null space:

 

우리는 앞서 A와 U에 대한 해 x를 찾았다. 이 해는 Null space에 있다. 따라서 한 개가 아닐 것이다. 그렇다면 나머지 해들은 어떻게 찾을까? 바로 임의의 상수 c를 x에 곱해주면 된다. 식은 아래와 같이 될 것이다. 

 

 

 

 

임의의 상수 c가 곱해진 해 x는 4차원 공간 R4에서 무한대의 2차원 line을 표현한다. 이때 x는 분명 Null space상에 존재한다. 이와 관련해 아래 물음을 한 번 생각해보자. 

 

그렇다면 위의 식(12)에 있는 x는 A와 U에 대한 모든 Null space를 나타낼까? 

 

정답은 No다. 

우리는 이 시스템에서 2개의 free variable을 가지고 있다. 즉 x2와 x4가 free variable인데, 우리는 x2=1, x4=0으로 결정했을 때의 해를 구한 것이다. 다른 free variable을 선택했을 때의 해를 한 번 구해보자. 역시 어떠한 값을 적용해도 상관 없지만 계산을 쉽게 하기 위해 x2=0, x4=1을 대입해보도록 하겠다. 

 

 

위와 같이 값을 설정하고 아까의 후방대입법(back substitution)과정을 반복하면 된다. 식 (8)에 나타난 방정식을 아래와 같이 다시 써보자. 

 

 

후방대입법으로 계산하면 x3=-2, x1=2가 됨을 알 수 있다. x를 정리하면 아래와 같다. 

 

 

 

x가 선형방정식에서 의미하는 것은 2*col1+0*col2-2*col3+1*col4이다. U와 A의 방정식에 각각 대입하여 계산해보면 성립하는 것을 알 수 있다. 

 

 

자 이렇게 해서 우리는 Null space상에 존재하는 두 개의 해 (12)와 (15)를 구했다. 이 두 개의 해는 임의의 free variable을 설정하여 구한 해(solution)이며 이를 special solution이라 한다. 보통 special solution을 계산할 때는 첫 번재 free variable을 1로 놓고 나머지는 0, 그 다음은 두 번재 free variable만 1로 놓고 나머지는 0으로 설정하는 식으로 계산한다. 식 (15)의 x에 관련된 나머지 해들도 역시 여기에 임의의 상수를 곱해주면 구할 수 있다. 

 

 

임의의 상수 d를 직접 곱했을 때에도 식이 성립하는지 각자 확인해보자. 

 

우리는 식 (12)와 (18)에 나타난 두 개의 해를 가졌다. 각각은 Null space상에 존재하고, 이들은 임의의 free variable을 설정하여 만들어진 해들이다. 이제 우리는 이 두 개의 해의 선형 결합(Linear combination)을 통해 전체 Null space를 정의할 수 있다

 

 

 

그렇다면 이 special solution은 얼마나 존재하는 걸까? 이는 각 free variable마다 존재한다. 그럼 free variable은 얼마나 존재하는 걸까? 

 

우리는 앞서 행렬 A의 rank가 2이고 rank는 pivot variable의 수임을 배웠다. pivot variable의 수는 m(rows) x n(columns)행렬에서 column의 수인 n에 대해서 정의된다. 즉 n개의 column중에 pivot이 어느 column에 설정되는지를 보는 것이다. 그렇다면 free variable은 pivot을 뺀 나머지 column의 수가 될 것이다. 즉 column의 수에서 rank의 수를 뺀 것과 같다. 

 

 

column의 수 4에서 rank의 수 2를 뺀 2가 최종적인 free variable의 수가 된다. 조금 더 쉽게 설명하자면 다음과 같다. 

행렬 U는 두 개의 free variable을 가지고 있고 한개의 free variable이 하나의 해(solution)에 대한 line을 표현 했다고 생각하자. 이때 우리는 두 개의 free variable을 가지고 있기에 총 두 개의 line을 가지고 있으며 이 두 라인의 선형 결합으로 하나의 평면(plane)이 행렬 A의 Null space 전체를 표현하는 것이다.  

 

지금까지 배운 알고리즘을 통해 우리는 임의의 행렬 A의 모든 Null space를 구할 수 있다. 

 

 

 

 

 

 

 

 

2. 기약행 사다리꼴 행렬(Reduced row echelon form)

 

우리는 앞의 section에서 행렬 A를 소거하여 U를 만들었다. 이때의 U는 계단 형태를 보였고 이를 echelon형태임을 알았다. 이번 section에선 이 U행렬에대해 좀 더 알아보고 이를 더 간소화(소거) 시킨 형태인 기약행 사다리꼴 (Reduced row echelon form)을 만드는 법을 알아보도록 하자. 이는 쉽게 말해 어떤 행렬에 가우스 소거법(Gauss Elimination)을 적용했을 때 계단 모양이 나오며, 몇 가지 조건을 만족하는 행렬을 의미한다. 우선 U행렬의 식 (5)를 다시 보자. 

 

 

U행렬을 잘 보면 세 번째 row가 전부 0인 것을 알 수 있다. 왜 row3는 0이 될까? 바로 소거 전의 행렬 A의 row3가 row1과 row2의 선형 결합이기 때문이다. 식 (1)을 보면 row3=row1+row2인 것을 볼 수 있다. 결국 row3가 row1과 row2에 종속적(dependent)이기 때문에 소거를 한 행렬 U의 세 번째 row가 0이 되는 것이다. 이러한 관계를 소거(Elimination)작업이 찾아내는 것이다. 

 

자 이제 U행렬을 다시 한 번 간소화 해보도록 하자. 어떻게 하면 될까? Lecture 3에서 배웠던 Gauss-Jordan소거법을 기억하는가? 이와 같이 이번엔 아래에서 위쪽으로 소거를 진행하는 것이다. 그럼 어느 부분을 소거해야할까? 역방향(위쪽)으로 소거를 진행할 땐 pivot원소의 위쪽에 있는 원소들을 소거하는 것이다. 즉 기약행 사다리꼴 행렬(Reduced row echelon form matrix)은 pivot 원소들의 아래, 위로 모두 0이 되어야 한다. 이제 U행렬을 한 번 소거해서 기약행 사다리꼴로 만들어보자. 

 

 

바로 위의 식 (5)에서 pivot 원소가 두 개 존재한다. 첫 번째 pivot(row1, col1)은 아래 위로 모두 원소가 0이다. 그러나 두 번째 pivot(row2, col3)은 위쪽 원소(row1, col3)가 2이다. 따라서 이를 소거해줘야한다. 소거 방법은 소거할 원소가 pivot과 같기 때문에 1을 곱해서 빼주면 된다. 즉 row1 = row1 - row2 와 같이 하면 된다. 결과는 아래와 같다. 

 

 

 

여기서 기약행 사다리꼴이 되기 위한 한 가지 과정을 더 진행해보자. 바로 pivot원소들을 모두 1로 만드는 것이다. 첫 번째 pivot은 이미 1이므로 그대로 놔두고 두 번째 pivot을 1로 만들어보자. 방법은 그냥 간단하게 pivot이 있는 row전체를 pivot으로 나눠주면된다. 결과는 아래와 같다. 

 

 

식 (22)의 마지막 행렬이 바로 기약행 사다리꼴 행렬(Reduced row echelon form matrix)인 R이다. 

이 행렬은 MATLAB에서 rref(A)라는 명령어를 통해 계산할 수 있다. A는 계산하고자 하는 input 행렬이다. 

결국 기약행 사다리꼴 행렬(Reduced row echelon form)이 되기 위해선 다음의 조건들을 만족해야 한다. 

 

 

기약행 사다리꼴 행렬이기 위한 조건:


  • pivot 원소들은 반드시 1이 되어야 한다. 
  • pivot 원소가 있는 column에서 pivot 변수의 모든 아래/위 원소들은 0이 되어야 한다. 
  • 각 row는 처음 나오는 pivot 원소를 만나기 전까지 모든 원소가 0이어야 한다.
  • 모든 원소가 0인 row는 반드시 pivot 변수가 있는 row의 밑에 있어야 한다. 

 

 

 

 

 

 

 

기약행 사다리꼴 행렬은 많은 정보들을 담고 있다. 어떤 정보들을 담고 있을까? 

바로 알아볼 수 있는 정보로는 row1과 row2인 pivot row와 col1과 col3인 pivot column을 볼 수 있다. 또한 U행렬 내에 단위 행렬(identity matrix)를 담고 있다. 아래 식을 보자. 

 

 

 

 

 

빨간색 box는 pivot row를, 파란색 box는 pivot column을 나타낸다. 이 둘이 겹쳐지는 부분을 보자. 2x2 크기의 단위 행렬의 모습이 보일 것이다. 이 단위행렬이 나타나는 당연한 이유는 우리는 행렬 A를 소거하는 과정에서 pivot variable의 위/아래의 모든 원소를 0으로 맞추었고, 모든 pivot을 1이 되도록 만들었다. 따라서 이러한 단위 행렬이 당연히 나타나게 된다. 

 

자 이렇게 해서 우리는 처음에 A행렬에서 가우스 소거를 통해 U행렬을 만들었고, 여기에 한 번더 가우스 소거를 적용하여 R행렬을 만들었다. 즉 A->U->R로 변화한 것이다. 이를 정리해보면 아래와 같다. 

 

우리는 A에서 U로 행렬을 변환한 뒤에도 Ax=0와 Ux=0의 해는 동일한 Null space에 존재함을 알았다. 그렇다면 U를 소거하여 만든 Rx=0의 해도 역시 동일한 Null space에 존재할까? 정답은 Yes이다. 앞서 구한 해를 R행렬에 적용하여 이를 확인해보자. 

 

 

식 (24)를 보면 역시 Rx=0해도 동일한 Null space에 존재하는 것을 알 수 있다. 우리는 행렬을 A에서 R로 변화시켰다. 그 과정에서 비록 각 행렬의 column space는 변했을지 모르나 원래의 행렬에 대한 고유한 성질은 변하지 않았다. 그렇기에 해가 동일한 공간(Null space)에 존재하는 것이다. 우리는 단지 A행렬을 줄이고 줄이고 줄여서 가장 간단한 형태인 R로 만들었다고 생각하면 좋을 것 같다. 

 

 

- Another example:

 

다른 행렬에 대한 Null space계산을 한 번 더 풀어보자. 임의의 행렬을 만들 수도 있으나 앞서 풀었던 A행렬을 전치(transpose)시킨 행렬을 가지고 계산해 보도록 하자. 중복된 내용이 많을 테니 수식으로만 간단히 표현하겠다. 

 

 

 

소거된 행렬 U에 대한 방정식을 쓰면..

 

 

x3=1로 설정한 뒤 후방 대입법(Back substitution)을 통해 나머지 해를 계산하면 x=[-1 -1 1]T이 된다. 여기서 전체 Null space를 표현하려면 임의의 상수 c를 곱한 x가 된다. 

 

 

이 예제에선 pivot이 두 개이고 따라서 Rank=2 이다. free variable은 column의 수에서 rank를 빼주면 되므로 n-r = 3-2 = 1이 된다. free variable이 하나 밖에 없기 때문에 식 (27)의 임의의 상수만 곱한 벡터 x가 전체 Null space를 표현하게 된다. 

 

 

 

3. 마치며

 

이번 포스팅에서는 지난 강의에서 배웠던 Null space를 구하는 알고리즘에 대해 공부하였다. 우리는 임의의 행렬 A를 가우스 소거를 통해 U행렬로 만드는 법을 배웠고 pivot과 free variable이 갖는 의미에 대해서 배웠다. 이 과정에서 pivot의 개수가 그 행렬의 rank를 의미한다는 중요한 사실을 알 수 있었다. 

우리는 또한 A-> U -> R로 만드는 과정을 통해 처음 임의의 행렬 A가 축소된 형태인 기약행 사다리꼴(reduced row echelon form)을 만드는 방법에 대해서도 배웠다. 또한 이 행렬이 갖는 의미를 배웠고 Null space를 정의하는 방법에 대해서도 알 수 있었다. 

 

필자는 본인의 전공 분야에 관한 좋은 원서를 읽고 책 내용을 번역 해서 개인 블로그에 포스팅 하고 있었다. 



  • 번역해서 포스팅을 하는 과정에서 훨씬 정리도 잘 되고 
  • 나중에 다시 찾아보기도 좋고
  • 그리고 영어에 고통 받는 많은 학생들에게 조금이나마 도움이 되고자 시작한 일이었다. 




그런데 포스팅을 하면서 뭔가 항상 마음 한구석이 찜찜했는데..

이거 혹시 불법 아니야? 

원작자의 허락도 없이 마음대로 이래도 되는 건가? 

이런 불안감이 문득 문득 엄습하곤 했다. 


결국 불안감을 떨치지 못하고 관련 내용에 대한 구글링을 착수





결과는...



저자의 허락 없이 원서를 번역하여 포스팅(posting) 하는 것은 역시나 불법이었다!! 





그런데 비영리 블로그면 괜찮지 않을까? 

광고 같은거 안 달아서 수익 발생하지 않으면 괜찮지 않을까? 

번역한 내용을 출판한다거나, 판매한다거나 하지 않으면 괜찮지 않을까? 



와 같은 생각이 들 수도 있다. 

그러나 위의 물음도 전부 괜찮지않다.!




재미있게도 필자와 똑같은 생각을 가지고 쿼라(Quora)에 다음과 같은 질문을 올린 중국인으로 추정되는 사람이 있었다. 


원서를 번역해서 온라인에 올리는 것은 불법인가요? 

Is it illegal to translate a book and post the translation online?



아래는 관련 질문의 링크이다. 

https://www.quora.com/Intellectual-Property-Is-it-illegal-to-translate-a-book-and-post-the-translation-online



아래는 질문의 내용 캡쳐 화면





요약하자면

내가 좋은 원서(English)를 봤는데, 아직 중국어로 번역된 것이 없는 것 같다. 그래서 이 좋은 책의 내용을 중국어로 번역해서 나의 개인 블로그에 올리고 싶다. 난 이 번역한 내용을 출판하지도 않을 거고, 어디에 팔지도 않을거며 내 개인 블로그에는 광고도 달지 않고 어떠한 이익도 취하지 않을거다. 그래도 이게 불법인가? 저자가 날 고소하려나? 




이에 대한 답변이 10개 정도 달렸는데.. 그 중에 Best 답변은 이렇다. 






당연히 당신과 같은 행동은 미국 저작권법에 위배 되는 행동이다. 

미 저작권법 title 17, chapter 1, section 106에 의하면 원서를 번역하는 행동은 파생작(derivative work)을 만드는 행동인데, 이러한 파생작을 만들기 위한 권리는 원작자에 독점권(exclusive right)이 있다. 라고 되어있다. 


만약 책이 저작권(copyright registration)에 등록되어 있다면, 저작권을 가진 사람은 당신에게 법정손해배상(statutory damages)을 청구할 권리가 있다. 법정 재량에 따라 $750~$150,000(한화로 약 90만원 ~ 1억 8천)의 손해배상금을 청구할 수 있다.

흠....




그래서 제가 미국 저작권법을 실제로 찾아 봤습니다. 답변 내용이 맞는 것 같긴 하네요. 아래는 링크 주소..


https://www.copyright.gov/title17/92chap1.html#106







포스팅 잘못 했다가 재산 탕진 할 수도 있겠군요;;



그러나 답변 말미엔 실질적인 내용을 언급했는데

대부분의 경우는 번역 포스팅에 대한 피해 정도가 그리 심각하지 않고, 원저자가 이러한 사항들을 일일이 확인할 수 없기에 법정까지 가는 상황은 거의 없다고 합니다. 그러나 어디까지나 "아마도"라고...

원저자가 고소 하고 싶으면 고소 하는 거고.. 



어쨋든 결론은 

원서 번역해서 포스팅하고 싶으면


  • 저작권이 없는 책이거나 
  • 저작권이 만료된 책이거나(일반적으로 저자 사후(死後


    ) 70년 이후 만료)
  • 저작권자의 허락을 받거나
  • 번역해서 혼자만 볼 수 있게끔 비공개로 하던가
  • 아니면 배짱 부리고 안들키길 기도하던가




저작권법을 찾아 공부한 후에, 원래 보던 원서의 앞 페이지를 다시 보니.. 평소엔 절대로 보이지 않을 것 같은 다음의 글귀가 보이네요.



All rights reserved. No part of this book may be reproduced, in any form, or by any means, without permission in writing from the publisher. 




포스팅에 대한 인식을 좀 바꿔야 겠습니다 ^^


'이것 저것' 카테고리의 다른 글

어떤 프로그래밍 언어가 가장 널리 사용될까?  (0) 2017.04.16

앞선 포스팅에서 우리는 이미지를 획득하는 다양한 방법에 대해 배웠다. 그러나 이렇게 다양한 이미지 획득 방법들의 최종 목적은 같다. 바로 센싱된 데이터들로부터 디지털 이미지를 만들어내는 것이다. 

대부분의 센서 데이터들은 센싱된 장면(scene)에 관련된 연속적인 전압의 파형(continuous voltage waveform)이며, 해당 장면의 특성은 파형의 진폭(amplitude)의 패턴으로 표현된다. 센싱된 전압 파형으로부터 디지털 이미지를 만들어내기 위해선 이러한 연속된 파형을 디지털 형식으로 바꿔야 한다. 연속된 파형을 얻는 과정, 디지털 형식으로 바꾸는 과정을 각각 샘플링(sampling)양자화(quantization)라 한다. 이번 포스팅에선 샘플링과 양자화에 대해 알아보도록 하겠다. 

 

 

 

1. 샘플링(sampling)과 양자화(quantization)의 기본 개념

 

- 샘플링(sampling)의 기본 개념 

 

샘플링(sampling)이라는 것은 기본적으로 수 많은(무한한) 데이터들 가운데 유한한 개수의 데이터를 뽑아내는 것이다. 

가령 속이 보이지 않는 어떤 상자에 10,000개의 공을 넣어 놓고 상자속 공의 색깔에 대한 분포를 추정한다고 생각해보자. 모든 공을 전부 뽑아서 조사하면 가장 정확하겠지만 시간과 비용이 너무 많이 든다. 따라서 10,000개의 공 중에 1000개만 뽑아낸다고 했을 때, 공을 뽑아내는 행위 자체를 샘플링이라고 한다. 

 

즉 어떤 모집단 전체의 데이터를 전부 사용하면 가장 정확하겠지만 시간과 비용이 많이 소모되기 때문에 적당한 개수의 데이터만 뽑아서 전체의 패턴을 추정하기 위한 데이터 수집 행위라고 할 수 있다. 

 

상자속 공의 샘플링말고 실제 1차원 신호를 예로 들어보자. 

 

녹음기 하나를 떠올리고, 이 녹음기에 어떤 대화를 녹음하는 것을 상상해보자. 이때 우리가 말하는 내용은 음성 신호(voice signal)로써 특정 파형(waveform)의 형태를 보일 것이다. 아래 그림을 실제 아날로그 음성 신호라고 가정해보자. 

 

 

 

 

 

가로축은 시간(time), 세로축은 진폭(amplitude)를 나타낸다. 

여기서 샘플링이라는 것은 어떤 것을 의미할까? 바로 일정한 간격의 주기로 신호의 강도를 수집하는 것을 의미한다. 이때 중요한 것은 어느 위치, 혹은 어느 시간에 진폭값이 얼마인지를 알아내는 것이다. 여기에 추가로 샘플링 주파수(sampling frequency)도 굉장히 중요하다. 원래 신호 모양을 온전히 복원하기 위해선 나이퀴스트 샘플링 주파수(Nyquist Sampling frequency) 규칙을 따라야한다. 이에 대한 내용은 본 포스팅 범위를 벗어나므로 패스하겠다. 구글에 검색하면 관련된 많은 자료가 있으니 참고하기 바란다. 

 

 

자 이제 위의 신호를 샘플링 해보자. 아래 그림에서 빨간 줄이 샘플링 지점(sampling point)라고 생각하면 된다. 즉 시간의 단위를 초(second)라고 했을 때 1초 때의 신호의 강도를 수집하여 저장하고 2초때 신호 강도를 수집해 저장하는 식으로 신호를 수집하는 것이다. 아래 그림은 위 신호의 샘플링 과정을 나타낸 모습이다. 

 

위의 점들을 직선으로 이어보자. 원래의 신호와 비교 했을 때 비슷한가? 아닐 것이다. 좀 더 촘촘하게(짧은 주기, 높은 주파수로) 샘플링을 할 수록 원래 신호에 가까워진다. 

 

 

 

샘플링 과정을 보면 매 샘플링 주기 T(여기선 1초로 가정)마다 신호의 강도(amplitude)를 측정하여 그 값을 저장한다. 위 그림의 아래는 샘플링 결과를 나타낸다. 

 

샘플링 주기가 짧을 수록 원래의 신호를 더 잘 복원할 것이다. 그러나 반대로 샘플링을 위해 더 많은 연산을 해야 하므로 샘플링 비용이 증가하고 이에 따른 부담이 커진다는 단점이 있다. sampled signal의 그림을 보면 매 샘플링 시간 마다 그 시간 위치에서의 진폭값(amplitude)이 빨간색 점으로 표현되어 있다. 이 점들을 차례로 연결시키면 원래의 신호 패턴이 복원될 것이다. 물론 앞서 언급했듯이 샘플링 주기가 짧을 수록, 이말은 곧 샘플링 주파수(sampling frequency)가 높다는 의미이며 샘플링 주파수가 높을 수록 원래의 신호에 더 가깝게 된다. 아래의 식과 같이 주기와 주파수는 역수의 관계임을 잘 생각하자. 

 

 

 

 

- 양자화(quantization)의 기본 개념

 

양자화(quantization)라는 것은 샘플링(sampling)한 아날로그 형태로 되어 있는 신호나 정보를 디지털화(digitizing) 하는 작업을 말한다. 좀 더 쉽게 말하자면 다음과 같다. 

 

0 ~ 1사이의 숫자를 생각해보자. 아날로그 방식으로 생각해보면 0과 1사이엔 실제로 무수히 많은 숫자가 존재한다. 0.1, 0.2479, 0.78001, 0.99999 등 우리가 셀 수 없이 많은 수가 무한대로 존재하는 것이다. 현실적으로 이 무수한 숫자들을 다루기란 불가능하기 때문에 우리는 일정한 범위와 기준값을 정해놓고 어떤 임의의 숫자가 나오면 그와 가장 근접한 기준값으로 만들어 사용하는 것이다. 

 

예를 들어 우리가 어떤 전압 값을 측정한다고 해보자. 이때 우리는 0.1V 단위로만 값을 측정한다고 가정해보자. 실제의 전압 값이 3.4122319800200922212935482...V 라고 했을 때 과연 이 값을 전부 표현하는것이 옳은가? 저렇게까지 정밀하게 측정하기도 어려울 뿐더러 그럴 만한 정밀한 센서도 없고 그럴 필요성도 없다. 이럴때 우리는 뒤에 필요 없는 정보는 생각하지 않고 측정된 값을 가장 근접한 값으로 만들어 사용하는 것이다. 

실제로 센서에 의해 측정된 아날로그 전압값이 3.41223V라고 했을 때 0.1V 단위로 측정한다고 했으니 이때의 양자화 시킨 Voltage값은 3.4V일 것이다. 

 

결국 양자화라는 것은 무한대로 이루어진 셀 수 없는 아날로그 정보를 셀 수 있을 만큼의 간격으로 만들어서 유의미한 정보만을 사용하는 것이다. 이 말은 샘플링에도 유효할 것이다. 

 

위에서 봤던 신호 샘플링의 그림을 다시 보자. 

 

t=2의 진폭 값과 t=4일 때의 진폭값은 눈으로 봤을 때 당연히 다르다. 그러나 0.1V단위로 양자화를 하게 되면 t=2와 t=4는 같은 전압값(0.2V)을 가지게 된다. 적절한 양자화의 Level설정이 필요하다. 

 

 

아까 수집한 전압 값을 0.1V 단위로 양자화 한다고 가정해보자. t=1일 때의 실제 측정된 신호의 진폭은 0.0973V이다. 양자화 과정을 통해 가장 가까운 값인 0.1V로 만들었고 결국 t=1일때의 신호 값은 0.1V가 된다. t=2 일때는 0.2V, t=3일때는 0.3V가 각각 되고 t=7일때는 -0.1V가 되는 것이다. 이렇게 하여 컴퓨터의 메모리에는 [0.1, 0.2, 0.3, 0.2, 0.3, ... ]의 값들이 배열의 형태로 순차적으로 저장된다.

 

그런데 위와 같이 0.1V단위로 양자화를 하게 되면 t=2일 때 0.2V가 되고 t=4일 때도 역시 0.2V가 된다. 눈으로 보기엔 분명 t=2와 t=4의 진폭값은 다르다. 그러나 양자화 결과 같은 값이 되는 것이다. 이때에 양자화 단계를 0.05V로 설정했다면 t=2와 t=4는 다른 진폭값으로 기억될 것이다. 따라서 적절한 양자화(quantization) Level 설정이 중요하다. 

 

 

 

2. 이미지의 샘플링(sampling)과 양자화(quantization)

 

- 이미지 샘플링(sampling)

 

우리는 지금까지 1차원 신호에 대한 샘플링과 양자화에 대한 개념을 공부하였다. 그렇다면 2차원인 이미지의 경우엔 샘플링과 양자화가 어떻게 이루어질까? 간단하다. 2차원 배열(2-D Array)형태의 센서를 이용해 영상 신호를 샘플링하고 양자화 하는 것이다. 2-D Array센서로는 대표적으로 CCD(Charge Coupled Device)와 CMOS(Complementary metal-oxide semiconductor)라는 센서가 있다. 두 센서에 대한 자료는 인터넷에 지나치게 많으니 자세한 설명은 생략하고.. 

 

간단히 얘기해서 빛 에너지를 전기신호로 바꾸는 센서이다. 즉 어떤 장면을 카메라로 촬영한다고 했을 때, 광원(태양 등)으로부터 나온 빛이 어떤 사물이나 환경에 다다른다. 이후 대상 물체에 반사된 빛 에너지들이 카메라 렌즈를 통과해 아래 그림과 같은 2-D Array 센서판에 다다르게 된다. 이때 센서 Array는 촬영한 장면에 대한 빛 에너지의 패턴대로 각 Cell에 일정 전압이 걸리게 되고 각 Cell에 대한 전압값은 양자화 과정을 통해 디지털 값으로 변환되어 메모리에 저장된다. 이 과정이 아래 그림에 나타나있다. 

 

 

 

 

카메라 안쪽에 위치한 2-D Array모습은 아래 그림과 같이 여러 개의 CCD 혹은 CMOS센서들이 촘촘하게 배열되어 있는 모습이다. 이때 빛의 3원색인 빨강, 초록, 파랑의 총 3가지 색깔의 빛 에너지를 흡수하는 센서들이 교차 배치되어 컬러 이미지를 형성하도록 한다. 각 센서는 해당 색깔만 통과시키는 필터가 있어서 해당 색깔 정보만 받아들이며, 이들의 컬러 조합으로 컬러 이미지가 만들어진다. 

 

 

 

Bayer pattern으로 불리는 2-D Array 센서. (이미지 출처: 위키 https://en.wikipedia.org/wiki/Bayer_filter)

 

 

 

그렇다면 2-D Array 센서가 이미지의 형성과 어떤 관계가 있을까? 2-D Array센서는 결과적으로 이미지의 품질(Quality)에 막대한 영향을 미치게된다. 2-D Array센서의 밀도가 높을수록, 즉 단위 면적당 센서의 개수가 많을 수록 이미지의 품질은 높아진다. 

우리는 흔히 디지털 카메라의 스펙을 이야기할 때 화소(picture element)를 이야기한다. 화소는 센서 Array 개개의 cell의 개수를 의미하는데, 예를 들어 1000만 화소라 하면 위 그림과 같은 센서 Array의 각 cell의 개수가 1000만개임을 뜻한다. 당연히 화소가 높을 수록 장면의 디테일한 부분까지 이미지에 표현되기 때문에 이미지의 품질에 큰 영향을 미친다. 카메라의 화소가 높다는 것은 결국 어떤 장면에 대한 빛의 패턴 신호를 높은 주파수(혹은 짧은 주기)로 샘플링 하는 것을 의미한다. 이와 관련하여 아래 그림을 참조 하여 이해를 해보자. 

 

 

 

센서 Array의 밀도에 따른 이미지 Quality. 왼쪽: 저밀도, 오른쪽 고밀도 센서 Array

꽃 이미지 출처: http://ccideas.com/chatter/high-resolution-images-vs-low-resolution-images-a-short-primer-for-beginners/

 

 

위 그림은 이미지 센싱을 위한 센서 Array의 밀도에 따른 이미지 품질을 나타낸 것이다. 왼쪽은 센서 Array의 밀도가 낮은 경우, 오른쪽은 고밀도 센서 Array를 이용해 이미지를 생성한 결과를 보여준다. 센서 밀도가 낮다는 것은 단위 면적당 각 Cell의 개수가 적은 것이고 그 만큼 촬영 대상 환경의 빛 에너지 패턴의 샘플링 주파수가 낮음을 의미한다. 

반대로 센서의 밀도가 높은 경우엔 단위 면적당 각 Cell의 개수가 많은 것이고 샘플링 주파수가 높기 때문에 원래의 이미지를 더 잘 복원하게 된다. 이때 한 cell에서 다음 cell까지의 거리를 샘플링 주기라고 생각하면 된다. 이러한 샘플링 과정이 x와 y축으로 동시에 존재하는 것이 2-D 센서 Array라고 생각하면 된다. 

 

그림의 아래쪽을 보면 dpi라고 표기된 부분은 dots per inch의 약자이며 1inch당 존재하는 정사각형(square)화소의 개수를 의미한다. 72 dpi는 1inch 길이의 라인에 존재하는 점이나 화소의 개수를 의미한다. 아래의 그림들은 dpi의 개념을 나타낸다. 

 

dpi별 이미지. 출처: http://www.tatge.biz/working-with-images-hi-res-vs-lo-res/

 

 

DPI(dots per inch)는 주로 프린터의 출력 분해능(resolution)을 표현하는데에 많이 사용되고 모니터나 이미지의 분해능(resolution)을 표현할 때는 PPI(pixels per inch)를 주로 사용한다. dpi에 따른 이미지를 잘 살펴보자. 

 

 

- 이미지 양자화(quantization)

 

이번에는 이미지의 양자화(Quantization)에 관해 알아보자. 

이미지 샘플링은 Array형태로 존재하는 이미지 센서를 통해 각 cell에 주사되는 빛 에너지의 양을 전압(voltage)으로 변환하여 저장하는 것을 의미한다. 이미지 양자화는 각 cell에서 변환한 전압값을 일정한 주기의 기준값에서 가장 근접한 디지털 값으로 매칭시키는 과정을 의미한다. 아래 그림을 보자. 

 

 

 

 

 

 

빛 에너지가 이미지 센서 Array에 다다르고, 빛의 강도와 파장에 따라 전압 값으로 변환된다. 여기 까지가 샘플링(sampling)단계이다. 이제 빛 에너지로부터 변환된 아날로그 전압값을 일정한 간격으로 나뉜 기준값들중 가장 가까운 값으로 matching이 이루어진다. 위의 양자화의 기본 개념 부분을 참고해보자. 결국 아날로그 전압값으로부터 적정 디지털 값으로 연결시키는 작업이 양자화(quantization) 단계이다. 이러한 기본적인 양자화 단계가 각 cell에 걸쳐 전반적으로 이루어지게 되고, 이를 통해 우리는 각 cell, 즉 이미지의 각 pixel에 대한 강도 값(intensity)을 얻을 수 있다. 

 

샘플링에서부터 양자화를 거쳐 최종적인 이미지를 얻기 까지는 굉장히 복잡한 단계를 거치게 된다. 이번 포스팅에서는 이 복잡한 과정중 샘플링과 양자화의 관점에서만 설명한 것이지 이면에는 굉장히 복잡한 과정들이 숨어있다. 

 

디지털 이미지의 양자화는 다양한 Level로 구성할 수 있다. 즉 전압값을 양자화할 때 몇 개의 간격으로 잘라서 디지털 값으로 매칭을 시킬지를 결정하는 것이다. 필자가 개인적으로 좋아하는 League of Legend의 베인 캐릭터 그림을 이용해 양자화 Level에 따른 결과이미지를 출력해 보았다. 쉬운 이해를 위해 흑백 이미지를 이용하여 구현하였다. 

 

 

L은 양자화의 Level을 의미하며 검은색으로부터 흰색에 이르는 밝기의 변화를 몇 단계로 자를지를 결정하는 것이다. L=4일 경우 4단계로 쪼개서 밝기 값을 표현하는 것이다. 흑백(gray-scale)영상에서 L은 2의 거듭제곱으로 표현되며 최대값은 256이다. 이는

을 의미하며 0~255까지의 밝기 값을 표현한다. 따라서 이미지의 한 pixel당 1Byte로 밝기 값을 표현한다. 

 

L=2인 이미지를 바이너리 이미지(binary image)라 부른다. 흑과 백 단 두 가지 밝기 값만을 이용해 이미지를 표현한 것이다. 이러한 바이너리 이미지는 영상처리에서 segmentation, 모폴로지 연산 등 특수한 상황에 사용되는 이미지이다. 

 

결과적으로 양자화 Level이 높을 수록(더 세밀하게 잘라서 밝기값 혹은 컬러값을 표현할수록) 원래의 영상(장면)에 가깝게 이미지가 표현되는것을 볼 수 있다. 

 

아래는 이미지 양자화의 단계별 영상을 출력하는 MATLAB 코드이다. 

 

 

+ Recent posts