Fortran固有値を求めるためのサブルーチンとmainプログラムの記述方法

このQ&Aのポイント
  • プログラミング初心者のため、Fortranのサブルーチンを使用して固有値と固有ベクトルを求める方法がわかりません。
  • サブルーチンの配列宣言方法についての具体的なコード例を教えていただきたいです。
  • また、3x3の行列を使用して固有値を求めるコードサンプルを示してください。
回答を見る
  • ベストアンサー

fortran 固有値

プログラミング初心者です。 http://www.netlib.org/toms/496 ↑このサブルーチン(複素数からなる行列の固有値と固有ベクトルを求めるプログラム)を使いたいのですが、勉強不足のため、それすらできません。多分、配列の宣言の仕方がまずいと思うのですが… mainプログラムはどのように書けばいいのでしょうか? よろしくお願いします。 行列は3*3で試しています。 ↓これが今のプログラムです。 complex A,B,X,EIGA,EIGB integer N,NA,NB,NX,ITER dimension A(N,N),B(N,N),X(N,N),EIGA(N),EIGB(N),ITER(N) logical WANTX N=3 NA=3 NB=3 NX=3 A(1,1)= : A(3,3)= call LZHES(N,A,NA,B,NB,X,NX,WANTX) call LZIT(N,A NA,B,NB,X,NX,ANTX,ITER,EIGA,EIGB) end

質問者が選んだベストアンサー

  • ベストアンサー
  • ultraCS
  • ベストアンサー率44% (3956/8947)
回答No.4

サブルーチンのソース拝見しました。 早起きしてしまった、というより昼間寝過ぎで寝られない(実は療養中)ので、飲みながらということで勘違いがあったら失礼 ここ IF (ANORM.EQ.0.) ANORM = 1.0 IF (BNORM.EQ.0.) BNORM = 1.0 EPSB = BNORM EPSA = ANORM 40 EPSA = EPSA/2.0 EPSB = EPSB/2.0 C = ANORM + EPSA IF (C.GT.ANORM) GO TO 40 ここで、ANORM=EPSA=0.はあり得ないので、EPSAが浮動小数点で桁落ちするまでループが回ります。FLOATINGだとかなり時間がかかると思う(とんだと思うくらいにはかかるはず)。 このループはEPSAが0.にならない限り(桁落ちしない限り)、抜けません。BNORMがANORMより小さければ、そのときはEPSBも桁落ちするので全く意味のないループです。大体、EPSAと0.を比較すりゃすむのに、何故、Cを計算する。 どうも、ここは、間違っているような・・・ あと、お節介だけど ・WANTXが初期化されていません。多分0クリアされているので、実際は.FALSE.と思いますが、定義しておいたほうがいいでしょう。 ・これはサブルーチン作者に言いたいが、D0という変数は使っちゃ駄目です。デバッグ時にD0はDOと見間違うのでね。ステートメントやよく使う関数と紛らわしい変数定義はしないように

robo_goo
質問者

お礼

回答ありがとうございます。 ご指摘いただいたとおり、このループから抜け出せなくなっているようです。 しかし、わたしには固有値問題に関する知識があまりなく、そもそもこのループが何のためになるのかわからないため、どこをどう直せばいいのかわかりません。(一応、いろいろ試してみましたがうまくいきませんでした。) また、サブルーチンLZHESの出力も明らかにおかしいので、こちらもどこかおかしいのかもしれません。 そこで、時間はかかりますが固有値問題に関する理論、fortranについて勉強しようとおもいます。 朝早くから、わざわざありがとうございました。大変参考になりました。

その他の回答 (3)

  • ultraCS
  • ベストアンサー率44% (3956/8947)
回答No.3

どこで停まるのか、少なくとも、CALLの前後にデバッグ用の出力は入れないとわからないですよ。 リンク先のライブラリも見えないし で、もし、このソースをそのまま流しているのだとすると call LZHES(N,A,NA,B,NB,X,NX,WANTX) call LZIT(N,A NA,B,NB,X,NX,ANTX,ITER,EIGA,EIGB)         ↑ここにカンマがないんだけど どこのFORTRANかわからないので、こういうときにどういう動作をするかは断言しないけど(リンカで教えてくれる親切な処理系もあるけど)。LZITの中では嵐が荒れ狂っていることでしょうね。 実はカンマがあったなら、与えた引数では解けないで途方に暮れているのかも(サブルーチンが参照できないので自信なし) あとは、つまらんアドバイスだが、可読性を上げるために complex A,B,X,EIGA,EIGB integer N,NA,NB,NX,ITER dimension A(N,N),B(N,N),X(N,N),EIGA(N),EIGB(N),ITER(N) logical WANTX   ↓ parameter (N=3, NA=3, NB=3, NX=3) integer ITER(N) complex A(N,N),B(N,N),X(N,N),EIGA(N),EIGB(N) logical WANTX ・型宣言で配列まで宣言する。 ・parameter文では右辺で型が決まってしまうので、別に型宣言はしない。 など、重複しての宣言は間違いの元なので避ける(一度で宣言してしまう) また、暗黙の型宣言(I-NがINTEGERってやつ)には、よほどのことがなければ従う

robo_goo
質問者

補足

回答ありがとうございます。 コンパイラは英Salford Software社の「Salford FTN77 Personal Edition」です。 リンク先ですが、見れない原因がちょっとわかりません、すみません。 The Netlib( http://www.netlib.org/ )というサイトで「Eigenvalue」で検索して一番目にhitしたものなのですが… ↓検索結果はこんな感じです。 toms/496 keywords:eigenvalue, generalized eigenvalue problem gams: D4b4 title: LZHES/LZIT for:generalized eigenvalue problem for complexmatrices alg: LZ algorithm by: L.C. Kaufman ref: ACM TOMS 1 (1975) 271-281 いただいたアドバイスどおり型宣言を変えてみましたが、うまくいきませんでした。 また、デバッグ用の出力をつけていろいろ試したところ、サブルーチンLZIT内のif文の後で止まっているようです。 ↓これです。  IF (ABS(REAL(W))+ABS(AIMAG(W)).LE.ABS(REAL(Z)) * +ABS(AIMAG(Z))) GO TO 210 if文の前までは出力されますが、if文の後では出力されませんでした。210の後でもだめでした。 ABS(REAL(W))+ABS(AIMAG(W))と、ABS(REAL(Z))+ABS(AIMAG(Z)) の値に問題があるということでしょうか? だとしたら、何が問題なのでしょう? ちなみに行列Aは A(1,1)=4 A(1,2)=2 A(1,3)=1 A(2,1)=1 A(2,2)=5 A(2,3)=2 A(3,1)=2 A(3,2)=3 A(3,3)=3 としています。行列Aの要素が複素数なので実数だけでもいいと思ったのですが…

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

「途中でとまる」ってのは, どういう状況なんでしょうか? 何かメッセージは出ていませんか? あと, REAL などを使うと正確に答えがでるとは限りません. というより, REAL や COMPLEX を使うとほぼ間違いなく (ほんのわずかですが) 計算に誤差が生じると思ってください. これは実数を計算機で使う以上は避けて通れない問題です. なので .EQ. を使ったところで「正確に計算できないかもしれない (例えば, 本当なら 0 になるはずが 0 にならないかもしれない) ので .EQ. を使うのは危険だよ~」ってコンパイラが言ってます. 数値計算するときには必須の知識.

robo_goo
質問者

補足

WARNINGの理由がよくわかりました。ありがとうございます。 止まるということについてですが、mainプログラムで下のようにしてサブルーチンLZHESの処理が終わると end lzhes というメッセージが出力されるようにしています。しかし、出力されません。 warningは出ていますが、それは全て関係式によるものです。 ERRORSも出ていません osはwindows、コンパイラはsalford ftn77 personal edition、エディタはCPad for Salford FTN77を使っています。 call LZHES(N,A,NA,B,NB,X,NX,WANTX) write(6,*) 'end lzhes' 何度も申し訳ありませんが、よろしくお願いします。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

これがメインプログラムだったら, N は定数にしないとダメ. これだと N の値がコンパイルするときに決まらないからエラーになってると思うんだけど.... complex ... の前にでも parameter(N=3) と書いてみて.

robo_goo
質問者

補足

回答ありがとうございます。最初の部分を次のように直してみました。しかし、途中で止まってしまいました。 integer ITER,N,NA,NB,NX parameter (N=3,NA=3,NB=3,NX=3) complex A,B,X,EIGA,EIGB また、関係式があるところでは必ず以下のようなWARNINGが出ます。(サブルーチン内) なぜでしょうか?よろしくお願いします。 0062) IF (D.EQ.0.0) GO TO 80 WARNING - The use of .EQ. or .NE. with non-integer operands can produce

関連するQ&A

  • 固有方程式の問題

    A,Bをn次正方行列とし、AとBは共通の固有値を持たない (1) f(x)をAの固有多項式とするとき、f(B)は正則関数であることを示せ。 (2) AX=XBを満たす複素n次正方行列はゼロ行列に限ることを示せ。 という問題です。(1)はなんとなくA,Bが共通の固有値が違うことからf(B)の行列式≠0から示すのかなとおもうのですが、(2)が解りません。 両辺の行列式をとればXは正則でないことは示せるのですが0にしかならないというところまでうまく示せないのです。 そもそも f(B)=(B-λ1*E)(B-λ2*E)…(B-λn*E) ただし各λiはAの固有値 で考えていいんですよね。でも f(B)=det(B*E-A) なのですか? なんだかよくわからなくなってきました。 (2)の考え方と固有方程式に行列を代入したときどううなるかについてどなたかお暇な方お答えください。よろしくお願いします。

  • 固有値 固有ベクトル

    固有値を求める場合の固有方程式について質問させて頂きます。 固有値と固有ベクトルの定義は、 n×n行列Aに対して、λ∈C,x∈C^nが Ax=λx |x≠0 を満たすとき、λをAの固有値、xをλに対するAの固有ベクトルという。 固有値を求める際の固有方程式ですが、 私の手元にある参考書では、 |λI-A|=0とあります。 web等で調べると|A-λI|=0という表記もありました。 Iは単位行列を表します。 |λI-A|=0と|A-λI|=0はどちらも正しいのでしょうか? また、なぜ等しくなるのか教えて頂けないでしょうか? 以上、ご回答よろしくお願い致します。

  • 2つの行列の固有値が同じことを示す

    n x n行列AとBがあって,A=f(B)なる関係がある時,それらの固有値がすべて同じ(つまりA,Bの固有値をa_i,b_iとしたとき,すべてのiに対してa_i=b_i)であることを示すためには,どのような方法があるでしょうか?

  • fortran 固有値を求めるプログラム

    2x2の実行列の固有値を求めるモジュール関数の中で、d > 0 のときに出てくる sign(squt(d), -b)の値が示す意味と eval(2) = cmplx(c/e,0.0d0) でなぜ c/eの値が入るのかがわかりません。教えて下さい。よろしくお願いします。 プログラム module subprogs implicit none contains function eval2x2mat(a) result(eval) real(8), intent(in) :: a(:,:) complex(8) eval(2) real(8) b, c, d, e if (size(a,1) /= size(a,2)) stop ' not square ' if (size(a,1) /= 2) stop ' not 2x2 matrix ' b = -0.5d0*(a(1,1)+a(2,2)) c = a(1,1)*a(2,2)-a(1,2)*a(2,1) d = b**2-c if ( d < 0.0d0 ) then eval(1) = cmplx(-b,sqrt(-d)) eval(2) = conjg(eval(1)) else if ( d > 0.0d0 ) then e = -b+sign(sqrt(d),-b) ←ここの部分 eval(1) = cmplx(e,0.0d0) eval(2) = cmplx(c/e,0.0d0) else          ↑ここの部分 eval(1) = cmplx(-b,0.0d0) eval(2) = eval(1) endif end function eval2x2mat end module subprogs program main use subprogs implicit none real(8), allocatable :: a(:,:) integer :: n = 2 allocate(a(n,n)) a(1,1:2) = (/-1,1/) a(2,1:2) = (/-1,-1/) write(*,*) a(:,:), eval2x2mat(a) end program main

  • 固有値 一次独立

    代数学の本に (定理) n次正方行列Aが対角化可能であるための必要十分条件は、Aのn個の固有ベクトルX(1)、X(2)、・・・、X(n)で1次独立なものが存在することである。 このとき、P=(X(1)、X(2)、・・・、X(n))とすると、Pは正則で P^-1AP=|t(1)       |         |    t(2)   |         |       t(n)| ti(i=12・・n)はAの固有値 xi(i=12・・・n)はtiに対する固有ベクトル とが書いてありますが    どのようなことをいっているのでしょうか? また、固有値の時の一次独立とはどのようなことをさすのでしょうか? 最後に固有値とは、tを媒介変数として、連立方程式の解を行列によって導き出すと考えていいのでしょうか? よろしくおねがいします。

  • 固有値

    次の問題で、(1)は固有方程式から解けましたが、(2)以降が解けません。 どなたか回答お願いします。 行列, ベクトルは実数成分で, ||v|| はベクトルvの大きさで、 (1) 行列 A = 3 1 1 1 3 1 1 1 5 の固有値と固有ベクトルを求めよ. ただし, 固有ベクトルは単位ベクトルで, 第一成分は非負 (2) x ∈ R3, x ≠0 ならAx ≠ 0 となることを示せ. (3) x≠ 0 のとき F(x) =Ax/||Ax|| とする. (1) で求めた固有値をλ1, λ2, λ3 (λ1≧b λ2 ≧ λ3), 対応する単位固有ベ クトルをそれぞれe1, e2, e3 とする。a1, a2, a3 ∈ R \ {0} に対し x0 = a1e1 + a2e2 + a3e3, xn+1 = F(xn) (n ≧ 0) で ベクトルの列{xn}∞ n=0 を帰納的に定義する. xn をe1, e2, e3 の一次結合とし て表示し, 係数をa1, a2, a3 で表せ. (4) (3) で与えた{xn}∞ n=0 に対し極限lim n→∞ xn が存在し, A の固有ベクトルになるこ とを示せ. というものです。あと R \ {0}の意味も分かりません。宜しくお願いします。

  • 行列の積の固有値

    「nxn正則行列A,B,X=ABに関して,AとBの固有値と固有ベクトルが分かっているときに,Xの固有値と固有ベクトルを求めよ.」 という問題が解けません.どなたかお分かりになる方いらっしゃいますでしょうか? 補足 難しさは変わらないと思うのですが,Aは上三角行列,Bは下三角行列,X,A,Bは確率行列(全ての行を足すと(1,1,...,1)となる)という条件がありました. ですので,X,A,Bはそれぞれ固有値1を持つというのは分かります.この条件を使わないほうがいいのですが,使った場合でもありがたいです. なお,反復法などを用いて数値計算的に解きたいのではなくて,解析的にビシッと解きたいので,よろしくお願いします. ヤフー知恵袋のほうでも質問させていただいたのですが,有効な解が得られれませんでした. 教科書や,問題集の練習問題などではなく私が個人的に解きたい問題です.

  • 行列の固有ベクトルの証明について

    はじめまして テスト対策のプリントで出た問題なのですが A,Bがn次行列で、B=QAQ^(-1)を満たすn次正方行列Qが存在するものとするとき、λがAの固有値で、→xがその固有ベクトルであるとする。このとき、λはBの固有値でもあり、→y=Q*→xはその固有ベクトルを示せ。 という問題で、前半の、λはBの固有値でもある、という部分は |B-λE|=|QAQ^(-1)ーλE|=|QAQ(-1)ーQλEQ(-1)|=|Q(A-λE)Q^(-1)|=|Q|*|A-λE|*|Q(-1)|=|A-λE| からわかるんですが、後半の『→y=Q*→x はその固有ベクトルである』 という部分がわかりません。。 どのようにすればいいのでしょうか?? よろしくお願いします

  • 行列の固有ベクトルの解法

    現在行列の固有値と固有ベクトルをもとめるプログラムを作成しています。 手順としては、入力行列をハウスホルダー法により三重対角行列に変換し、その後QR法で対角化を行い固有値を求めます。 固有ベクトルはLU分解を使用して固有値ごとに求めていこうと考えました。 現状固有値を求めるプログラムは作成できました(そして正しく求められていることも確認しました)。そして行列のLU分解を行うプログラムまで作成できたのですが、LU分解後の行列から固有ベクトルを求める方法がわかりません。 詳しく説明します Ax = λx を (A - Iλ)x = 0 として、この(A - Iλ)をLU分解しました。 すると式は LUx = 0 となり 最終的に Ux = 0 をとく問題になります。 ここで行列Uは上三角行列なので、1次の連立方程式を解くように、行列Uの右下の要素を使って計算を始めていくのですが、自分がなにか勘違いをしているのだと思うのですがこの方法で計算すると固有ベクトルが全て0になってしまいます。  行列U     x       0 | 2 3 4 5 | |x1|   =  |0| | 0 4 2 9 | |x2|   =  |0| | 0 0 7 5 | |x3|   =  |0| | 0 0 0 8 | |x4|   =  |0| このような図式になり、固有ベクトルであるxを求めていくのですが、x4から順にもとめても0にしかならないんです。 下記のサイトを参考に学んでいたんですが、この部分が分からずにいます。 http://hooktail.org/computer/index.php?KL%C5%B8%B3%AB2 どこを勘違いしているんでしょうか? アドバイスをお願いします。  

  • 固有値、固有ベクトル

    いつもお世話になっています。固有値問題がわかりません。 Ax=λx λ:固有値 x:固有ベクトル としたとき ・A^-1 ・A^2 ・A+A^2 の固有値、固有ベクトルの求め方が分かりません。 Aがどんな行列か与えられてないのでどう解けばいいかわかりません。 教えてください。お願いします。