2015년 6월 17일 수요일

싸이랩(scialb)의 행렬 연산

(A) 덧셈과 뺄셈

 두 행렬의 덧셈/뺄셈은 크기(행수와 열수)가 같아야 수행되며 다르면 에러가 발생한다. 한 가지 주의할 것은 <스칼라±행렬> 의 연산인데 수학적으로는 정의되지 않지만 Scilab 에서는  (Matlab 와 마찬가지로) 스칼라를 모든 요소와 각각 더하는 연산을 한다는 것이다.
>> A=[1 2;3 4]; B=[5*%i %pi;%e %e^2]; C=[1 2 3]; d=-2;
>> A+B
ans  =
   1. + 5.i     5.1415927  
   5.7182818    11.389056  
>> B-C
    !--error 9
 Inconsistent subtraction.
>> C+d
ans  =
 - 1.    0.    1.
위 의 예에서 보듯이 행렬 A와 B는 크기가 둘 다 2x2로 같으므로 덧셈/뺄셈이 가능하지만 B와 C는 크기가 다르다. 따라서 B와 C의 덧셈/뺄셈은 허용되지 않는다. 다만 d는 스칼라이므로 이것과 행렬과의 연산은 가능하며 모든 요소에 이 스칼라를 더하거나 빼는 연산을 수행한다.

(B) 곱셈

 행렬의 곱셈에 사용되는  연산자들은 다음 표와 같다.
[표 1]  행렬의 곱셈
A*B
일반적인 곱셈. A의 행과 B의 열의 개수는 같아야 함.
A.*B
요소간 곱셈. A와 B는 같은 크기여야 함.
A.*.B
Kronecker 곱셈.
A^n, A**n
A행렬의 n승. 즉, A*A*A*...*A. A는 정방행렬이어야 함.
A.^B
요소간 거듭제곱. A와 B는 같은 크기여야 함.
단순한 A*B 연산은 행렬의 곱셈으로서 피연산자의 한 쪽이 스칼라 이거나 아니면 A의 행 수와 B의 열의 개수는 같아야 계산이 성립한다.
>> A=[1,2+3*%i;%pi %e^2]
A  =
   1.           2. + 3.i  
   3.1415927    7.3890561

>> %i*A
ans  =
    i           - 3. + 2.i    
  3.1415927i    7.3890561i  

>> A*[1 2 3;4 5 6]
ans  =
   9. + 12.i    12. + 15.i    15. + 18.i  
   32.697817    43.228466     53.759115

>> [1 2 3]*A
         !--error 10
Inconsistent multiplication.
위의 예들에서 마지막 것은 행렬의 차수가 맞지 않아서 에러가 발생하는 것이다.

 이에 반해서 A.*B 연산은 행렬의 같은 위치에 있는 요소끼리 곱하는 연산으로서 A행렬과 B행렬의 크기가 같아야 한다.

>> P=[1 2 ; 3 4]
P  =
    1.    2.  
    3.    4.  

>> Q= [%i %pi; %e %T]
Q  =
    i            3.1415927  
    2.7182818    1.        

>> P.*Q
ans  =
    i            6.2831853  
    8.1548455    4.        
이 연산의 결과도 같은 크기의 행렬이다. 만약 크기가 서로 다른 행렬에 대해서 이 연산을 수행하려고 한다면 에러를 발생할 것이다.

>> [1 2].*[3;4]
         !--error 9999
inconsistent element-wise operation
 
그리고 A.*.B 연산은 Kronecker 곱셈으로서 수학기호로는 ⊗로 표시 한다. 즉 A⊗B는 다음과 같은 연산을 수행한다.


따라서 행렬 A와 B에 대한 크기 제약 조건은 없으며 예를 들면 다음과 같다.

>> [1 2].*.[10 20;30 40]
ans  =
   10.    20.    20.    40.  
   30.    40.    60.    80.
 
 행렬의 거듭제곱에는 ^, **, .^ 연산자가 있다. A^n, 또는 A**n 은 행렬의 거듭제곱 연산자로서 예를 들어서 A^3 또는 A**3은 A*A*A 와 결과가 같다. 따라서 이 연산이 수행되려면 A행렬은 반드시 정방행렬이어야 한다. 이에 반해서 A.^n 은 행렬의 각각의 요소를 n승 하는 것이다. 따라서 A행렬의 크기에 대한 제한 조건은 없다.
>> A=[2,3;4,5];
>> A^3
ans  =
    116.    153.  
    204.    269.  
>>A.^3
ans  =
    8.     27.  
   64.    125.  
행렬의 거듭 제곱과 요소간 거듭 제곱은 반드시 구분해야 한다. 한 가지 특이한 (혼동하기 쉬운)점은 만약 A가 벡터라면 A^n 이나 A.^n 이나 결과가 같다는 것이다. (개인적인 생각으로는 A가 벡터일 때 A^n 연산은 에러를 뱉는 것이 더 일관성이 있는 것 아닌가 하는 아쉬움은 있는데 어쨌든 Scilab은 그렇게 동작한다.(

(C) 나눗셈

 행렬의 나눗셈에 대해서 다음 표에 정리하였다. 나눗셈은 보통의 나눗셈과 좌나눗셈으로 나뉜다는 점이 특이하다.
[표 2]  행렬의 나눗셈
A/B
행렬의 나눗셈. A*inv(B)와 같다.
한 쪽이 스칼라이거나 크기가 같아야 한다.
A./B
요소간 나눗셈. A와 B는 같은 크기여야 한다..
A\B
행렬의 좌나눗셈 inv(A)*B와 같다.
한 쪽이 스칼라이거나 크기가 같아야 한다.
A.\B
요소간 좌나눗셈. A와 B는 같은 크기여야 한다.
이 경우에도 요소간 연산자가 따로 정의되어 있으며 dot(.)으로 시작한다. 또한 행렬의 나눗셈의 경우는 역행렬과 관계되어 있으며 A/B는 A*inv(B)와, A\B는 inv(A)*B와 동일한 연산을 수행한다. inv()함수는 정방행렬의 역행렬을 구하는 함수이다.

(D) 기타 연산자

  행렬의 복소전치행렬은 작은 따옴표(‘)를 행렬의 끝에 붙여주면 구할 수 있고 단순 전치 행렬은 점 작은 따옴표 (.’)를 붙이면 된다. 복소전치행렬은 행과 열의 위치를 바꾸고 켤레복소수로 변환된 행렬을 의미하며 단순 전치 행렬은 그냥 위치만 바꾼 행렬은 의미한다.
>> A=[1, 2*%i; 3+4*%i, 5]
 A  =
    1.          2.i  
    3. + 4.i    5.  

>> B=A'
B  =
    1.     3. - 4.i  
 - 2.i    5.        

>> C=A.'
C  =
   1.     3. + 4.i  
   2.i    5.      

 

이 결과를 잘 살펴보면 B행렬은 A행렬의 복소 전치 행렬이고 C행렬은 단순 전치 행렬이라는 것을 알 수 있다.

 정방행렬의 역행렬을 구하는 함수는 inv()이고 행렬식(determinant)을 구하는 함수는 det()이다. 직전의 A행렬에 대해서 역행렬과 행렬식을 구하는 예는 다음과 같다.

>> inv(A)
 ans  =
    0.3170732 + 0.1463415i    0.0585366 - 0.1268293i  
   - 0.0731707 - 0.3414634i    0.0634146 + 0.0292683i  

>> det(A)
   ans  =
      13. - 6.i  


댓글 없음:

댓글 쓰기