본문

자바 JAMA 라이브러리로 행렬 계산하기

보안통신을 구현하는데 이번에는 행렬을 사용하여 계산하기 때문에 행렬 관련 자바 라이브러리가 필요했다. 여러 라이브러리를 구글링을 통해 찾을 수 손쉽게 찾을 수 있었으나 이중에서 pseudoinverse matrix(의사역행렬)를 지원하는것이 필요했으며, 그중 가볍다는 JAMA를 찾아 사용하기로 하였다. NIST의 협력으로 만들어졌으며 public domain에 있어서 마음껏 사용할 수 있다. 그런데 문서/예제도 별로 없고 코드가 전반적으로 구식같아, 이를 분석하고 커스터마이징 해야 했다. 특히 정수로 된 행렬이 필요했기 떄문에 random함수를 약간 변경했다. print()에서의 숫자는 별로 상관이 없고 적당히 크기만 하면 된다(digit). 그냥 이런게 있다는 것을 기억하기 위해 글을 적어본다.

[5x2]행렬과 그의 의사역행렬[2x5]연산의 결과로 나온 세번째의 [2x2] 단위행렬을 보자면 [2x5](matinv)*[5x2](mat) 으로서 연산이 된것을 알 수 있다. 하지만 이와 달리 [5x2](mat)*[2x5](matinv)를 하게된다면 [5x5] 행렬이 나오고 이는 단위행렬과는 전혀 상관이 없게 된다. (기존에 있던 정방행렬의 역행렬에서 성립하는 AA'=A'A=I과는 다르다). 아래에 One-sided inverse(left inverse or right inverse)에 대해 위키피디아(Generalized inverse)에 있던 설명을 캡쳐해놓았다.



참고로 A*B를 연산하고 싶다면 A.times(B)처럼 순서대로 적어주면 된다, 따라서 아래에서는 A'*A=I이므로 연산은 matInv.times(mat)으로 이루어 진것이다. 아무튼 이 라이브러리를 사용하여 프로젝트를 진행할 수 있었다.


import java.util.Random; import Jama.Matrix; public class HelloJama { public static void main(String[] args) { Matrix mat = random(5,2); mat.print(5, 5); Matrix matInv=mat.inverse(); matInv.print(5, 5); matInv.times(mat).print(5, 5); } public static Matrix random(int i, int j) { Matrix matrix = new Matrix(i, j); double ad[][] = matrix.getArray(); Random rn = new Random(); for(int k = 0; k < i; k++) { for(int l = 0; l < j; l++) ad[k][l] = rn.nextInt()%100; } return matrix; } }

========================================== 

57.00000 -17.00000

57.00000 -65.00000

-38.00000 91.00000

84.00000 -34.00000

64.00000 88.00000


0.00297 0.00230 -0.00087 0.00425 0.00482

-0.00005 -0.00243 0.00398 -0.00052 0.00525


1.00000 0.00000

0.00000 1.00000

댓글

Holic Spirit :: Tistory Edition

design by tokiidesu. powerd by kakao.