1. Armadillo와 Wrapper
많은 사람들이 MATLAB과 같은 프로그램을 프로그래밍 언어로 사용하고 있다. (사실 언어가 아니라고는 하지만) 이는 언어가 가지는 장점이라기 보다 특히 행렬 연산 등에서 굉장히 편리하기 때문일 것이다.
예컨에 엑셀에서 행렬 A*B 를 계산하고자 한다면 아래와 같은 함수를 사용해야 한다.
=MMULT(A1:B2,D1:E2)
만약 여러번 행렬 연산을 한다거나 전치를 사용하는 등 행렬식이 조금이라도 길어지면 가독성이 몹시 안 좋게 된다.
=MMULT(MMULT(TRANSPOSE(A1:B2),A1:B2),MINVERSE(D1:E2))
반면 MATLAB과 같이 행렬 연산에 특화 되어 있는 툴을 활용 하면 간단히 다음과 같이 쓸 수 있다.
A=[1,0,0,1];
B=[1,2,3,4];
A*B
하지만 MATLAB은 몹시 비싸서 개인이 사기에는 부담스럽기도 하고, 학생들의 경우 해적판을 쓰는 경우가 많다. 특히나 회사에서 구매할 경우 더욱 비싸기 때문에 보통 EXCEL 하나만 덜렁 주고 끝낸느 경우가 많다. 물론 VBA를 이용하면 확장성은 크지만 여전히 MATLAB과 같은 툴의 편의를 따라가지 못한다.
C언어와 같은 프로그래밍 언어를 사용할 때에도 불편함은 따른다. C언어로 행렬 연산을 하기 위해서는 행렬 연산에 해당하는 함수를 직접 만들어 쓰거나 남이 만든 라이브러리를 끌어다 써야 하고 역시 함수를 call할 때마다 위의 엑셀 수식처럼 가독성이 떨어지는 지저분함은 사라지지 않는다.
이러한 문제들을 해결하기 위해 뛰어나면서 이타적이신 분들이 wrapper라는 것들을 만들어서 배포하고 있다. 그중 대표적인 것이 Armadillo라는 것으로 LAPACK이나 BLAS, ATLAS와 같은 선형대수 솔버를 사용하기 쉽도록 말 그대로 포장을 해 놓은 것이다. 이 Armadillo라는 것은 완전히 무료이며, 이것을 사용할 경우 C언어를 통해 다음과 같이 행렬을 계산할 수 있다.
mat A, B;
A << 1 << 0 << endr
<< 0 << 1 << endr;
B << 1 << 2 << endr
<< 3 << 4 << endr;
cout << A*B << endl;
여기서 "mat A, B;"이라는 변수형 선언을 하게 되는데 익숙히 알고 있는 int나 float과 같은 것이다. 즉 행렬을 하나의 변수형으로 선언할 수 있다. 또 A와 B를 배열(array)로 지정할 때처럼 크기를 따로 설정할 필요가 없다. 물론 각 요소들을 읽고 쓰기 위해서는 크기를 지정해주거나 초기화 후 써야 한다.
주목할 점수 endr인데 armadillo library에서 제공하는 것으로 행렬에서 한 행이 끝났음을 알려주는 것이다. 그리고 출력문에서 A*B로 마치 MATLAB처럼 간단히 연산할 수 있는 것을 알 수 있다.
또 Ax=b 처럼 system equation 문제를 풀 때에도 solve()라는 함수를 제공해 따로 가우스 소거법이나 LU 분해 코드를 짜지 않고도 문제를 풀 수가 있다.
근래에는 Microsoft에서 호의적으로 Visual Studio Express 버전을 배포하여 개인이나 회사나 상관없이 무료로 사용할 수 있다. (지금 Express는 Community로 바뀌었고 완전히 무료도 아니다. 하지만 쓸 수는 있다.) 따라서 우리는 완전히 무료로 꽤 쓸만한 행렬처리가 가능한 언어를 가진 셈이다.
유한요소해석과 같이 행렬 연산이 꼭 필요한 경우에는 이러한 선형대수 솔버를 갖는 것이 필요하다. 만약 이런 wrapper가 없다면, 우리는 문제를 풀어보기도 전에 행렬 조차 풀지 못해 책을 덮어버리게 될 것이다.
Armadillo는 아래 주소에서 받을 수 있다.
Armadillo: C++ library for linear algebra & scientific computing
arma.sourceforge.net
2. Armadillo 설치 방법
우선 windows 환경에서 사용하기 위해서는 MS Visual studio express 2013을 설치해야 한다. 아래 주소에서 받고 설치하면 된다.
http://www.microsoft.com/ko-kr/download/details.aspx?id=40787
다음으로 Armadillo library를 받는다.
http://arma.sourceforge.net/download.html
Armadillo: C++ library for linear algebra & scientific computing
arma.sourceforge.net
Armadillo library의 압축을 해제하고 아래 주소에서 해당 파일을 에디터로 연다.
include\armadillo_bits\arma_config.hpp
맨 위에 다음과 같이 Armadillo에서 LAPACK과 BLAS를 사용할 수 있도록 전처리기를 붙여 준다. 크기가 작은 행렬은 Armadillo가 내장한 코드로 풀어버리지만 크기가 큰 행렬은 Armadillo가 풀지 않는다. 이 경우에는 library가 LAPACK과 BLAS를 호출하여 행렬을 풀기 때문에 아래 전처리기를 붙여주어야 한다.
#define ARMA_USE_LAPACK
#define ARMA_USE_BLAS
만약 위 전처리기를 붙이지 않고 크기가 큰 행렬 문제를 푼다면 아래와 같은 경고문을 볼 수 있다. (여기서 크기가 큰 행렬은 아주 크지도 않다. 5x5 행렬 조차도 안 푼다. 5x5 행렬을 만들어서 역행렬을 구해보자)
error: inv(): use of ATLAS or LAPACK needs to be enabled
전처리기를 붙였으면 arma_config.hpp 를 저장하고 include 폴더 내용을 통째로 복사하여 아래 주소에 복사한다.
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include
이제 다시 원래 압축을 풀었던 곳으로 돌아가 examples 폴더에 들어간다. example1_win64.sln 파일을 더블클릭하여 비주얼 스투디오를 열고 컴파일 해본다. 소스코드의 내용대로 행렬연산을 수행하고 결과를 보여줄 것이다.
하지만 여러분이 새로 프로젝트를 만들고 코드를 짜서 컴파일을 하면 실행이 안될 수 있다. 이것은 LAPACK과 BLAS library를 찾지 못하기 때문이다. Visual studio에서 메뉴에서 아래 순서로 따라 들어간다.
프로젝트 -> 프로젝트명 속성 -> 구성 속성 -> 링커 -> 입력
아래와 같이 추가 종속성에서 콤보박스를 내리고 "편집"을 눌러 LAPACK와 BLAS 라이브러리 주소를 입력한다. LAPACK과 BLAS 라이브러리는 Armadillo 압축을 푼 폴더에 lib_win64 폴더에 들어 있다. 이것보다 더 성능이 좋다고 알려진 GotoBLAS 같은 것들을 직접 받아서 컴파일 한 후 써도 좋다.


이제 다시 컴파일을 한후 lapack_win64_MT.dll과 blas_win64_MT.dll 파일을 컴파일 결과가 생성되는 debug나 release 폴더에 복사해 넣으면 실행이 될 것이다.
최근댓글