간단히 역행렬 구하기(포트란에서 슬라텍이용), 또는 다른 라이

yuni의 이미지

소스가 오픈되어 있는 수치해석용 라이브리 중에서 슬라텍으로 간단히 테스트를 해본 것입니다. 그런데 답이 영 엉뚱하게 나옵니다. 아마도 제가 잘 못 알고 있는 것 같은데, 해결 방법이 없을까요?

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: 
doldori의 이미지

안 써봐서 잘은 모르지만

Quote:
! SGEDI computes the determinant and inverse of a matrix
! using the factors computed by SGECO or SGEFA.

이걸 보면 SGECO나 SGEFA를 먼저 호출해서 factorization을 한 후에 SGEDI를
호출해야 하는 게 아닌가 싶습니다.

ps. 함수(서브루틴인가?) 이름이 꽤나 묘하네요.
Single precision - Gauss - Elimination - Determinant - Inverse 인가요? ^^;

hokim의 이미지

c++를 조금 아시면
http://root.cern.ch 에 가셔서
ROOT 패키지를 한번 사용해 보세요.
c++ 로 코딩할 수 있으며, octave처럼 interactive 모드도 지원합니다

설치를 했다고 전제하고 my_matrix.cc를 다음처럼 코딩하고

#include "Riostream.h"
#include "TMatrix.h"

int main()
{
        float x[] = {2, 0, 1, -2, 3, 4, -5, 5, 6};
        TMatrix a(3,3,x);
        cout << "a"  << endl;
        a.Print();
        TMatrix inv_a(a);
        inv_a.Invert();
        cout << "inv(a)" << endl;
        inv_a.Print();

        TMatrix mul = a*inv_a;
        cout << "a * inv(a)" << endl;
        mul.Print();
}

다음처럼 컴파일하고

Quote:

[hokim@koren161 ~/test]$ g++ -o my_matrix `root-config --cflags` `root-config --libs` my_matrix.cc

실행결과는 다음과 같습니다

Quote:

[hokim@koren161 ~/test]$ ./my_matrix
a

3x3 matrix is as follows

| 0 | 1 | 2 |
------------------------------------------------------------------
0 | 2 0 1
1 | -2 3 4
2 | -5 5 6

inv(a)

3x3 matrix is as follows

| 0 | 1 | 2 |
------------------------------------------------------------------
0 | -2 5 -3
1 | -8 17 -10
2 | 5 -10 6

a * inv(a)

3x3 matrix is as follows

| 0 | 1 | 2 |
------------------------------------------------------------------
0 | 1 0 0
1 | 0 1 0
2 | 0 0 1

너무나 쉽지 않나요 ? :D

hokim의 이미지

좀더 가벼운 패키지를 원한다면 여기도 둘러보심이...
http://wwwasd.web.cern.ch/wwwasd/lhc++/clhep/

aero의 이미지

학교 다닐때 수치해석하던 생각이 새록새록 떠오르네요.
그때 프로그램 짜면서 머리속을 아스트랄하게 만들던

이런 수치해석 방법들이 이미 컴퓨터가 만들어지기전
대부분 이론상으로 다 정립되어 있었다는데 또 한 번
놀라움과 과거 학자들에 대한 경외감을 가졌던적이... :)

C        EXAMPLE : MATRIX INVERSE
C        METHOD  : GAUSSIAN ELIMINATION & PIVOTING
C        USED SUB: SGECO, SGEDI
C  INPUT MATRIX
C        A:     ( 1.0 3.0 3.0 )
C               ( 1.0 3.0 4.0 )
C               ( 1.0 4.0 3.0 )

      PARAMETER  ( N=3)
      REAL       A(N, N), Z(N), DET(2), WORK(N)
      INTEGER    IPVT(N)
      DATA       A/1.0, 1.0, 1.0, 3.0, 3.0, 4.0, 3.0, 4.0, 3.0/
    
      T0=SECOND()
      CALL SGEFA (A, N, N, IPVT, INFO )
      IF(INFO.NE.0)GO TO 99
      CALL SGEDI (A, N, N, IPVT, DET, WORK, 1)
      T1=SECOND()
      TIME= T1- T0

      WRITE(6,11)((A(I,J),J=1,N),I=1,N)
11    FORMAT(' A : ', 3F8.3,/, 5X, 3F8.3,/, 5X, 3F8.3, /)
      WRITE(6,*)' TIME = ', TIME
      STOP
99    WRITE(6,22)
22    FORMAT(40H PROBABLY MATRIX IS SINGULAR CALL SGBCO )
      STOP
      END

A : 7.000 -3.000 -3.000
-1.000 0.000 1.000
-1.000 1.000 0.000

TIME = 1.5013800000929E-0004

yuni의 이미지

답변을 주신 doldori님, hokim님, aero님께 감사 드립니다. 실은 KLDP에 슬라텍 사용법을 알려 주십사 한번 글을 올린 그 몇달과 바로 지금까지 주말마다 이것 저것 해 본다고 늘 막히고 결정적으로 설명문에 대한 이해가 부족 했었습니다.

오늘 시간을 계산해 보니, 그동안 투자한 시간이 거의 한달이 되네요.^^;;;;;;;;;

정말 감사드립니다. 거의 뭔가 딱하고 머릿속에 번쩍한 느낌입니다. 방금까지 행렬의 연산은 아주 구식의 방법을 썼었는데, 여기 있는 SGEMM으로 쉽게 해결이 됩니다. 실은 이 문제도 슬라텍으로 해결할려고 하다가 계속 실패를 해서는 그냥 스스로 짜서 해결을 보았습니다.

갑자기 세상이 환해진 느낌입니다. 앞으로 Gauss-Seidel, singular value decompsiton 도 손을 대볼 계획입니다.

거듭 감사 드립니다. :D

==========================
부양가족은 많은데, 시절은 왜 이리 꿀꿀할까요?
=====================
"지금하는 일을 꼭 완수하자."

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.