質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
FORTRAN

FORTRAN(フォートラン)は科学時術計算に向いた手続き型プログラミング言語です。 並列計算の最適化が行いやすい特性上、数値予報および気候モデルなどの大規模な計算を行う分野のスーパーコンピュータで使われています。

Q&A

解決済

1回答

4942閲覧

Fortran: 大きさ1の正方形を格子点で埋める.

退会済みユーザー

退会済みユーザー

総合スコア0

FORTRAN

FORTRAN(フォートラン)は科学時術計算に向いた手続き型プログラミング言語です。 並列計算の最適化が行いやすい特性上、数値予報および気候モデルなどの大規模な計算を行う分野のスーパーコンピュータで使われています。

0グッド

0クリップ

投稿2017/03/21 13:28

###前提・実現したいこと
前にもFortranのプログラムについて質問させていただきましたが、今回もお世話になります。

今写真にあるような問題をとき直しています(わからないままだったので)。
問題

![![結果]
###発生している問題・エラーメッセージ
格子点を打ち、これに線を(gnuplotで)描かせても不完全な格子点になる.
###該当のソースコード

Fortran

1program lattice 2 implicit none 3 real(8), allocatable :: x(:,:,:) 4 real(8) :: x1 = 0.0d0, x2 = 0.0d0, x3 = 0.0d0, x4 = 0.0d0 5 integer :: i,j,l, m = 2, n(2)=(/ 10, 10 /) 6 real(8) dx1, dx2 7 open(11, file='Ex2.15_output.d') 8 allocate(x(m,n(1),n(2))) 9 dx1=1.0d0/dble(n(1)-1) 10 dx2=1.0d0/dble(n(2)-1) 11 do j=1, n(2) 12 do i=1, n(1) 13 x(1,i,j)=x1 14 x(2,i,j)=x2 15 write(11,*) x(1,j,i), x(2,i,j) 16 enddo 17 write(11,*) '' 18 x1=x1+dx1 19 x2=x2+dx2 20 enddo 21 22 do i=1, n(1) 23 do j=1, n(2) 24 x(1,i,j)=x3 25 x(2,i,j)=x4 26 write(11,*) x(1,i,j), x(2,j, i) 27 enddo 28 write(11,*) '' 29 x3=x3+dx1 30 x4=x4+dx2 31 enddo 32 close(11) 33end program lattice

###試したこと
いろいろ考えて、x(1,i,j)成分をi=1の場合j=1,nまで描き(点を打ち)、空行を入れる. i=2の場合j=1,nまで描き、空行を入れる...これを繰り返せばgnuplotで縦棒を描くことができるのではないかと考え、同様にしてx(2,i,j)については、iとjを入れ替えればマス目(格子点に線を描いたもの)をgnuplotに描かせることができそうとも考えました。(実際一つのdo分だけで考えてみたのですが、三角形が描かれるだけでした。)これをもとにして上のようなコードを書きました。ただ、結果としてはご覧の通りで、マス目を十分描かせることができません。

ご助言いただけるとうれしいです。以上よろしくお願いします。

###補足情報(言語/FW/ツール等のバージョンなど)
gfortran, gnuplot, 数値計算のためのFortran90/95プログラミング入門(牛島) P.63

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

座標点の生成と作図用の出力を分離すべき。
I/Oは鬼門なので分けてやる方が祟りが少ない。
ある意味、そのためにわざわざ配列を使っている。
横線だけをまず引き、次に縦線を引いてゆけば楽勝。

また座標点の生成ではdx,dyを足し合わせていっているが、これは浮動小数点数では地獄の一丁目で、避けねばならない。十進数でいえば0.333を三回足して1.0にならんと状況に陥る。どうしてもやりたいなら2のべき乗で分割しておけば避けられるが。

普通は下のように整数倍して最後に割って、浮動小数点数の誤差が溜まるのを避ける。この辺は数値計算の本の第1章あたりに必ず書いてあることなので、暇がある時に、初めの方だけ見ておくと吉。丸め誤差とか桁落ちとか、式を変形しろとグズグズ説教される。

要点を言えば、実数型は浮動小数点数で数学的実数ではないので、代数則の結合則が成り立たっていない。このため、実数の代数系で等価な式でも、コンピュータで演算すると同じ値を返さない。数学的実数の代数系で等価な式の内、コンピュータの浮動小数点数の代数系で演算して、元の式の答えに近い表現を選ぶ必要がある。

fortran

1program lattice 2 implicit none 3 real(8), allocatable :: x(:,:,:) 4 integer :: i,j, m = 2, n(2)=(/ 10, 10 /) 5 real(8) dx1, dx2 6 open(11, file='Ex2.15_output.d') 7 allocate(x(m,n(1),n(2))) 8 9 do j=1, n(2) 10 do i=1, n(1) 11 x(1,i,j)= (1.0d0 - 0.0d0) * (i - 1) / real(n(1) - 1, kind = 8) 12 x(2,i,j)= (1.0d0 - 0.0d0) * (j - 1) / real(n(2) - 1, kind = 8) 13 enddo 14 enddo 15 16 ! x-direction 17 do j = 1, n(2) 18 do i = 1, n(1) 19 write(11, *) x(1, i, j), x(2, i, j) 20 end do 21 write(11, *) 22 end do 23 24 ! y-direction 25 do i = 1, n(1) 26 do j = 1, n(2) 27 write(11, *) x(1, i, j), x(2, i, j) 28 end do 29 write(11, *) 30 end do 31 32 close(11) 33end program lattice

plot "Ex2.15_output.d" with linespoints

投稿2017/03/21 18:50

curehoney

総合スコア249

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/03/21 19:20

たびたびお世話になります。本当に助かります。 数値計算の内容については初心者なので、常識を教えていただき本当に助かります。Fortranは「いつか必要になるだろう」というモチベーションでやっていましたが、誤差についてもちゃんと考慮しておく必要があるとのご助言を頂いたので、これについても勉強していこうと思います。 I/Oについては、出来る限りシンプルに冗長にならないようにとdo文を減らしてまとめることを心がけていたのですが、ご助言通りI/Oパートは分けてかくようにします。 度々ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問