간단히 역행렬 구하기(포트란에서 슬라텍이용), 또는 다른 라이
글쓴이: yuni / 작성시간: 금, 2005/04/08 - 4:47오후
소스가 오픈되어 있는 수치해석용 라이브리 중에서 슬라텍으로 간단히 테스트를 해본 것입니다. 그런데 답이 영 엉뚱하게 나옵니다. 아마도 제가 잘 못 알고 있는 것 같은데, 해결 방법이 없을까요?
program SGEDI_test implicit none real :: a(3,3) integer :: ipvt(3) integer :: i, j real, dimension(3) :: work real, dimension(2) :: det open(1, file='a', status='old') open(2, file='aa', status='old') open(3, file='b', status='old') open(4, file='bb', status='old') open(5, file='inva', status='unknown') do i =1,3 read(1,*) a(i,1:3) enddo write(*,*) 'Matrix a' do i=1,3 write(*,*) a(i,1:3) enddo call SGEDI(a, 3, 3, ipvt, det, work, 11) write(*,*) 'Invert Matrix a' do i=1,3 write(*,*) a(i,1:3) write(5,*) a(i,1:3) enddo write(*,*) det close(1); close(2); close(3); close(4); close(5) end program SGEDI_test
slatec에 있는 SGEDI의 설명문 입니다. 아래 부분의 소스는 생략을 했습니다.
지금 가장 이해가 안되는 부분은 N이라는 변수의 역할입니다. 그냥 보기에는 A행렬의 열을 넣으면 되는 것 같은데 그게 아닌 모양입니다.
subroutine SGEDI (A, LDA, N, IPVT, DET, WORK, JOB) ! !! SGEDI computes the determinant and inverse of a matrix using the ... ! factors computed by SGECO or SGEFA. ! !***LIBRARY SLATEC (LINPACK) !***CATEGORY D2A1, D3A1 !***TYPE SINGLE PRECISION (SGEDI-S, DGEDI-D, CGEDI-C) !***KEYWORDS DETERMINANT, INVERSE, LINEAR ALGEBRA, LINPACK, MATRIX !***AUTHOR Moler, C. B., (U. of New Mexico) !***DESCRIPTION ! ! SGEDI computes the determinant and inverse of a matrix ! using the factors computed by SGECO or SGEFA. ! ! On Entry ! ! A REAL(LDA, N) ! the output from SGECO or SGEFA. ! ! LDA INTEGER ! the leading dimension of the array A . ! ! N INTEGER ! the order of the matrix A . ! ! IPVT INTEGER(N) ! the pivot vector from SGECO or SGEFA. ! ! WORK REAL(N) ! work vector. Contents destroyed. ! ! JOB INTEGER ! = 11 both determinant and inverse. ! = 01 inverse only. ! = 10 determinant only. ! ! On Return ! ! A inverse of original matrix if requested. ! Otherwise unchanged. ! ! DET REAL(2) ! determinant of original matrix if requested. ! Otherwise not referenced. ! Determinant = DET(1) * 10.0**DET(2) ! with 1.0 <= ABS(DET(1)) < 10.0 ! or DET(1) == 0.0 . ! ! Error Condition ! ! A division by zero will occur if the input factor contains ! a zero on the diagonal and the inverse is requested. ! It will not occur if the subroutines are called correctly ! and if SGECO has set RCOND > 0.0 or SGEFA has set ! INFO == 0 . ! !***REFERENCES J. J. Dongarra, J. R. Bunch, C. B. Moler, and G. W. ! Stewart, LINPACK Users' Guide, SIAM, 1979. !***ROUTINES CALLED SAXPY, SSCAL, SSWAP !***REVISION HISTORY (YYMMDD) ! 780814 DATE WRITTEN ! 890831 Modified array declarations. (WRB) ! 890831 REVISION DATE from Version 3.2 ! 891214 Prologue converted to Version 4.0 format. (BAB) ! 900326 Removed duplicate information from DESCRIPTION section. ! (WRB) ! 920501 Reformatted the REFERENCES section. (WRB) !***END PROLOGUE SGEDI INTEGER LDA,N,IPVT(*),JOB REAL A(LDA,*),DET(2),WORK(*) ! REAL T REAL TEN INTEGER I,J,K,KB,KP1,L,NM1 !***FIRST EXECUTABLE STATEMENT SGEDI ! ! COMPUTE DETERMINANT
간단히 옥타브로 계산을 해 보면 얻고자 하는 답은 아래와 같습니다.
octave:1> load a octave:2> a a = 2 0 1 -2 3 4 -5 5 6 octave:3> inv (a) ans = -2.0000 5.0000 -3.0000 -8.0000 17.0000 -10.0000 5.0000 -10.0000 6.0000 octave:4> a* inv(a) ans = 1.00000 0.00000 0.00000 -0.00000 1.00000 -0.00000 -0.00000 0.00000 1.00000
어떻게 하면 될까요? 지금까지는 뉴메리컬레서피에 나오는 가우스 조던을 그냥 써 왔는데 저도 다른 방향으로 한번 가볼까 하는데 벌써 이틀동안 진도가 전혀 안나가네요. :oops:
혹시 뉴메릭 라이브러리를 이용하시는 분이 계시면 조언을 바랍니다.
Forums:
안 써봐서 잘은 모르지만[quote]! SGEDI comput
안 써봐서 잘은 모르지만
이걸 보면 SGECO나 SGEFA를 먼저 호출해서 factorization을 한 후에 SGEDI를
호출해야 하는 게 아닌가 싶습니다.
ps. 함수(서브루틴인가?) 이름이 꽤나 묘하네요.
Single precision - Gauss - Elimination - Determinant - Inverse 인가요? ^^;
c++를 조금 아시면 http://root.cern.ch 에 가셔서
c++를 조금 아시면
http://root.cern.ch 에 가셔서
ROOT 패키지를 한번 사용해 보세요.
c++ 로 코딩할 수 있으며, octave처럼 interactive 모드도 지원합니다
설치를 했다고 전제하고 my_matrix.cc를 다음처럼 코딩하고
다음처럼 컴파일하고
실행결과는 다음과 같습니다
너무나 쉽지 않나요 ? :D
좀더 가벼운 패키지를 원한다면 여기도 둘러보심이...http://ww
좀더 가벼운 패키지를 원한다면 여기도 둘러보심이...
http://wwwasd.web.cern.ch/wwwasd/lhc++/clhep/
이렇게 해보세요
학교 다닐때 수치해석하던 생각이 새록새록 떠오르네요.
그때 프로그램 짜면서 머리속을 아스트랄하게 만들던
이런 수치해석 방법들이 이미 컴퓨터가 만들어지기전
대부분 이론상으로 다 정립되어 있었다는데 또 한 번
놀라움과 과거 학자들에 대한 경외감을 가졌던적이... :)
A : 7.000 -3.000 -3.000
-1.000 0.000 1.000
-1.000 1.000 0.000
TIME = 1.5013800000929E-0004
답변을 주신분들께 감사 드립니다.
답변을 주신 doldori님, hokim님, aero님께 감사 드립니다. 실은 KLDP에 슬라텍 사용법을 알려 주십사 한번 글을 올린 그 몇달과 바로 지금까지 주말마다 이것 저것 해 본다고 늘 막히고 결정적으로 설명문에 대한 이해가 부족 했었습니다.
오늘 시간을 계산해 보니, 그동안 투자한 시간이 거의 한달이 되네요.^^;;;;;;;;;
정말 감사드립니다. 거의 뭔가 딱하고 머릿속에 번쩍한 느낌입니다. 방금까지 행렬의 연산은 아주 구식의 방법을 썼었는데, 여기 있는 SGEMM으로 쉽게 해결이 됩니다. 실은 이 문제도 슬라텍으로 해결할려고 하다가 계속 실패를 해서는 그냥 스스로 짜서 해결을 보았습니다.
갑자기 세상이 환해진 느낌입니다. 앞으로 Gauss-Seidel, singular value decompsiton 도 손을 대볼 계획입니다.
거듭 감사 드립니다. :D
==========================
부양가족은 많은데, 시절은 왜 이리 꿀꿀할까요?
=====================
"지금하는 일을 꼭 완수하자."
댓글 달기