MATLAB 환경에서의 행렬

여기에서는 MATLAB®에서 행렬을 생성하고 기본 행렬 계산을 수행하는 방법을 소개합니다.

MATLAB 환경에서는 2차원 그리드의 실수 또는 복소수 변수를 행렬이라는 용어를 사용하여 나타냅니다. 배열이라는 용어는 일반적으로 숫자로 구성된 벡터, 숫자로 구성된 행렬, 숫자로 구성된 더 높은 차원의 그리드를 뜻합니다. MATLAB의 모든 배열은 사각 배열이며, 이는 차원별로 성분 벡터의 길이가 모두 같다는 것을 의미합니다. 행렬에 정의되는 수학적 연산이 선형 대수의 대상입니다.

행렬 생성하기

MATLAB에는 다양한 유형의 행렬을 생성할 수 있는 여러 함수가 들어 있습니다. 예를 들어, 다음과 같이 파스칼의 삼각형에 기반한 요소들로 구성된 대칭 행렬을 생성할 수 있습니다.

A = pascal(3)
A =
       1     1     1
       1     2     3
       1     3     6

또는, 다음과 같이 행의 합과 열의 합이 같은 비대칭 마방진 행렬을 생성할 수 있습니다.

B = magic(3)
B =
       8     1     6
       3     5     7
       4     9     2

또 다른 예는 임의의 정수로 구성된 3x2 직사각 행렬입니다. 여기서 randi에 대한 첫 번째 입력값은 정수 값의 가능한 범위를 나타내고, 그다음 두 입력값은 각각 행 개수와 열 개수를 나타냅니다.

C = randi(10,3,2)
C =

     9    10
    10     7
     2     1

열 벡터는 mx1 행렬이고, 행 벡터는 1xn 행렬이며, 스칼라는 1x1 행렬입니다. 행렬을 수동으로 정의하려면 대괄호([ ])를 사용하여 배열의 시작과 끝을 나타내십시오. 대괄호 안에서는 세미콜론(;)을 사용하여 한 행의 끝을 나타냅니다. 스칼라(1x1 행렬)의 경우에는 대괄호를 사용할 필요가 없습니다. 예를 들어, 다음 명령문은 각각 열 벡터, 행 벡터, 스칼라를 생성합니다.

u = [3; 1; 4]

v = [2 0 -1]

s = 7
u =
       3
       1
       4

v =
       2     0    -1

s =
       7

행렬을 만들고 이를 사용하는 방법에 대한 자세한 내용은 행렬 생성, 결합, 확장하기 항목을 참조하십시오.

행렬의 덧셈과 뺄셈

행렬과 배열의 덧셈과 뺄셈은 요소별로 수행됩니다. 예를 들어, AB를 더한 다음, 그 결과에서 A를 빼면 다시 B가 됩니다.

X = A + B
X =
       9     2     7
       4     7    10
       5    12     8
Y = X - A
Y =
       8     1     6
       3     5     7
       4     9     2

덧셈과 뺄셈을 수행하려면 두 행렬의 차원이 호환되어야 합니다. 차원이 호환되지 않으면 오류가 발생합니다.

X = A + C
Error using  + 
Matrix dimensions must agree.

자세한 내용은 배열 연산과 행렬 연산 항목을 참조하십시오.

벡터의 곱과 벡터의 전치

길이가 같은 행 벡터와 열 벡터는 어느 쪽으로든 곱할 수 있습니다. 그러면 그 결과로 스칼라(내적이라고 함) 또는 행렬(외적이라고 함)을 얻게 됩니다.

u = [3; 1; 4];
v = [2 0 -1];
x = v*u
x =

     2
X = u*v
X =

     6     0    -3
     2     0    -1
     8     0    -4

실수 행렬의 경우 전치 연산을 수행하면 aij와 aji가 교환됩니다. 복소수 행렬의 경우, 한 가지 더 고려할 사항은 배열에서 복소수 요소의 켤레 복소수를 구해 켤레 복소수 전치를 생성할지 여부입니다. MATLAB에서는 아포스트로피 연산자(')를 사용하여 켤레 복소수 전치를 수행하고, 점-아포스트로피 연산자(.')를 사용하여 켤레 없이 전치를 수행합니다. 실수 요소만 포함되어 있는 행렬의 경우에는 두 연산자가 모두 동일한 결과를 반환합니다.

예로 든 행렬 A = pascal(3)대칭 행렬이므로 A'A는 서로 같습니다. 반면 B = magic(3)은 대칭 행렬이 아니므로 B'에서는 요소들이 주대각선을 기준으로 대칭 이동합니다.

B = magic(3)
B =

     8     1     6
     3     5     7
     4     9     2
X = B'
X =

     8     3     4
     1     5     9
     6     7     2

벡터의 경우 전치를 수행하면 행 벡터는 열 벡터로, 열 벡터는 행 벡터로 변환됩니다.

x = v'

x =
       2
       0
      -1

xy가 모두 실수형 열 벡터인 경우 곱 x*y는 정의되지 않지만 다음 두 개의 곱

x'*y

y'*x

는 동일한 스칼라 결과를 산출합니다. 이 수량은 매우 자주 사용되며 내적(Inner Product), 스칼라 곱(Scalar Product), 내적(Dot Product)이라는 세 가지 다른 이름으로 불립니다. dot라는, 내적 전용 함수도 있습니다.

복소수 벡터 또는 복소수 행렬 z의 경우 수량 z'는 벡터 또는 행렬을 전치하는 것은 물론 각각의 복소수 요소를 해당 켤레 복소수로 변환합니다. 즉, 각 복소수 요소의 허수부 기호가 변경되는 것입니다. 다음 복소수 행렬을 예로 들어 보겠습니다.

z = [1+2i 7-3i 3+4i; 6-2i 9i 4+7i]
z =

   1.0000 + 2.0000i   7.0000 - 3.0000i   3.0000 + 4.0000i
   6.0000 - 2.0000i   0.0000 + 9.0000i   4.0000 + 7.0000i

z의 켤레 복소수 전치는 다음과 같습니다.

z'
ans =

   1.0000 - 2.0000i   6.0000 + 2.0000i
   7.0000 + 3.0000i   0.0000 - 9.0000i
   3.0000 - 4.0000i   4.0000 - 7.0000i

각 요소의 복소수부 기호가 그대로 유지되는 비켤레 복소수 전치는 z.'로 나타냅니다.

z.'
ans =

   1.0000 + 2.0000i   6.0000 - 2.0000i
   7.0000 - 3.0000i   0.0000 + 9.0000i
   3.0000 + 4.0000i   4.0000 + 7.0000i

복소수 벡터의 경우, 두 스칼라 곱 x'*yy'*x는 서로에 대한 켤레 복소수이며, 복소수 벡터의 제곱인 스칼라 곱 x'*x는 실수입니다.

행렬 곱셈

행렬의 곱셈은 선형 변환의 결합을 나타내는 방식으로 정의되며, 선형 연립방정식을 간결하게 표현할 수 있도록 합니다. A의 열 차원이 B의 행 차원과 같거나 이들 중 하나가 스칼라인 경우 행렬 곱 C = AB를 정의할 수 있습니다. A가 mxp이고 B가 pxn이면 이들의 곱 C는 mxn입니다. 이 곱은 실제로 MATLAB for 루프, colon 표기법, 벡터 내적을 사용하여 정의할 수 있습니다.

A = pascal(3);
B = magic(3);
m = 3; 
n = 3;
for i = 1:m
     for j = 1:n
        C(i,j) = A(i,:)*B(:,j);
     end
end

MATLAB은 C = A*B와 같이 별표를 사용하여 행렬 곱셈을 나타냅니다. 행렬 곱셈은 가환적이지 않습니다. 즉, A*B는 일반적으로 B*A와 같지 않습니다.

X = A*B
X =
      15    15    15
      26    38    26
      41    70    39
Y = B*A
Y =
      15    28    47
      15    34    60
      15    28    43

행렬은 오른쪽으로 곱하면 열 벡터와 곱하고 왼쪽으로 곱하면 행 벡터와 곱할 수 있습니다.

u = [3; 1; 4];
x = A*u
x =

     8
    17
    30
v = [2 0 -1];
y = v*B
y =

    12    -7    10

사각 행렬 곱셈은 차원 호환성 조건을 충족해야 합니다. A는 3x3이고 C는 3x2이므로, 이 두 행렬을 곱하면 그 결과로 3x2 행렬(즉, 공통된 내부 차원이 소거됨)이 반환됩니다.

X = A*C
X =

    24    17
    47    42
    79    77

반면, 순서를 반대로 하여 곱하면 제대로 동작하지 않습니다.

Y = C*A
Error using  * 
Incorrect dimensions for matrix multiplication. Check that the number of columns 
in the first matrix matches the number of rows in the second matrix. To perform 
elementwise multiplication, use '.*'.

스칼라와는 이러한 조건 없이 곱할 수 있습니다.

s = 10;
w = s*y
w =

   120   -70   100

배열과 스칼라를 곱할 경우, 스칼라는 다른 입력값과 같은 크기가 되도록 암시적으로 확장됩니다. 이를 보통 스칼라 확장이라고 합니다.

단위 행렬

일반적인 수학 표기법에서는 대문자 I가 단위 행렬을 나타냅니다. 단위 행렬은 주대각선상의 요소가 1이며, 그 외 나머지 요소가 0인 다양한 크기의 행렬을 말합니다. 단위 행렬의 특성상, 차원이 호환되는 경우 AI = A가 성립되고 IA = A가 성립됩니다.

최초 버전의 MATLAB에서는 I를 이러한 용도로 사용할 수 없었습니다. 이유는 프로그램에서 대문자와 소문자를 구분하지 못했고 i가 이미 첨자나 복소수 단위로 사용되고 있었기 때문이었습니다. 따라서 동음이의의 영단어를 차용해 함수 이름을 만들어야 했습니다. 다음 함수는

eye(m,n)

mxn 사각 단위 행렬을 반환하고 eye(n)은 nxn 정사각 단위 행렬을 반환합니다.

역행렬(Matrix Inverse)

행렬 A가 정사각 정칙 행렬(0이 아닌 행렬식)인 경우 방정식 AX = IXA = I는 동일한 해 X를 가집니다. 이 해를 A역행렬이라고 하며 A-1로 나타냅니다. inv 함수와 표현식 A^-1은 모두 역행렬을 계산합니다.

A = pascal(3)
A =
       1     1     1
       1     2     3
       1     3     6
X = inv(A)
X =

    3.0000   -3.0000    1.0000
   -3.0000    5.0000   -2.0000
    1.0000   -2.0000    1.0000
A*X
ans =

    1.0000         0         0
    0.0000    1.0000   -0.0000
   -0.0000    0.0000    1.0000

det에서 계산된 행렬식은 행렬로 설명되는 선형 변환의 스케일링 인자를 측정한 값입니다. 행렬식이 정확히 0이면 행렬은 특이 행렬이고 역행렬이 존재하지 않습니다.

d = det(A)
d =

     1

특이 행렬에 가까운 일부 행렬의 경우, 역행렬이 존재함에도 불구하고 계산 시 수치 오차가 발생하기 쉽습니다. cond 함수는 행렬의 역을 구한 결과에 대한 정확도를 나타내는 역행렬의 조건수를 계산합니다. 조건수의 범위는 1(수치적으로 안정적인 행렬의 경우)에서 Inf(특이 행렬의 경우)까지입니다.

c = cond(A)
c =

   61.9839

행렬의 명시적(Explicit) 역행렬을 구할 필요는 거의 없습니다. 그럼에도 불구하고 선형 연립방정식 Ax = b를 풀 때 inv를 잘못 사용하는 경우가 자주 발생합니다. 그러나 실행 시간과 수치적 정확도 측면에서 보면, 이 방정식을 푸는 가장 좋은 방법은 행렬 백슬래시 연산자 x = A\b를 사용하는 것입니다. 자세한 내용은 mldivide를 참조하십시오.

크로네커 텐서 곱(Kronecker Tensor Product)

두 행렬의 크로네커 곱(Kronecker Product) kron(X,Y)X의 요소와 Y의 요소 간에 발생 가능한 모든 곱으로 구성되는 보다 큰 행렬입니다. X가 mxn이고 Y가 pxq이면 kron(X,Y)는 mpxnq입니다. 이 요소들은 다음과 같이 X의 각 요소가 행렬 Y 전체와 곱해지도록 배열됩니다.

[X(1,1)*Y  X(1,2)*Y  . . .  X(1,n)*Y
                     . . .
 X(m,1)*Y  X(m,2)*Y  . . .  X(m,n)*Y]

크로네커 곱은 대개 작은 행렬의 반복되는 복사본을 만들어 가기 위해 0과 1로 구성된 행렬과 함께 사용됩니다. 예를 들어, X가 2x2 행렬이고

X = [1   2
     3   4]

2x2 단위 행렬 I = eye(2,2)가 있는 경우, 이 두 행렬의 크로네커 곱 결과는 각각 다음과 같습니다.

kron(X,I)
ans =

     1     0     2     0
     0     1     0     2
     3     0     4     0
     0     3     0     4

kron(I,X)
ans =

     1     2     0     0
     3     4     0     0
     0     0     1     2
     0     0     3     4

kron 외에, 배열을 복제하는 데 유용한 다른 함수들로는 repmat, repelem, blkdiag가 있습니다.

벡터 노름과 행렬 노름

벡터 x의 p-노름은

xp=(|xi|p)1p,

norm(x,p)로 계산됩니다. 이 연산은 p > 1인 모든 값에 대해 정의되지만 가장 일반적인 p 값은 1, 2, ∞입니다. 디폴트 값은 p = 2이며 이는 유클리드 길이 또는 벡터 크기에 해당합니다.

v = [2 0 -1];
[norm(v,1) norm(v) norm(v,inf)]
ans =

    3.0000    2.2361    2.0000

행렬 A의 p-노름은

Ap=maxxAxpxp,

p = 1, 2, ∞에 대해 norm(A,p)로 계산할 수 있습니다. 여기서도 디폴트 값은 p = 2입니다.

A = pascal(3);
[norm(A,1) norm(A) norm(A,inf)]
ans =

   10.0000    7.8730   10.0000

행렬의 각 행 또는 각 열의 노름을 계산하려는 경우 다음과 같이 vecnorm을 사용할 수 있습니다.

vecnorm(A)
ans =

    1.7321    3.7417    6.7823

선형 대수 함수에 멀티스레드 계산 사용하기

MATLAB에서는 다수의 선형 대수 함수와 요소별 숫자형 함수의 멀티스레드 계산을 지원합니다. 이 함수들은 여러 스레드에서 자동으로 실행됩니다. 여러 개의 CPU를 기반으로 보다 빠른 속도로 실행해야 하는 함수 또는 표현식의 경우 다음과 같은 다양한 조건을 충족해야 합니다.

  1. 함수가 동시에 실행 가능한 여러 부분으로 쉽게 분할할 수 있는 연산을 수행해야 합니다. 이 부분들은 프로세스 간에 거의 교신이 이루어지지 않는 상태로 실행될 수 있어야 하며, 순차적 연산이 거의 필요하지 않아야 합니다.

  2. 데이터를 나누고 개별 실행 스레드를 관리하는 데 소요되는 시간보다 동시 실행으로 얻게 되는 이점이 더 클 정도로 데이터 크기가 충분히 커야 합니다. 예를 들어, 대부분의 함수는 배열에 수천 개 이상의 요소가 포함되어 있는 경우에만 실행 속도가 빨라집니다.

  3. 연산이 메모리에 바인딩되지 않아야 합니다. 처리 시간에서 메모리 액세스 시간이 많은 비중을 차지해서는 안 되기 때문입니다. 일반적으로 단순한 함수보다 복잡한 함수의 경우에 더 높은 속도 향상이 이루어집니다.

행렬 곱셈 (X*Y) 연산자와 행렬 거듭제곱 (X^p) 연산자의 경우, 대규모 배정밀도 배열(약 1만 개 요소)에 대해 크게 향상된 속도를 보여줍니다. 행렬 분석 함수 det, rcond, hess, expm 역시 대규모 배정밀도 배열에 대해 현저히 향상된 속도를 보여줍니다.

관련 항목