수치처리 파이썬 설치하기 수치처리 파이썬을 사용하려면 먼저 이 프로그램을 설치해야 한다. 지시사항 및 다운로드 위치를 알려주는 자세한 사항은 여기를 클릭할 것! |
a와 b는 모두 같은 요소들을 담고 있지만 그 꼴이 서로 다르다. 행렬의 꼴은 행과 열의 개수에 의해서 기술된다. a 행렬은 열 벡터(column vector) 또는 3ⅹ1 행렬로 기술될 수 있다. b 행렬은 행 벡터(row-vector) 또는 1ⅹ3 행렬로 기술될 수 있다. C 행렬은 3ⅹ3 행렬의 예이다.
그러나 다음은 유효하지 않다.
행렬 곱셈
이 공식은 행렬 a의 행과 행렬 b의 열을 곱해서 행렬 c를 어떻게 생성할 수 있는지를 보여준다. 새로 만들어지는 행렬 c(i,j)의 안에 있는 지표들의 용도는 c행렬에서 i 번째 행과 j 번째 열에 위치한 요소를 지정하는 것이다. (같은 개념이 행렬 a와 행렬 b에도 적용된다.) 그리스 문자 시스마(Sigma)는 합계를 뜻한다. 시그마를 k=1 에서부터 n까지 진행되는 일종의 루프로 생각해라. 이 때 n은 내항의 크기이다. 그 루프를 한 번씩 돌 때마다 나오는 결과 값을 모두 더해라.
나눗셈은 어떤가?
한 행렬과 그 역행렬을 함께 곱할 경우 그 결과는 I 또는 항등 행렬로 나타낼 수 있다. 항등 행렬(identity matrix)이란 (좌상에서부터 우하까지 이어지는) 주 대각선상에 있는 요소들을 제외하고 모든 요소들이 0인 정방 행렬이다. 3ⅹ3 항등 행렬의 예는 다음과 같다.
전통적인 나눗셈과 역행렬이 약간 다르기는 하지만 그 개념은 다음과 같은 수량(scalar) 수학을 직접적으로 따른다:
여러 가지 제한사항이 있다. 역행렬은 (행과 열의 개수가 같은) 정방 행렬에 대해서만 정의되면 이 외의에 대해서는 존재하지 않을 수도 있다. 이런 제한사항은 0으로는 어떤 수도 나눌 수 없다는 개념과 비슷하다고 볼 수 있다. 따라서 모든 행렬이 역행렬을 갖는 것은 아니라고 할 수 있다. 만약 역행렬이 존재한다면 이 튜토리얼에서 나중에 살펴보겠지만 어려운 방정식을 푸는데 대단히 유용하게 사용된다.
>>> from Numeric import *.일단 NumPy 모듈이 임포트되면 array() 함수로 배열을 만들 수 있다. array() 함수는 인수를 두 개 취한다. 값으로 터플이나 혹은 리스트를 취하고 형으로 Float 또는 Int와 같은 형 코드를 선택적으로 취한다. 리스트는 내포되어 다차원 배열을 만들 수 있다. array() 함수는 지정된 형과 값들을 가진 배열을 하나 생성할 것이다. 형이 지정되지 않으면 그 배열의 형은 그 원소들의 형에 따를 것이다.
>>> a=array((1,2)) >>> print a [1 2]터플 안에 담긴 값들이 정수이기 때문에 정수 배열을 만든다.
>>> b=array((1,2),Float) >>> print b [ 1. 2.]정수 인수들을 사용하여 부동소수점 배열 하나를 만든다. 부동 소수점 형은 정수 인수들을 덮어 쓴다.
>>> c=array(((1,2),(3,4))) >>> print c [[1 2] [3 4]]다차원 터플을 사용하여 다차원 배열을 만든다.
>>> a=array((1,2)) >>> a.shape (2,) >>> c=array(((1,2),(3,4))) >>> c.shape (2, 2)a는 오직 한 개의 차원만 가지며 (꼴지정 터플(shape tuple)은 값을 오직 한 개만 가짐) 그리고 c는 다차원이라는 것을 주목하라 (꼴지정 터플에 값이 두개이다). 기본으로, 1차원 배열은 오직 길이만을 가진다. 행과 열이라는 개념은 1차원 배열의 구조에는 구현되지 않는다. 그렇지만 배열의 꼴은 reshape() 함수를 통해 변경될 수 있다. reshape 함수는 배열과 꼴 지정 터플(shape tuple)과 같이 두 개의 인수를 취한다.
>>> a=array((1,2)) >>> a.shape (2,) >>> print a [1 2] >>> ma=reshape(a,(1,2)) >>> ma.shape (1, 2) >>> print ma [ [1 2]] >>> mb=reshape(a,(2,1)) >>> mb.shape (2, 1) >>> print mb [[1] [2]]꼴 바꾸기(reshape)를 사용하여 1차원 배열에 보다 전통적인 행렬같은 꼴을 부여하면 인쇄결과(printout)는 변경된다. 1ⅹ2 행렬 ma에서 여분의 공간은 그 행렬의 다차원적인 본성을 보여준다. a의 출력과 ma의 출력을 대조해 보자. 원래 형태와 바뀐 형태사이의 차이점이 보이는가? 원소들은 똑같지만 그 꼴은 다르다.
>>> c=array(((1,2),(3,4))) >>> c.shape (2, 2) >>> print c [[1 2] [3 4]] >>> d=reshape(c,(1,4)) >>> d.shape (1, 4) >>> print d [ [1 2 3 4]]행렬 곱셈
>>> ma array([ [1, 2]]) >>> mb array([[1], [2]]) >>> ma*mb array([[1, 2], [2, 4]]) >>> mb*ma array([[1, 2], [2, 4]]) >>> matrixmultiply(ma,mb) array([ [5]]) >>> matrixmultiply(mb,ma) array([[1, 2], [2, 4]])곱셈 연산은 "의사 지표(† 역자 주: 의사 지표(Pseudo Indices)는 주로 파이썬 표현식을 평가하는 동안에 배열이 중심축을 추가함으로써 모습을 바꾸는 능력을 말함)"라는 동작에 의해서 통제된다. 의사 지표는 진짜 유용하다. 이 의사 지표의 개념은 다음 기사에서 설명하겠다. 지금 당장은 matrixmultiply() 함수만으로 예상된 결과들을 달성하자.
>>> From LinearAlgebra import *다음에 보는 간단한 예제에서 이 함수의 사용법을 살펴보자.
>>> a=array(((3,2),(2,4)),Float) >>> print a [[ 3. 2.] [ 2. 4.]] >>> a_inv = inverse(a) >>> print a_inv [[ 0.5 -0.25 ] [-0.25 0.375]]결과를 점검하려면 a_inv에 a를 곱하라(이렇게 하면 항등 행렬이 나올 것임).
>>> matrixmultiply(a_inv,a) array([[ 1.00000000e+000, 1.11022302e-016], [ 0.00000000e+000, 1.00000000e+000]])게임 끝
이 고전적인 문제는 평면에서 두 라인이 서로 교차하는 곳을 찾는 문제이다. 두 라인은 여러 가지 다른 현상들을 표현하기도 하는데, 경제학에서 "수익 Vs 비용"과 같은 현상을 표현하거나 또는 생물학에서 "성장 대 쇠퇴"와 같은 현상을 표현하기도 한다. 어느 경우라도 교차점을 찾아 내는 것은 지겨운 일이고 약간의 변수를 더 추가할 경우 계산은 엄청나게 어려워질 것이다.
이것은 다음과 같이 2ⅹ2 행렬과 1ⅹ2 행렬(미지수들)의 곱이 2ⅹ1 행렬과 같다고 다시 쓸 수 있다.
행렬 수학에는 전통적인 대수학에 있는 것보다 약간 더 많은 규칙이 있다. 그 중에 하나를 아래에 있는 방정식에서 볼 수 있다. 미지수에 대하여 해를 찾으려면 z만 왼쪽에 놓아둘 필요가 있다. 대수학적으로 생각하면 제일 먼저 떠오르는 직감은 A로 나누는 것이 될 것이다. 그러나 행렬 나눗셈은 정의되어 있지 않다! 다행스럽게도 우리는 역행렬을 사용할 수 있다. (마치 양편 모두에 1/A를 곱하는 기분으로) 양쪽 모두에 역행렬을 곱해라.
왼쪽에 나온 그 결과는 항등행렬과 z가 곱해져 있다(이 값은 그냥 z이다). 역행렬은 행렬 A와 약분된다. 오른쪽에는 A-1b의 곱이 남았다. 오른쪽에 있는 모든 값들은 아는 값이고 왼쪽에는 모르는 값만 남았으므로, 해답은 바로 눈 앞에 있다! 이러한 방정식들은 그저 역(inverse)과 곱(multiply)만으로도 해결된다.
>>> A=array(((3,4),(5,2))) >>> b=reshape(array((11,9)),(2,1))array()와 reshape() 함수를 조합하여 b를 어떻게 눈깜짝할 사이에 만들어 내는지 주목하라.
>>> Ainv = inverse(A) >>> z=matrixmultiply(Ainv,b) >>> z array([[ 1.], [ 2.]])이것이 바로 그 해답이다. 결과를 원래 행렬 A와 점검해보자.
>>> matrixmultiply(A,z) array([[ 11.], [ 9.]])이것은 정답을 보여준다! 잘만 한다면 복잡하게 머리로 문제를 풀기보다는 Numpy로 연습해보는 것이 덜 고통스럽다. 이런 간단한 문제로는 Python/NumPy의 힘을 약간만 볼 수 있을 뿐이다. 진정한 힘은 더 큰 문제들을 해결하는 데서 볼 수 있다. 만약 미지수와 방정식의 개수가 10개 정도나 된다면 그 문제를 Nmpy의 도움 없이 그냥 머리로만 푸는 것은 정말 어려울 것이다.
앞으로 다룰 것들
더 읽어야 할 것
이전 글 : 스택리스 파이썬 다시 태어나다!
다음 글 : SQLJ를 배우자! - DDL 문과 트랜잭션
최신 콘텐츠