Fortranグラムシュミットの直行化プログラム実行結果の誤りについて

このQ&Aのポイント
  • Fortranで書かれたグラムシュミットの直行化プログラムの実行結果に誤りがあります。
  • プログラムを実行した際、答えの2列目1行目の値が予想と異なっています。実際の計算ではマイナスの値が得られるはずですが、プログラム上ではマイナスになっていません。
  • 計算結果の正確さに疑問があるため、プログラムに問題があるのかどうか知りたいです。
回答を見る
  • ベストアンサー

fortran グラムシュミットの直行化

グラムシュミットの直行化を行うプログラムを書いたのですが、実行結果の答えで2列目1行目の答えがマイナスになるはずなのになっていません。自分の計算ではマイナスになったのですが、プログラムに問題があるのでしょうか?教えて下さい。よろしくお願いします。 module subprogs implicit none contains function normal_vec2(v,n) result(nv) integer, intent(in) :: n real(8), intent(in) :: v(n) real(8) nv(n), vl vl = sqrt(dot_product(v,v)) if (vl == 0.0d0) then nv(:) = 0.0d0 else nv(:) = v(:) / vl endif end function normal_vec2 end module subprogs module subprogs2 use subprogs implicit none contains function gs(a,n) result(e) integer, intent(in) :: n real(8), intent(in) :: a(n,n) real(8) e(n,n), dotp integer k, j e(1:n,1) = normal_vec2(a(1:n,1:1),n) do k = 2, n e(1:n,k) = a(1:n,k) do j = 1, k-1 dotp = dot_product(a(1:n,k),e(1:n,j)) e(1:n,k) = e(1:n,k)-dotp*e(1:n,j) enddo e(1:n,k) = normal_vec2(a(1:n,k:k),n) enddo end function gs end module subprogs2 program main use subprogs use subprogs2 implicit none real(8), allocatable :: q(:,:) integer :: n = 2 allocate(q(n,n)) q(1,1:2) = (/2.0d0,1.0d0/) q(2,1:2) = (/1.0d0,2.0d0/) write(*,*) gs(q,n) end program main 実行結果 0.8944271909999159 0.4472135954999579 0.4472135954999579 0.8944271909999159                   ↑                             実計算では-(マイナス)がつく

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

  • ベストアンサー
  • f272
  • ベストアンサー率46% (8012/17124)
回答No.1

e(1:n,k) = normal_vec2(a(1:n,k:k),n) は e(1:n,k) = normal_vec2(e(1:n,k:k),n) のはず。

528612
質問者

お礼

そうですね。よくよく見返してみるとaでは異なった値になりますね。eに直して実行してみたら、ちゃんと実行結果が正しく表示されました。ご指摘ありがとうございました、

関連するQ&A

  • fortran cosθをベクトリから求めるプログラム

    ベクトルからcosθを求めるペログラムを作ってみたのですが、実際計算した値と実行結果の値が一致しないのですが。プログラム上に問題があるのでしょうか?教えて下さい。よろしくお願いします。 module subprogs implicit none contains function vec_cos(a,b) result(vcos) real(8), intent(in) :: a(:), b(:) real(8) ab, vcos if (size(a) /= size(b)) stop ' er : size(a) /= size(b) ' ab = dot_product(a,a) * dot_product(b,b) if (ab == 0.0d0) then vcos = 0.0d0 else vcos = dot_product(a,b)/sqrt(ab) endif end function vec_cos end module subprogs program main use subprogs implicit none real(8) :: x(1:2) = (/1.2d0, 3.4d0/), y(1:2) = (/5.6d0, 7.8d0/) write(*,*) 'cos = ', vec_cos(x,y) end program main 実行結果 cos = 0.9601163787292428

  • fortran 実行結果がうまく表示されない

    グローバルモジュールを用いてプログラムを書いたのですが実行結果が表示されません、プログラム中に問題があるのでしょうか?教えて下さい。 module params implicit none integer :: n = 2 end module params module sample implicit none contains subroutine swapvec3(x,y) use params real(8), intent(inout) :: x(n), y(n) real(8) tmp(n) tmp(1:n) = x(1:n) x(1:n) = y(1:n) y(1:n) = tmp(1:n) end subroutine swapvec3 end module sample program main use sample implicit none real(8), allocatable :: a(:), b(:), tmp(:) integer n allocate(a(n),b(n),tmp(n)) call swapvec3(a,b) call random_seed call random_number(a) call random_number(b) call random_number(tmp) write(*,*) ' a = ', a(1:n) write(*,*) ' b = ', b(1:n) write(*,*) ' tmp = ', tmp(1:n) end program main 実行結果  a = b = tmp =

  • fortran 乱数を用いてcosθをベクトリから求めるプログラム

    乱数を配列に格納してcosθをベクトルから求めるプログラムを書いてみたのですが、コンパイルしてみるとrandom_numberのところの設定がおかしいみたいでうまくコンパイルできません。どこに問題があるのかわからないので困っています。教えて下さい。よろしくお願いします。 module subprogs implicit none contains function vec_cos(a,b) result(vcos) real(8), intent(in) :: a(:), b(:) real(8) ab, vcos if (size(a) /= size(b)) stop ' sr : size(a) /= size(b) ' ab = dot_product(a,a) * dot_product(b,b) if (ab == 0.0d0) then vcos = 0.0d0 else vcos = dot_product(a,b)/sqrt(ab) endif end function vec_cos end module subprogs program main use subprogs implicit none real(8), allocatable :: x(:), y(:) integer n write(*,'(a)', advance = 'no') ' input n : ' read(*,*) n if ( n < 1 .or. n > 100 )stop ' n must be 0 < n < 101 ' allocate(x(n),y(n)) call random_seed call random_number(x,y) write(*,*) 'cos = ', vec_cos(x,y) end program main コンパイル結果 Undefined symbols: "_random_number__", referenced from: _MAIN_ in ccxYbc0C.o ld: symbol(s) not found

  • 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

  • fortran 配列

    はじめまして。fortranを勉強しているのですが割付け配列がよく理解できないので教えていただきたいのですが。以下に自分で作った簡単なプログラムを実行していたのですが正しい値になりません。どこが間違っているのでしょうか?教えて下さい。よろしくお願いします。 program list2_3 implicit none real(8), allocatable :: u(:), v(:) integer :: i, n = 2 real(8) dotp allocate (u(n), v(n)) u(1:2) = (/1.2d0,3.4d0/) v(1:2) = (/4.1d0,2.6d0/) dotp = 0.0d0 do i = 1, n dotp = dotp + u(n) * v(n) enddo deallocate (u, v) write(*,*) ' dot product =' , dotp end program list2_3

  • fortran 行列ベクトル積

    行列ベクトル積を計算するプログラムを下のように書いたのですが、実行した結果の答えが実際計算した答えと異なります。初期の要素の設定がおかしいのでしょうか?教えて下さい。よろしくお願いします。 program list2_14 implicit none integer , parameter :: n = 2 real(8) a(n,n), x(n), y(n) integer i, j, k, l a(1,1:2) = (/1.2d0,3.4d0/) a(2,1:2) = (/5.6d0,7.8d0/) x(:) = (/9.0d0,10.0d0/) do i = 1, n y(i) = 0.0d0 do j = 1, n y(i) = y(i) + a(i,j) * x(j) enddo enddo do k = 1, n write(*,*) (a(k,l), l = 1, n) enddo write(*,*) x(:) write(*,*) y(n) end program list2_14 実行結果 1.2 3.4 5.6 7.8 9. 10. 128.4

  • fortran 途中まで考えたのですが。。。。

    エラトステネスのふるい(素数の倍数を除いていって残ったのが素数)で3桁の素数を求めて表示したいです。 私が考えたのは、 1・2~99までの数を素数かどうか調べて、素数を配列に入れていく 2・100~999まで素数の配列の中の数で割って、割り切れたらおしまい。割り切れなかったら表示していく ということです。 しかし下のプログラムではうまく素数配列ができていないようなのです。 ここまでかなり時間がかかったのでこのプログラムに手をいれて これ以外におかしくなるところもどこを直せばいいのか教えてくださるとうれしいです。 C C q223.f C PROGRAM q223 C IMPLICIT NONE C INTEGER N,i,K,s,l REAL a(99),b(99),c(99),X,Y C real M C a(1)=2 a(2)=3 l=2 C DO N=2,99,1 M=N**(0.5) S=M DO i=2,S,1 K=MOD(N,i) IF(K ==0)THEN exit ELSE IF(K /=0)THEN l=l+1 a(l)=N ENDIF ENDDO ENDDO C do N=100,999 do l=1,99 X=a(l) Y=N/X if(Y==0)then exit else if(Y/=0)then write(*,*)N end if end do end do c end よろしくおねがいします

  • fortran おそらく二重解法のエラー

    以下のようなプログラム(速度ベレル法による時間発展)を書いたのですが,エラーがでてしまいます. どこが悪いのかを教えていただけたらと思います. PROGRAM verlet implicit none integer::i,n,p real(8)::dt,k,m,ratio,ti real(8),allocatable::x(:),v(:),f(:) allocate(x(0:n)) allocate(v(0:n)) allocate(f(0:n)) dt=0.01d0 n=1000 k=1.0d0 m=1.0d0 ratio=k/m p=4 ti=0.0d0 x(0)=0.0d0 v(0)=1.0d0 f(0)=-k*(x(0))**(p-1) do i=0,45 x(i+1)=x(i)+dt*v(i)+f(i)/(2.0d0*m)*dt**2.0d0 f(i+1)=-k*(x(i+1))**(p-1) v(i+1)=v(i)+dt*(f(i)+f(i+1))/(2.0d0*m) end do do i=0,n ti=i*dt write(6,*) ti,x(i),v(i) end do deallocate(x) deallocate(v) deallocate(f) END PROGRAM verlet

  • 電界の球座標(Fortran)

    FDTD法で求めたex(i,j,k), ey(i,j,k), ez(i,j,k) を使ってEr, Eθ,Eφを求めたいのですが、以下のプログラムではうまくいきません。式自体が間違っているのでしょうか? 詳しい方がいらっしゃったら教えて下さい。よろしくお願いします。 subroutine efield_spherical use consts use fdtd implicit none integer :: i, j, k, n, td real(8) :: e_r, e_the, e_phi real(8) :: r, theta, phi, s real(8) :: sx, sy, sz real(8) :: tx, ty, tz real(8) :: rx, ry open(10,file="e_r.dat") open(20,file="e_the.dat") open(30,file="e_phi.dat") sx = sin(theta)*cos(phi) sy = sin(theta)*sin(phi) sz = cos(theta) tx = cos(theta)*cos(phi) ty = cos(theta)*sin(phi) tz = sin(theta) rx = sin(phi) ry = cos(phi) theta = 0.0d0 s = pi/180d0 do n = 0, 360 phi = s*n ! Er e_r = ex(i,j,k)*sx+ey(i,j,k)*sy+ez(i,j,k)*sz ! E_theta e_the = ex(i,j,k)*tx+ey(i,j,k)*ty-ez(i,j,k)*tz ! E_phi e_phi = -ex(i,j,k)*rx+ey(i,j,k)*ry write(10,*) e_r write(20,*) e_the write(30,*) e_phi enddo close(10) close(20) close(30) return end subroutine

  • fortran77教えてください

    fortran77のプログラムについての質問です。 次のプログラムを実行するとどのような結果になるか教えてください REAL A,B,C,D,E,F A=7.0 B=5.0 CALL WASA(A,B,C,D) CALL WASA(C,D,E,F) WRITE(*,*)E,F STOP END SUBROUTINE WASA(P,Q,R,S) REALP,Q,R,S R=P+Q S=P-Q RETURN END

専門家に質問してみよう