Fortran 95 및 LAPACK을 사용한 실제 비대칭 행렬의 행렬 지수


10

최근 에 skew-Hermitian 행렬에 대해 같은 줄을 따라 질문했습니다 . 그 질문의 성공에 영감을 받아 벽에 머리를 두 시간 동안 두드린 후 실제 비대칭 행렬의 행렬 지수를보고 있습니다. 고유 값과 고유 벡터를 찾는 경로는 다소 복잡해 보이므로 잃어버린 것 같습니다.

배경 : 얼마 전에 나는 이론 물리 물리학 SE에 대해이 질문 을했습니다. 결과적으로 마스터 방정식을 실제 비대칭 행렬로 표현할 수 있습니다. 시간에 독립적 인 경우,이 방정식을 지수화하여 마스터 방정식을 풉니 다. 시간 종속적 인 경우 통합이 필요합니다. 나는 현재 시간 독립에 대해서만 걱정하고 있습니다.

다양한 서브 루틴을보고하면 내가 전화해야한다고 생각 ( ? gehrd , ? orghr , ? hseqr ...) 그것에서 행렬을 캐스팅 간단 할 것인지가 불분명 real*8complex*16이러한 루틴의 복잡한 이중 버전 및 진행, 또는 real*8내 배열의 수를 두 배로 늘리고 나중에 복잡한 행렬을 만드는 것을 명심하십시오.

그렇다면 어떤 루틴을 어떤 순서로 호출해야합니까? 그리고 실제 이중 버전 또는 복잡한 이중 버전을 사용해야합니까? 아래는 실제 이중 버전 으로이 작업을 수행하려는 시도입니다. 의 고유 값과 고유 벡터를 찾는 데 어려움을 겪었습니다 L*t.

function time_indep_master(s,L,t)
  ! s is the length of a side of L, which is square.
  ! L is a real*8, asymmetric square matrix.
  ! t is a real*8 value corresponding to time.
  ! This function (will) compute expm(L*t).

  integer, intent(in)    :: s
  real*8,  intent(in)    :: L(s,s), t
  real*8                 :: tau(s-1), work(s), wr(s), wi(s), vl
  real*8, dimension(s,s) :: time_indep_master, A, H, vr
  integer                :: info, m, ifaill(2*s), ifailr(2*s)
  logical                :: sel(s)

  A = L*t
  sel = .true.

  call dgehrd(s,1,s,A,s,tau,work,s,info)
  H = A
  call dorghr(s,1,s,A,s,tau,work,s,info)
  call dhseqr('e','v',s,1,s,H,s,wr,wi,A,s,work,s,info)
  call dhsein('r','q','n',sel,H,s,wr,wi,vl,1,vr,s,2*s,m,work,ifaill,ifailr,info)

  ! Confused now...

end function

답변:


8

먼저 행렬이 완전히 임의적인지 아닌지에 대해 정말로 열심히 생각합니다. Hermitian으로 만드는 변환이 있습니까? 물리학에서 행렬이 대각선 화 가능해야한다고 보장합니까 (합리적으로 조절 된 고유 벡터 행렬 사용)?

실제로 악용 할 대칭이없는 것으로 밝혀지면 , 표준 참조 인 MA9 (Matrix ABon 의 저자 및 G & vL의 공동 저자에 의해 작성된 Matrix Exponential을 계산하는 9 가지의 Dubious Ways)를 읽어야 합니다. .


1
2×24×4

1
나는이 대답을 좋아한다. 비대칭 케이스는 문제의 공식화가 비대칭 매트릭스 대신 대칭 매트릭스로 이어질 수 있는지 고려할 가치가있는 함정을 충분히 가지고 있습니다.
JM

@ MarkS.Everitt : 당신은 거의 거기에있는 것 같습니다 ... 행렬은 얼마나 큽니까? 다시 ~ 36 x 36?
잭 폴슨

16×1636×36

2
@ MarkS.Everitt : 문제는 이제 4x4 행렬을 지수화하는 방법입니다. 이것은 점근 적 분석과 관련이 없을 정도로 충분히 작으므로 답은 전적으로 값에 달려 있습니다. 연결된 물리 게시물을 선형 대수로 변환하지 않으면 더 이상 말할 수 없습니다 (슈퍼 오퍼레이터 란 무엇입니까?!?).
잭 폴슨

7

Jack의 말을 바탕으로 소프트웨어에서 사용되는 것으로 보이는 표준 접근법 (예 : EXPOKIT과 같은)은 스케일링 및 제곱에 이어 Padé 근사법 (방법 2 및 3) 또는 Krylov 부분 공간 방법 (방법) 20). 특히 지수 적분기를 살펴 보려면 Krylov 하위 공간 방법을 고려하고 지수 적분기에 대한 논문을 살펴보십시오 (일부 참조는 Moler & van Loan 논문의 방법 20과 함께 언급 됨).

고유 벡터를 사용하는 것에 지옥이 있다면 삼각 벡터의 고유 벡터를 사용하는 것이 좋습니다 (방법 15). 행렬은 대각 화가 불가능할 수 있으므로이 방법은 최선의 방법은 아니지만 고유 벡터와 고유 값을 직접 계산하는 것 (즉, 방법 14)보다 낫습니다.

Hessenberg 형식으로 축소하는 것은 좋은 생각이 아닙니다 (방법 13).

Fortran 복잡한 산술이 빠르지 만 오버플로 / 언더 플로 일 수 있기 때문에 실제 또는 복잡한 산술을 더 잘 수행 할 것인지는 분명하지 않습니다 ( "Fortran 컴파일러가 실제로 얼마나 더 나을까요?"참조 ).

방법 5-7 (ODE 솔버 기반 방법은 비효율적 임), 방법 8-13 (고가), 방법 14 (큰 행렬의 고유 벡터 계산은 특별한 구조없이 어렵고 조건이 잘못된 경우 수치 오류가 발생하기 쉽습니다)를 안전하게 무시할 수 있습니다. 및 방법 16 (매트릭스의 요르단 분해 계산은 수치 적으로 불안정하다). 방법 17-19는 구현하기가 더 까다 롭습니다. 특히, 방법 17 및 18은 더 많은 판독이 필요합니다. 방법 1은 Padé 근사가 제대로 작동하지 않는 경우 스케일링 및 제곱에 대한 대체 옵션입니다.

편집 # 1 : Jack의 답변에 대한 의견에 따라 블록 대각선 화는 옵션처럼 보입니다.이 경우 방법 18 (블록 삼각형 대각선 화)과 같은 것이 사용하기에 매우 좋은 방법입니다. 귀하의 질문 에이 구조를 지정하지 않았으므로 처음에 권장하는 것을 주저했지만 매트릭스를 대각선으로 나타내는 블록을 변환하는 변환이 있으면 접근 방식에서 대부분의 복잡성을 제거합니다. 각 블록 대각 행렬 분해하는 GW Stewart의 트릭을 사용하고 싶을 것입니다.제이

제이=γ제이나는+이자형제이,

γ제이제이이자형제이


1
영형(2)영형()

의심의 여지없이 그들은 그들이 무엇을하고 있는지 알고 있습니다. LAPACK의 구현에 대해 걱정하지 않습니다. Fortran 컴파일러 동작에 더 놀랐습니다.
Geoff Oxberry

2
예, 컴파일러는 잘 작성된 LAPACK보다 문제가 될 수 있습니다. 컴파일러가 사용하는 절대 가치와 나눗셈 구현이 실패했기 때문에 프로그램이 실패했다는 것을 당황스럽게 생각할 수 있습니다.
JM

-1

임의 행렬의 지수를 계산하는 간단한 포트란 서브 루틴이 있습니다. Matlab 명령과 비교하여 확인했는데 괜찮습니다. 스케일링 및 제곱을 기반으로합니다. 나는 몇 년 전에 그것을 썼습니다.

gams.nist.gov에서 다운로드 한 것과 같은 다른 서브 루틴을 찾아보고 싶었습니다. 그러나 아직 운이 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.