1 :
デフォルトの名無しさん :
2009/01/24(土) 18:32:01
2 :
デフォルトの名無しさん :2009/01/24(土) 21:22:49
気象庁とかが推奨している、配列の代入にコロンを明示する方式でのスピード低下率の
まとめがあった。
ttp://www.ifremer.fr/ditigo/molagnon/fortran90/f90col.html たとえば、以下のような場合
CALL( A )
CALL( A(:) ) -> ALLOCATE( TMP(SIZE(A)) ) ; TMP = A ; CALL (TMP) ; A = TMP ;DEALLOCATE(TMP)
ソースの意味的には同じだが、下の書き方だと、コンパイラが一度テンポラリに
Aの中身をコピーしてテンポラリを読んだりする実装がされたりする。
最近は少し賢くなったようだw
それ最近の記事?
へ~ allocateして動的にメモリの空きを探して確保してコピーして、って 素で考えると手間がかかるだけな気がするけど、わざわざそうするということは 何か別な利得が発生するのかな?
6 :
5 :2009/01/26(月) 06:59:41
allocateして、は消してね。 a(:)が添字範囲全部の場合も、一部だけの場合でも両方対応するようにしたけど、 範囲全部の場合だけ別にする事を忘れただけなのかな?
その記事は古いアルよ。 出ているコンパイラやOSを見る限り。
じゃ、今は気にせんでおkってことね?
do I = 1 , N if(条件式) then endif done と do I = 1 , N if( ! 条件式) cycle done は、やってることは等価だけど、速さも同じ?
両方コンパイル時に止まるから速さも同j(ry まあ、コンパイラにもよるから自分で試してみてくれ。
最近大学でfortranを使い始めたのですが、インテルMKLを使うときはコンパイル時に 「ifortl」というコマンドを使うように指示されたのですがうまくいきません どなたかわかる方いらっしゃいませんでしょうか? 環境は OS Linux バージョン不明 コンパイラ Intel Fortaran 10.0 MKL Intel MKL9.1 コンパイラの購入時に「ifortl」コマンドを使うと自動でMKLのリンクが張られる~ のような説明を受けたらしいのですが、使用すると引用したモジュールが見つかりません という旨のエラーメッセージがでます。 リンクオプションをきちんと記述するとコンパイルできます MKLへのリンクの環境変数が通っていないんだと思うのですが、 設定方法がわからない状態です
12 :
9 :2009/01/28(水) 02:42:17
>>10 >両方コンパイル時に止まるから速さも同j(ry
意味わからん。文法ミスって意味?
普通に使えてるんだが
>>11 ウチのIntel Fortran 11.0 x86_64版には"ifortl"なるコマンドはないし、
ちょっとググってもそれらしい物はヒットしない。
とりあえず
file `which ifortl`
で ifortl の位置と種類を確認して、シェルスクリプトか何かなら
cat `which ifortl`
で中身を確認、書き換えられそうなら自力で修正
という感じで。
>>11 「ifort」の間違いってオチじゃないよね…
教官殿が気を利かせてMKLライブラリリンク用のを作ってくれたのかも知れんね。 13の通りwhichしてその内容をさらしてみるべし。
MKLライブラリ、って書き方はおかしかったな・・。
17 :
11 :2009/01/28(水) 12:33:23
>>13-
>>16 ありがとうございます、無事解決できました。
>>15 まったくその通りでした
うっかり「ifortl」という隠しコマンドでもあるのかと思ってました。
リンクを張ったつもり~でしたが、実際は一部しか張ってなかったです
それにしてもなんというゆとりコマンド・・・
そーいう余計なことは正直やめてほしいよなぁw
ちょっと年代ものの他人が書いたf77のコードなのですが、 FW=CB(2)-CB(1) //計算領域の幅を算出 CW=FW/NCX //幅をセル数で割ってセルの幅を算出 となる部分で、FWが1.33、NCXが200で、CWが6.65E-03となるはずが、 なぜか6.6500003E-3となっています。ちなみにFWはここで突如出現、 それ以外は特に型の宣言無くCOMMON文の中で定義されています。 何となく型の宣言が問題のような気がするんですが、原因と解決法 (ぴったり6.65E-3にしたい)を教えていただけませんか?
20 :
19 :2009/01/28(水) 18:05:01
あ…すいません、FWもCOMMON文中に定義してありました。
>>19 単精度なら有効桁からいって7~8桁目にゴミが出てもおかしくない。
ゆえに気にするな。
フォーマットを与えずに*で書かせれば、自動的に精度の範囲内で出力するので
ゴミは見えなくなるだろう。フォーマットは浮動小数点での表現を単に何桁でも
十進法に直して書くだけだから、単精度でもF30.20とか書けば小数点以下20桁とか
書いてくれるが、有効数字的には6~7個しか意味ない。
22 :
19 :2009/01/29(木) 09:49:23
>>21 回答ありがとうございます。なるほど、7~8桁目は有効数字外なんですね。
実害があってですね、粒子の位置の判定ををするとき、粒子の位置Xを
セルの幅CWで割って、
LCX=(X/CW)+0.999999 //Xが3.5、CWが1だとすると4.499999、整数に代入して4で4番目のセルに入る
みたいな処理があるんです。このとき、CWがずれてるとセルナンバーが大きいところだと、
想定外の変なセルに入っちゃう粒子が増えてきます。でも有効数字の問題だとすると、倍精度にしたとしても、
頻度は減るにせよ、根本的解決ではないってことになりますね?やっぱりこの処理自体に問題があるんでしょうか?
問題があるとしたらどういう方法にするべきでしょうか?
小数点捨てにしよ四捨五入にせよ、数値誤差や丸め誤差やら打ち切り誤差で致命的に 結果が変わるようなモデルが悪い。そんなの窓から投げ捨てちゃえw
24 :
23 :2009/01/29(木) 10:25:56
とはいっても粒子数がいっぱいあれば、離散化した箱の中の数が一個二個違うくらいではそんなに 変わらないだろうな。同じ問題は倍精度にしてもたぶん起こるよ。いまのCPUは単精度と倍精度で ほとんど計算コストが変わらないので気が向いたら倍精度でやってみよう。
>いまのCPUは単精度と倍精度でほとんど計算コストが変わらない ほんとに?! 普通に考えれば倍精度になればデータが倍になるから、スピードは半分になるような その辺考えてあえて倍精度じゃなく単精度を使ってるコードもあるじゃん
26 :
デフォルトの名無しさん :2009/01/29(木) 11:33:48
>>25 いまの計算機ってメモリ・CPU間のデータ転送をクレバーに
さばくからあまり目立っては違わない。
ほとんど変わらないとは思わないけどコードにもよるけど
単精度でしても2割速くなれば御の字じゃないかな。
メモリ節約して粒子数なり格子数を増やす方にメリットがあると
当然単精度でするだろうけど。仮に2倍速になるにしても、
高々2倍のスピードを求めてあえて単精度で計算する、
というのは何か間違っていると思うよ。
27 :
デフォルトの名無しさん :2009/01/29(木) 12:04:26
ディスクアクセスが非常に多い場合はそこでのロスを減らすために 単精度ですることは良くある たくさんの測定データを読み込んで処理するときとかは特に 測定値だと元から倍精度の精度はないし
>>22 はじめに一言。
四捨五入をしたいだけなら、NINTという関数があるのでそれを使うとよい。
ただNINTを使っても、十進表記にこだわると、今回の問題は解決しないかもしれない。
その理由を簡単に言うと以下のようになる。
Fortranでいうところの実数は、数学的な意味での実数ではない。
いわゆる浮動小数であって、有限個の有理数点で実数を代表させている。
ある種の区間をあらわす代表の数である。
その区間は、二進数表記で区切りのいい点で切っているので、十進数表記では
切りのいい点になっていない。
十進数で四捨五入しようとしても、そもそも閾値に幅があるのだから、その幅分の誤差が
出てもしょうがない。単精度ではそれが、有効数字7~8桁目にくる。
数直線をかみそりで切り分けるイメージではなく、木材をのこぎりで切るイメージで
考えればおk。切るとき、おがくずが出て、切った材木にはのこぎりの歯の幅だけの誤差がでる。
それは避けられない。
>>26 クレバーってどういう意味?データ転送のレイテンシ隠蔽をがんがってくれるって意味?
普通のアプリでは役に立つけど、数値計算のようなデータを単純にガバガバ読むプログラムじゃ
そういうテクの恩恵はあんまないでしょ。
メモリから演算器へ転送するデータ量が単純に倍になるんだから・・・
違いは計算のコードや計算機の種類によりそうだけどね。 ベクトル化をすごく気にしたコードとか 一つのループを短くしたコードだとデータ転送の頻度がたぶん すごく高いから29の通り単精度倍精度の違いは大きいだろう。 ループを細切れにせずに一つのループ内でながめな処理をするタイプだと 計算中に次に使うデータを取ってきたり更新の済んだ分をメモリに戻す暇が 出来そうだ。
非線形系だと誤差って結構重要なんだよね 簡単に見えて意外に厄介
>>31 んだ。超厄介
>>30 キャッシュ内ですっぽり収まる程度の長さのループなら
ループの頭でlocalな変数に大配列の一部を複写してからの方が
編集やバグ探しが楽になるからまあ良いんだけど。
いまはだいぶ楽ちんだけど、ちょっと前はある長さを境にして
ガクンと遅くなることがあったな。他人のコードってあんまり見た
こと無いから判らないけど,ループは長いor短い方が良い、
とかtemporalな変数にうつすor大きい配列をガンガン右辺に持ってこよう、
とか、今の流行というか推奨はどっちなんだろう。
33 :
19 :2009/01/29(木) 17:45:46
なるほど…ひとまず倍精度にしてみてどれくらい遅くなるか 見てみることにします。情報を小出しにしちゃって申し訳ないんですが、 一番問題なのは、上の処理をすると、領域ぎりぎりに粒子があったとき、 50までしかセルがないのに51セル目を見ようとしちゃうことですね。 このエラー自体が不可避ならとりあえずそこの例外処理だけは入れといたほうがよさそうですね。 いろいろありがとうございます。上記件について何かいいアイデアあればぜひ。
>>33 50セルがMaxなら、いったん10000倍なり拡大して整数に入れて、その整数の世界で
切り分ければいい。
整数がオーバーフローすると問題だが、50セルがMaxなら大丈夫だろう。
35 :
デフォルトの名無しさん :2009/01/30(金) 00:07:25
分からないので質問させてください。 拡大係数行列Pに対して、部分ぴぼっと選択と行基本変形を繰り返して、 ガウスの消去法をするプログラムを書きました。 ここでPのある縦列が全て0のとき、たとえぴぼっと選択していても、 (*)のところで0の割算が出てしまいます。 これを回避するうまい方法or常套手段はありますか?
36 :
35 :2009/01/30(金) 00:07:53
! Searching the factor and its location which held the maximum number in a column j do j = 1,sizeN ValMax = 0.0d0 ImaxHeld = 0 do k = j, sizeN if( ValMax < abs( P(j,k) ) )then ImaxHeld = k ValMax = abs( P(j,k) ) end if end do write(*,*) 'ImaxHeld=', ImaxHeld, 'ValMax=', ValMax ! Two rows are exchanged so that the maximum factor is placed at a diagonal tmp(:) = P(:,j) P(:,j) = P(:,ImaxHeld) P(:,ImaxHeld) = tmp(:) ! Now the diagonal factor P(j,j) is a pibot P(:,j) = P(:,j) / P(j,j) ! <=(*) do i = 1, sizeN if (i /= j) then P(:,i) = P(:,i) - P(j,i)*P(:,j) end if end do end do
>>35 一列全部0なら、シンギュラーな行列なんだから、そもそも解が無いだろ!
線形代数の教科書を100回読み直せ!w
38 :
デフォルトの名無しさん :2009/01/30(金) 07:23:57
pivot?
39 :
35 :2009/01/30(金) 11:25:16
そうでした。すみません。 『行列式も0になって、クラメールも使えなくてどうしよう』などと考えてしまいました。 やりたいことは最小二乗法の正規方程式を解くことなのですが、問題は データの与えかたによって、解が有ったり無かったりする (列が全部0になったり、ならなかったりする)事です。 こんなとき、システマティックにやる方法はありますか?
40 :
35 :2009/01/30(金) 11:31:51
今見直したら、最小二乗法で与える近似関数として、
間違ってsin(0)を与えていたために係数行列の列が全て0になっていました。
>>37 さんありがとうございました。
CrayがFortran2003完全対応のコンパイラをリリースしたらしいな。 ついでにFortran2008にも部分対応らしいな。 といっても、CoArrayはもともとCRAYがやっていたので当然なんだが(笑
caryってまだ生きてたんだ・・・
>>42 Crayはここ10年くらいのアメリカの護主義のおかげで復活してる。
一時期の低迷は脱している。
そういえば、東工大のつばめに刺さっていたクリアスピード社が、イギリスの経済壊滅の
余波で株価急落、資金繰りにもつまってきたというニュースが先週流れてきてた。
ETA10の夢ふたたびw
この不況でスパコン業界の勢力図も相当変わるだろうな つーかCrayってもう石は作ってないんだよな? その他大勢の単なるシステム屋さんに成り下がっちまった
45 :
デフォルトの名無しさん :2009/02/07(土) 22:16:59
>9 アセンブルコードを吐かせてサイズを比較しろ
>>9 1CPUなら後者が速いことが多い・・・とおもう。
並列だとたぶん前者・・・とおもう。並列処理すると代償でマスキング処理が抑制されることがあるから。
個人的にはif-endifで処理しない・する範囲を明示する方が好き。
if文の行うマスク処理って、ベクトル処理のときの話じゃない? 違ったらごめん
48 :
デフォルトの名無しさん :2009/02/08(日) 18:01:42
超初心者で恥ずかしながらご質問させていただきます。Compaqのvisual fortranを使ってます。 先輩からいただいたプログラムのファイルは2つあり、ひとつが本プログラム、もうひとつがサブルーチンプログラムです。 この状況で、もうひとつのサブルーチンプログラムをworkspaceのところで作成し、compile、excecutionをしたのですが、 どうもerrorなどはないのですが、write文などの結果が既存のサブルーチンプログラムからの結果が出力され、 新しいプログラムでの結果が出力できません。どうやったら、新しいプログラムの結果が 出力できるのか、教えていただけますでしょうか。 大変、初心者の質問で申し訳ございません。
49 :
デフォルトの名無しさん :2009/02/08(日) 18:08:07
↑ちょうど友達から電話があり、教えていただきました。どうもご迷惑をおかけいたしました。 無視してください。また、お世話になるかと思いますが、どうぞよろしくお願いいたします。
50 :
デフォルトの名無しさん :2009/02/08(日) 19:23:15
>>47 あってるよ。
でも並列処理するときに誤作動防止で
ベクトル処理を抑制することがあるというのはありそうではある
MKL(というかライブラリ一般)の使い方を初心者に解説してるサイトや本ってありませんか(英語可) Matlabから移行してきたんですが、公式マニュアル見てもプログラミング関係の単語がわからずで。ラッパーとか。 数値計算に関しては、噂に聞いてたよりも使いやすいなあ、と思ってるんですが。 よろしくお願いします
52 :
デフォルトの名無しさん :2009/02/10(火) 17:32:15
gfortranでコンパイル時、下記のエラーが発生して困っています。
gfortran -i8 '-mcmodel=medium' -fdefault-integer-8 -O2 -mtune=opteron -m64 -c hoge.f
In file hoge.f
C(1) = LShift(I1,32).or.(I2.and.NM32)
1
Error: Operands of logical operator '.and.' at (1) are INTEGER(8)/INTEGER(8)
似たような問題を見つけましたが、対処方法がよく分かりません。
ttp://gcc.gnu.org/ml/fortran/2005-07/msg00416.html どなたか教えて頂けないでしょうか。
ENV: RedHat 4, GCC 4.1.2
>>52 何をしたいのか、それだけでは意味不明だが、『hoge』などというUNIX系の方言を
しゃべるところを見ると、C言語とかと混同して論理演算とビット操作を勘違いしていると邪推?
> C(1) = LShift(I1,32).or.(I2.and.NM32)
(LShift という関数は、Fortranの標準関数には存在しない。が、ベンダー拡張の
ビット操作演算子としてよく存在しているので、ビット操作演算子だと仮定する。)
これは、論理演算とビット操作と論理演算を混用しているので、コンパイラが怒っていると
思われる。
正しくは、
INTEGER(8) :: i1, i2, nm32
INTEGER(8) :: ic(整数)
ic(1) = IOR( ISHFT(i1, 32), IAND(i2, nm32) )
Fortranには、論理型と整数型の区別がある。 .and. や .or. は論理演算子であって
真偽の二値しかもたない論理型の変数(あるいは定数)に作用する。
一方、整数型の変数(や定数)に対するビット演算子も存在している。
それは二引数をとる関数で IAND や IOR、あるいはビットシフト演算子 ISHFT である。
cを整数として使うのは、暗黙の型に反するので、どうしてもと言う理由がなければ
やめたほうがいいと思う。
なお、Fortranの論理変数の内部表現は規格では不定であって、処理系によってことなる。
一般的にLSBが1か0かで真偽を区別していることが多い。
C言語のように0が偽で、その他が真というわけでない。
よって、論理演算を行ってもLSBしか変化していなかったりする。
しりたければEQUIVALENCEをかけるか、TRANSFER関数で内部表現を見れば分かる。
>>53 的確かつ詳細な回答有り難う御座います。大変参考になりました。
お察しの通りC言語の経験者ですが、Fortranは皆無です。
ご指摘を参考に勉強致します。有り難う御座いました:-)
Intel Visual Fortran の update 通知が来てたけど、F2003対応は進展したかい?
FORTRANのG77をダウンロードしたいのですが、よくわかりません。 Vistaに対応した無料FORTRANが出来るようになるサイトを教えてください。 申し訳ありませんが、よろしくお願いします。
>>56 俺的にこれがお勧め
ttp://www.download.com/Silverfrost-FTN95/3000-2069_4-10491439.html Plato3と言うソフトが一緒にインストールされるから、それを起動して
File->Newもしくは左上の白いアイコンをクリックするとNew Fileと言うウィンドウが出る
FORTRAN77のコードを書きたいならFixed Format Fortran fileを
Fortran90/95のコードを書くならFree Fomat Forrtran fileを選択しOpenボタンを押す。
あとはコードを書いて、左上に青い再生ボタンがあるのでクリック、変なダイアログが出ても
OKおせばおk。あと、黒いウインドウを閉じる時は、右上の×じゃなくて、キーボードの
Enterを押さないと落ちる事があるので注意
Intel Fortran11が出たけど、初物には飛びつかんほうがいいかなーやっぱ
そういえばWindows XP SP3の対応って11からだっけ?>Intel Fortran
>>55 bug fixが中心だろう
Memory allocation error in for_array_copy_in()
とか
11.0 message catalog produces garbled messages with Japanese compiler
とかあったから、とりあえず入れといた
IntelFortran6.0使ってたんだけど、 11.0でコンパイルしなおしただけで計算時間が1/3になってワロタ 別に最適化オプション何も使ってないデフォルトなんだけどな これでOpenMPで最適化したら一体どうなるんだ
>>61 黒カエラーはまだ直ってないなw
誰もIntelに通報してないのか?
>>62 7になった時にですごく良くなった気がする。
あとはあまり変化は大きくない気がする。
・・・といって今使ってるのが9のままなので10,11でまた進歩があったのかな?
SSE絡みでは順次良くなったそうだけど
明示的にそれを使うことは少ないからなあ。
DECのエンジニアが入ったのが7からだっけ? 見違えるように良くなったって話だが
昔のはVisualC++へのプラグインだったからなぁ。
つまらないことなんですけど みなさんはエラー系の出力はwrite(0,*)を使っていますか? それとも、標準出力もエラー出力も全部print *を使っていますか?
>>67 標準出力とエラー出力があるっていうのはUNIXの話だから、
メインフレーム上がりでUNIXをおもちゃと馬鹿にしているおっさんたちは、
そんなもの存在も知らず、相変わらず6番に出力していると思う。
program mtest integer, allocatable :: imem(:) msize = 1000*1000 * 200 call alloc4i(imem, msize) c : stop end subroutine alloc4i(imem, msize) integer, allocatable :: imem(:) if ( .not. allocated(imem) ) then allocate( imem(msize), stat=ier ) if (ier .ne. 0) stop else stop endif return end こんな感じでメモリ割付をするサブルーチンを作りたいのですが、サブルーチン側の 配列宣言でコンパイルエラーになってしまいます。このように親側でallocatableにした 配列は、サブルーチン側でどのようにallocateするのでしょうか?
70 :
69 :2009/02/22(日) 00:57:29
>>69 先頭のスペースが全て削除されてしまったようです。
c: の行は無視してください。
>>69 外部サブルーチンだからエラーが出んじゃない?
内部サブルーチンやモジュールで使ってるけど
エラーは出ないよ
72 :
69 :2009/02/22(日) 02:58:23
>>71 program memtest
integer, allocatable :: imem(:)
msize = 1000*1000 * 200
call alloc4i
stop
contains
subroutine alloc4i
if ( .not. allocated(imem) ) then
allocate ( imem(msize), stat=ier )
if (ier .ne. 0) stop
else
stop
endif
return
end subroutine
end program
レスどうもです。こんな感じでしょうか?
たしかにコンパイルは通りました。ただ、ライブラリ化
したいため、分割コンパイルしたいのです。何とか
外部プログラムで実現できないでしょうか・・・
>>72 MODULEに入れるか、本体側でINTERFACEを書けばいいんでね?
ALLOCATABLE属性をつけても、77式に裸にしておくと、引数がマッチしているのか分からんから
怒られるんだと思うが。
74 :
69 :2009/02/22(日) 09:30:19
>>73 module malloc
integer, allocatable :: imem(:)
contains
subroutine alloc4i(imem, msize)
integer::imem(:)
integer::msize
allocate ( imem(msize), stat=ier )
if (ier .ne. 0) stop
return
end subroutine
end module
program memtest
use malloc
integer::msize
msize = 1000*1000 * 200
call alloc4i(imem, msize)
stop
end program
う~ん・・・ f90に疎くて、こんなコードしか書けませんでしたorz
ホントは、下みたいな感じで、program側で複数の配列確保に使える
サブルーチンが欲しいのですが・・・
program memtest
:
call alloc4i(imem1,msize)
call alloc4i(imem2,msize)
:
>>74 やりたいのはこんな感じかな?
MODULE m_test
CONTAINS
subroutine alloc4i(imem, msize)
integer, allocatable, INTENT(OUT) :: imem(:)
integer, INTENT(IN) :: msize
if ( .not. allocated(imem) ) then
allocate( imem(msize), stat=ier )
if (ier .ne. 0) stop
else
stop
endif
return
end subroutine alloc4i
END MODULE m_test
program mtest
USE m_test
integer, allocatable :: imem1(:), imem2(:)
msize = 1000*1000 * 200
call alloc4i(imem1, msize)
call alloc4i(imem2, msize)
stop
end
76 :
69 :2009/02/22(日) 20:12:35
>>75 レスどうもです。
ズバリ75のコードなのですが、私のコンパイラ(Fortran PowerStation 4.0)ではエラーが出ます。
4行めがイカンと言っているようです。
malloc.f90(4):error FOR3435: symbol IMEM is a dummy argument
- cannot be ALLOCATABLE detected between IMEM and (
文法的には間違っていないと思うのですが・・・
別のコンパイラでも試してみようと思います。
コードの調整までして下さり、本当にありがとうございました。
>>76 俺のおぼろげな記憶では、ALLOCATABLE な配列をサブルーチン側で ALLOCATE して
返せるようになったのは Fortran95 以降だった気がする。
Fortran90ではPointerでやるんじゃなかったかな?
文法書で確かめてくれw ガセネタだったらすまんこ。
78 :
69 :2009/02/23(月) 06:31:29
>>77 統合環境のオンラインマニュアルを良く読むと、以下の記載がありました。
>Remarks
>You can only use the ALLOCATABLE attribute to declare an array
> that is not a dummy argument or a function result.
不注意でしたorz
どうやら仰る通りのようです。ポインタを勉強したいと思います。
実は、先輩がメインフレームで使っていたコードを引き継いだのですが、昔風のメモリ管理を
していて、ブロック名を直接メモリ域に書き込んだりしていたので、PC上ではコンパイル
出来ずに困っていました。それで、Fortran90を使って書きなおそうと考えた次第です。
重ね々々ありがとうございました。
>>78 POINTERに直すだけなら簡単。
ただALLOCATABLEに比べて自由度が大きい分最適化やチェックに支障が出るらし。
MODULE m_test
CONTAINS
subroutine alloc4i(imem, msize)
integer, POINTER :: imem(:)
integer, INTENT(IN) :: msize
if ( .not. ASSOCIATED(imem) ) then
allocate( imem(msize), stat=ier )
if (ier .ne. 0) stop
else
stop
endif
return
end subroutine alloc4i
END MODULE m_test
program mtest
USE m_test
integer, POINTER :: imem1(:), imem2(:)
msize = 100*100 * 200
call alloc4i(imem1, msize)
call alloc4i(imem2, msize)
PRINT *, SIZE(imem1), SIZE(imem2)
stop
end
ASSOCIATED だけでいいのか今一自信なし。
80 :
69 :2009/02/24(火) 07:04:42
>>79 何から何まで申し訳ありません。
コードはコンパイル1発でOKでした。
allocate後は配列と同じように使えるみたいですし、cのポインタより保護されている感が
あっていいですね。危険性に関しては、昔のメモリマネジメントより随分安全と感じますが、
別ルーチンでしっかりチェックするつもりです。
ただ、f90は利用情報が少ないので、少しずつ勉強しながら使って行こうと思います
(周りに利用者がいない。f77かcかVB)。特にPCの処理系では、方言等ありそうですね。
規格にも目を通したいと思います。
色々とありがとうございました。
モジュールで宣言した変数って自動的にsaveになるんですか?
82 :
81 :2009/03/12(木) 21:16:17
すいません。
>>81 は勘違いでした。
もう一つお聞きしたいんですが、INTERFACEって使ってますか?
外部プログラムを書いてから、また同じようなのをイチイチ書くのは
面倒臭いし、モジュールで全部代用できる気がするんですが・・・。
83 :
81 :2009/03/12(木) 21:27:41
ちなみに何故
>>81 で勘違いしたかですが、下のようなテストをしたところ
sub2でもi=1だったので、変数iはsave属性なのかと思ったためでした。
同じモジュール中の変数をuseしたから同じもの(実体)を見てるだけで
あって、save属性が付いているわけではない、が正解でしょうか?
以下、ソース(行頭タブは全角スペースにしてます)
module module0
implicit none
integer::i
contains
subroutine set(j)
integer,intent(in)::j
i=j
end subroutine
end module
subroutine sub1
use module0
call set(1)
print *, 'in sub1 : i=' , i
end subroutine
subroutine sub2
use module0
print *, 'in sub2 : i=' , i
end subroutine
program main
call sub1
call sub2
end program
>>83 変数のスコープや寿命について勉強してみてはどうかな?
>>82 interface は使わないで済む事が多いよね。
pure 属性つけたサブルーチン内で
pure 属性つけたサブルーチンを呼ぶ時には
interface で前もって教えておかないとintel fortran に怒られるようなので
使うけど。これも多分使わないですむやり方がありそうな気もする。
>>83 愛が・・・
86 :
83 :2009/03/13(金) 14:02:12
どうもmoduleのuseを、Cでいうクラスのインスタンス生成みたいに
考えてたのが混乱の原因だったようです。
で、結局
>>83 の理解は間違っていますか?
教科書にモジュール変数をグローバル変数とする場合はsaveを付けろと
あるんですが、実際
>>83 のmodule0のiにsaveを付けても付けなくても、
module0をuseしたプログラムでiの値を確認すると、値が保持されているようです。
>>86 教科書に書いてることは正しい。
Fortranの規格からすると、Module変数はSAVE属性は無い。
Fortran Handbook なんかにもわざわざ書いてある。
本来の規格の上では
>>83 でiが消えてもいいように思う。
NAGあたりの規格への忠実さを目指したコンパイラで試してみればいいのではないかと思う。
>>82 INTERFACE は、ソースが無くてバイナリ-だけで配られているような、
ライブラリを呼ぶようなときに必要になるもんだと思う。
ソースが揃っているなら、Moduleにまとめておけばおk?
88 :
85 :2009/03/14(土) 03:06:21
>>87 の後半
正統なFortranではOKとおもう。が、
ソースが揃ってるか一つのファイルにまとまっているなら interface文は無くてもいい子・・・
と思ってたらifortは文句行ってきた・・。まあ害が無いなら、interface を呼ぶ側でぺたぺた
使ってもいいと思う。
呼ばれるサブルーチンの頭の部分を変更した時に、呼ぶ側全部でそれを意識していたかを確認できるし。
手間が増えるだけな気もするけど、勘違いやバグ防止の対価と思えば高くもない、かな。
>勘違いやバグ防止の対価と思えば高くもない たしかにそうね 先人が書いた得体の知れないFORTRAN77な外部副プログラムを安全に呼ぶために使う、とか つーかinterfaceって名前が、javaやc#と意味が全然違くて紛らわしいというか、いまいち気に入らんw
90 :
83 :2009/03/15(日) 20:19:01
>>87 >本来の規格の上では
>>83 でiが消えてもいいように思う。
とすると、
>>83 は実際には規格外の動作ということですか?
コンパイラはIntel Fortran 10.1です。(確かにintelはけっこう拡張してるからなぁ・・・)
メンバ変数みたいな真似をmoduleでやらせようかと思ってたんですが、
この方法じゃ駄目ぽいですね。そういうオブジェクト指向的なことって
Fortran2003をちゃんと勉強すればできるのかしら・・・?
91 :
デフォルトの名無しさん :2009/03/16(月) 22:18:43
サブルーチンがたくさんあるプログラムを作る時はmoduleよりもinterfaceの方が良いですか? module間で相互にmoduleを参照(use)するとエラーが出て、悲しい状態です。 誰か教えてください。 ちなみに、moduleについて詳しく書いてある本があればそれも教えてください。
そのエラーがどんなものか分からないことには何とも・・・ 確かにmoduleはよく考えて使わないと面倒な目に合うな 個人的にはFortranやるなら、あんまり細かく部品化しすぎないほうがいいと思う
>>91 module の前方参照のみしか許していないコンパイラーが多いよね。
ソースの前方に書いたmodule だけをuse するようにしてごらん。
95 :
91 :2009/03/21(土) 12:36:18
返事遅くなりました。すんません。 >92 サブルーチンは使いまくってます。 サブルーチンがないと不便です…。 >93 前方参照はmoduleをprogramより前に書けってことですよね? moduleは別ファイルです。こんな感じになってます。 ファイルa.f90 module a use b contains subroutine foo ... end module a ファイルb.f90 module b use a contains subroutine bar ... end module b わかりにくい質問ですんませんでした。 >94 コンパイラはifort(ver.11)です。 inteface使えよって意見は出ないもんなんですね。 みなさんはサブルーチン使うとき、どうやってるでしょう?
>>91 >module間で相互にmoduleを参照(use)する
相互にuseするのって不可能じゃないの?
コンパイルするときにuseするモジュールの.modファイルが必要だし。
というか、fortranに限らず相互に呼び合うようなのは概念的に許されるのかな・・・?
もし許されるとしても、混乱の元だろうし非常にまずいような・・・・
>inteface使えよって意見は出ないもんなんですね。
>みなさんはサブルーチン使うとき、どうやってるでしょう?
interfaceの主な用途としては、fortran77で書いた外部サブルーチンを
そのままいじらずに、より安全に使いたいとき、などじゃないかな。
形状引継ぎ配列や割付け配列などの機能を使いたいときは、
いずれにしろそのサブルーチンの修正が必要になるので、そのときは大人しく
モジュールで囲ってモジュールサブルーチンに変更すべきかと思うが。
97 :
91 :2009/03/22(日) 10:19:29
>>96 ありがとうございます。
相互に呼び出さないようにするためにはツリー構造を考えないといけないですね。
ちょっと面倒くさい気がします。
結局>>91のエラーは解決したの?
99 :
91 :2009/03/24(火) 08:27:42
相互参照しないように書けば、エラーは消えます。 ただ、皆さんがどういう風に対応してるのか知りたかったのです。 お相手ありがとうございました。
>>99 オレ、一個の超特大module にしている。
>>96 めったに使わんが、関数なんかを引数にする汎関数?っぽいサブルーチンなんかでは
インターフェースを書いて引(関)数を指定せざるおえないな。
77時代はExternalを書いておけばよかったが、90だとInterface書かないと文句言われる。
F2003では、Methodの記述用にPROCEDURE(..)宣言子が新設されたので、
場合によってはインターフェース代わりに使えるのかもしれないが。
102 :
デフォルトの名無しさん :2009/03/28(土) 12:21:25
なんか、副プログラムの引数やら型を渡す儀式のパターンが増えちゃったよね。 並列計算を意識してか想定しているシステムの種類を 増やさないといけない関係かも知れないけど、 男は黙ってインライン、とはいかないのか。
ちょっと便乗して質問します。今、不便を我慢して使ってきたcommon文を全部module文にしようかと 思ってるんですけど、何か気をつけるべきことやありがちな落とし穴とかありますかね? もちろん自分でテストはしますが、後の運用性とか未然にバグを防ぐとかでもっと上手く出来そうなら 指摘してもらえますか?例えばこんな感じです。 PARAMETER (MNM=5000,MNC=100) DOUBLE PRECISION CC(MNC) COMMON /CELL/ CC,CG(6,MNC),NCX,NCY COMMON /MOLS/ NM,PP(3,MNM),PV(3,MNM) ってのが使用される各サブルーチン先頭に書いてあったのを ↓ module mnpara PARAMETER MNM=5000,MNC=100 end module module cell use mnpara DOUBLE PRECISION CC(MNC) real CG(6,MNC) integer NCX,NCY end module module mols use mnpara real PP(3,MNM),PV(3,MNM) integer NM end module と、mainの前に書いて、各サブルーチン中でuse cellなりuse molsなりと。 double precisionと型宣言の扱いがこれでいいか良くわからんのですがこれで大丈夫でしょうか?
微妙に便乗して質問します。今、common文をmodule文に書き換えようとしてるんですが、 もちろん書き換えた後テストはしますが、もっと上手く出来るこれはよろしくないとかあれば指摘してください。 PARAMETER MNC=8000,MNSP=2,MNS=5 DOUBLE PRECISION COL(MNSP,MNSP),MOVT COMMON /SAMP / COL,NCOL,MOVT,SELT,SEPT,CS COMMON /CELLS / CC(MNC),CG(3,MNC),IC(2,MNC,MNS) というのが各サブルーチンの先頭にあったのを module mnpara PARAMETER MNC=8000,MNSP=2,MNS=5 end module module samp use mnpara DOUBLE PRECISION COL(MNSP,MNSP),MOVT,NCOL real selt,sept,cs integer ncol end module module cells use mnpara real CC(MNC),CG(3,MNC) integer IC(2,MNC,MNS) end module と、mainの前に書いて各サブルーチンの先頭でuse samp;use cells でよろしいでしょうか?double precisionと型宣言の扱いがこれでいいか少し不安ですが… よろしくおねがいします。
すみません…なんか書き込み失敗したと勘違いして連投してしまいました。 申し訳ないです。
>>103 COMMON変数は、EQUIVALENCEっぽいというか、名前ではなく順番で、つまり
メモリーの位置で対応しあっているので、サブルーチンごとでCOMMON変数の名前が
変えてあると本体の変数名も直さねばならず一気に面倒になる。
あとから変数の受け渡しが必要になったらしくて、いくつかのCOMMON文の末尾だけに新しい
変数が加わっていたりするのも昔のプログラムでは良くあること。
一括変換で機械的に直せないことがままある。
幸運を祈る。
107 :
104 :2009/04/02(木) 05:02:49
>>106 回答有難う御座います。
すみません、common文が内部的にどう働いてるか実は良く
分かってないので的外れな質問かもしれませんが、
もしいくつかのcommon文の末尾だけに変数を書き加えて、
同一名のcommon文のサイズが違ったとすると、例えば別のcommon文の要素とかを
書き換えちゃいそうな気がするんですけど、そんなことしてまともに動くんでしょうか?
幸いそういうのは今のところ無さそうなんですけど、純粋に知識として気になって。
「動作は未定義」じゃないのかね。 ま,includeすればそんな心配もない訳だが。
109 :
104 :2009/04/02(木) 07:12:26
すいません、未定義と言うのはどういうことでしょうか? 規格上定められてないのでどうなるかはコンパイラ等に依存するってことですか? それともう一つお聞きしたいんですが、そのサブルーチン内で使ってない moduleを呼び出した時の弊害ってあるでしょうか?無駄に呼ぶと速度とかに影響します?
>>109 変数の数が違うとフツーは警告を出すだろうが,エラーになるコンパイラもあるかもね。
なんにせよ,そんな間違いをしない方法を考えた方が有益だろよ。
moduleの方は判らないなぁ・・・
>>109 無名COMMONでは、各COMMONブロックごとのサイズは異なっていい。
(その代わりBLOCK DATA文で初期化できない)
文法書を読めば書いてある。
名前つきCOMMONはすべて共通の大きさでなければならないのだが、
名前つきCOMMONでもサイズが違っているプログラムはごろごろ転がっていた。
昔はハードウェアもOSもてんでんばらばらだったので、すべては処理系に依存する。
112 :
デフォルトの名無しさん :2009/04/02(木) 14:42:53
>>111 たいていのfortranコンパイラは警告を出すけど、そのまま作業を続けるよね。
関係ないけど、アメリカのSGIが潰れてしまった・・・。
alphaマシンがまた一つ・・。
SGIって伝統的にMIPSじゃなかった?
>>113 だな。
2ch的にはアルファは法則発動であぼーんと言うべきか。
>>113 だね。
片手間?で「Alpha始めました」の張り紙を出したところが出始めは案外評判が良くって、
注力しはじめたところでAlphaが本領を発揮してアボン。
ifort ってバージョンの9あたりから、シェフお薦め最適化オプション -fast 付けるより
デフォの方が早かったりしない?
自分のコードが変なだけかもしれないけど、そういうケースに気付くようになった。
116 :
115 :2009/04/03(金) 03:54:48
sgiの場合AlphaよりはItaniumが疫病神か
疫病神ヒドスw Altixも終わりかな?
>>115 デフォってオプション何もなしってこと?
-fastは-O3も含んでるけど、そんなことあり得るのかな?
>>102 いや、悪くないんじゃ?w>男は黙ってインライン
いずれにしろFortranは速度も優先せざるを得ない以上、他の言語のように
抽象化しまくって直交性高めまくるやり方を期待するのは土台無理というもの。
やはりFortranerに一番必要なものとは「漢気」である。
>>118 ,115
-fast = -O3 -ipo -static
が基本オプションかな?微妙にifortのバージョンで変わるみたいだから、
シェフお薦め、というのはそうだな。ip(o) が混じるから副作用があるのかも。
121 :
120 :2009/04/04(土) 03:23:26
ipoはインライン促進だからあまり副作用の心配はいらないか。 -O3 は unrolling促進やら含んだとおもうし、-staticも何か悪さする場合もありそうな気もする。 -fast -unroll0 で あんろーりんぐ無しの最適化を試してみるといいのかも(順番大事だよ)。
あ、インライン使うときは、リンクするライブラリはインテルアーカイバ(xiarだっけ?)で作ったほうがいいかも 何にしても-fastで遅くなるなんて悲しすぎるから、ちゃんと見直したほうがいいかと
123 :
デフォルトの名無しさん :2009/04/04(土) 07:55:36
version9あたりからデフォ(-O2)が速くなった気がするのは気のせいかな?
static と dll でどっちを選んだほうがいいの? おすえて 昔派の漏れは static の方が安心な気がするのだが、最近のデフォは dll だっけ?
125 :
デフォルトの名無しさん :2009/04/04(土) 15:05:45
ちょっと前はstatic推奨だったけどな。なんかバージョン毎の違いも大きそう。 自分が経験した例では、バージョン8くらいまでは -ftz つけると速くなったけど 9以降だと遅くなった、こととかかな。 intelも工夫してるんだろうけど、使う側もいろいろ試してちょ、という事か?
>>123 -O2ってデフォでかかるの?
>>124 dllのほうが一般に速いという話を聞いたことが
ifort --help かけると、 -O0 disable optimizations -O1 optimize for maximum speed, but disable some optimizations which,,,,,, -O2 enable optimizations (DEFAULT) -O3 enable -O2 plus more aggressive optimizations that may not improve -O same as -O2 と出るね。linuxに入ってたversion9.1ではこうだった。
というわけで -fast や -O3 つけたらかえって遅くなっても 製造元の想定の範囲内って事で気にしないのが良いのかも知れないね。
>>127 ほんとだ、v10.1でもそうだった
thx
130 :
デフォルトの名無しさん :2009/04/05(日) 04:50:08
g77 は最適化のレベルがたくさんあった気がするけど、 インテルはあっさりしてるよね。ゼロ・松竹梅の4つ。 マクドナルドと吉野家くらいメニューが違う。
>>130 細かいオプションとかカテゴリーの違うものを比較してないか?
今はgfortranだっけか 完全フリーでgnuより速いコンパイラって出ないもんかね
133 :
130 :2009/04/06(月) 07:50:51
>>131 ごめんよ。書いた後でこりゃ変だと思ったよ。
>>132 出ないものかね。でも、
いまのintelのポリシーだと、個人で商用目的でFortran/Cを使う人以外、そこそこ満足だからね。
フリーな奴の開発プロジェクトを立ち上げたり維持するだけの理由があまり無い気もする。
なんて言っている大学関係者はたいてい犯罪者だけどな Note that academic use of the products does not qualify for a non-commercial license. Intel offers heavily discounted licenses to academic developers through our Academic Developer Program.
135 :
133 :2009/04/10(金) 02:07:44
>>134 ちょっと知ったかぶり、というか早合点、というかまぬけ。
それ、大学関係者じゃ自明じゃね?
まわりの奴は知らないだろうと得意がる子供は・・・
まぁもちけつ・・・良スレで喧嘩はいかんよ 実際使っちゃってる香具師は少なくはないだろう 内部告発とか食らうとやばいかも?w ちなみにAdobeとか違反使用に厳格なところは大学に何億って賠償請求することもある Intelはあんまそういう話を聞かないが、寛容なのかなw
133だけど・・・なにこれ?ひどす。
134のはまっとうな指摘だと思うよ。
いろんなソフトでアカデミックパック版があるしフリーソフトが当たり前にあるから、
特に大学に長くいる人はなんとなくライセンスに鈍感というか、
タダであることを当然と思うところがあるから。
>>136 フリーでつかって学習して潜在的なユーザーが増えると良いな、という事だろうけど、
論文に使った計算と、購入検討のための試運転の区別が付きにくい、という事はあるから
なかなかintelが積極的にライセンスチェックするのはコスト的にも難しいのかも。
というか計算結果にコンパイラ毎のクセが出るようでは困るw
それこそ内部告発でもなければintelも動けないだろうね。
その点あたりまえだけど純粋なソフト屋はその辺もっとシビアで迅速だよね。
138 :
デフォルトの名無しさん :2009/04/11(土) 00:37:18
質問よろしいでしょうか?? 大学に入って初めてfortranにさわりました。 Frotran77を使用し、ソースプログラムは何とか書けましたが、次の作業の コンパイルというものがよくわかりません。 OSはLinuxを使用しています。何か別のソフトをインストールして作業しないと いけないんでしょうか? よろしくお願いします。
>>138 普通はg77とかgfortranとか入ってるだろうけど
学校で使ってるのなら、まずは教官に聞け。
どうでもいい話かもしれんけど、コンパイラの開発ってどれくらいの規模と金かかるもんなんだろ ハッカーな天才を何人か高給で雇えばいっちょ上がり、ってわけでもないよね?
普通のソースコードを読んで、特定のマシンでとにかく動けばいいレベルの コードを吐くだけなら、学生が1ヶ月かければ作れる。 仕様の細かいところまで厳密に対応し、高度な最適化をかけ、複数の ターゲットに対応し、etc... となると複数人で継続してメンテナンスされる プロジェクトになる。
質問させてください。fortran90ソースをpgf90 でコンパイルしています。 write (*, 20) ( A(k),k=1,10) 20 format('A=',(' ',10i2)) 例えば、上記のように、write文でdo形反復を用いて、配列Aの要素十個を 横並びに書き出すことは出来るのですが、 書き出したい要素数を n としたとき、n個を横並びに書き出すことは出来ますでしょうか。 下記の方法では、出来ませんでした。 write (*, 20) ( A(k),k=1,n) 20 format('A=',(' ',ni2)) よろしくお願いいたします。
143 :
デフォルトの名無しさん :2009/04/12(日) 13:40:06
この板にあるもう一つのFortranスレで似た質問を見た気がするから捜してみて。 多分それと違う答は・・・・ character*4 fmtstring (中略) write(fmtstring,'(i2.2,''i2'')') n write(*,fmt=fmtstring) ( A(k),k=1,n) かなあ。最初の文字列定義はプログラムの頭の方でしてね。 2行目でformatの中身を文字列で指定して 3行目で使ってる。でもこれダメなシステムもあった気がする・・。 intel と 富士通ではOKだったけど、pgfでは果たしてどうだろうか?まあ試してみて。
144 :
142 :2009/04/12(日) 16:42:18
ご提案ありがとうございます。 その方法を試してみましたところ、 コンパイルに文句を言われることは無くなりました!! しかし、セグフォルトが出たので、これからデバッグかんばリます。。。
その配列aに入っている値は二桁以下の整数(または一桁の負の整数)って 確定しているの? i2だと二桁までだからもし3桁以上の数字が来ると、 そこで**とか出るだろうけど、どうも一部のシステムでは そこでsegmentation faultになることもある。 なので特段の理由がなければi9くらいに めけんとうで大きめな桁数にしとくと吉。
146 :
142 :2009/04/12(日) 18:35:39
はい、確かに2桁以下とは限りませんでした。 i9くらいにして、charactor の宣言も、それを許容できるくらいに取っていれば安心ですね。 ありがとうございます。 セグフォルトは他で出ているようです。 実は、ifort 用のソースをpgf90に書き換えているのですが、とても難航しています。 何かご助言を頂けないでしょうか。
147 :
デフォルトの名無しさん :2009/04/12(日) 22:15:49
本の書いてある通りにプログラムを組んだが、どうやってもランタイムエラーになってしまう。 誰か教えてほしい。 integer fulls,maxval,minval,sum,N,P real avr character subjct*30,FNAME*20 read(5,*) FNAME open(1,FILE=FNAME) read(1,*) sucjct,fulls N=0 maxval=-9999 minval=fulls sum=0 10 read(1,*,END=20) P write(6,*) P if((0.le.P).and.(P.le.fulls)) then N=N+1 sum=sum+P maxval=max(maxval,P) minval=min(minval,P) else write(6,*)'Incorrect data! ignored' end if goto 10 20 close(1) end 出典は、原田賢一 、2007:Fortran77プログラミング、サイエンス社 PP57
gfortran (mingw build, ver 4.4.0) で -fno-automatic が効いてないみたいなんですけど これって既出ですか? 以下再現するコードと実行結果です。 C------ a.f ------ program main call test call test end program main subroutine test write(*,*) i i = i+1 return end C----------------- > gfortran -finit-local-zero -fno-automatic -oa a.f > a 0 0 他のコンパイラ(g77 や ifort -save)だとちゃんと 0 1 と出力されます。
>>147 6行目
read(1,*) sucjct,fulls => read(1,*) sucbct,fulls
150 :
149 :2009/04/12(日) 22:50:40
間違えた subjct ね
151 :
デフォルトの名無しさん :2009/04/12(日) 23:39:12
>>150 ありがたい。しかし、そこを直してもランタイムエラーが発生する。
コンパイラはSalfort FTN77だが、問題ないだろうか。
また、
>>147 で示した書籍で勉強した人はこの例題をどうしたのか良ければ教えてほしい。
>>151 入力ファイルと、エラーメッセージがないと教えようがないです
>>148 実はIntelFortranのwin32のdebug mode でも同じ問題がずっと存在しているw
releaseやx64ならおk。漏れはx64メインなのでバグレポートしてないw
ごめんな、スチーブ
スチーブww
>>151 >>152 のいうとおり、入力データファイルや、エラーメッセージを見ないとなんとも
答えようがない。テキストも持ってないし。
ただ、エスパー的に推測すると、入力ファイルの最後の行で数値データの
最後で改行していないためだろう。処理系によるが、空行がないとEND=nnに
引っかからない。
あと、
>if((0.le.P).and.(P.le.fulls)) then
これは多分 (0.ge.P) ではないかと思われる。
入門テキストであることをかんがみるに、科目ごとの平均点を求めるプログラムだろうが
点数が負のテストは少しばかり酔狂すぎる。
156 :
153 :2009/04/13(月) 02:03:34
ごめんw
>>148 の逆の問題だったかもしれない。
Automaticで0 clear を選択してもクリアされない。
157 :
148 :2009/04/13(月) 20:49:55
158 :
デフォルトの名無しさん :2009/04/13(月) 22:32:07
>>152 >>155 >>147 だが動かすことが出来た。読み込むファイルの場所を間違えた場所に保存して
いたのが原因だった。終わってみれば単純なミスで申し訳なく恥ずかしい限りだ。
ただ、自分としてはFortranについて多くのことを学べた。ありがとう。
初歩的な質問かもしれませんが・・・ Intel Fortran+Visual studio2005でOpenMPを利用して ライブラリなどがインストールされていない環境でコンパイルしたプログラムを走らせたいのですが 「libiomp5md.dllがありません」と出てしまって、走らせることができません。 ライブラリのない環境で使いたいとき、どのようにコマンドを指定すればよいのでしょうか。
ライブラリをstaticにリンクすればいいんでないの?
>>148 gfortranはなんか色々変わりすぎてて気に入らないので、自分はもうしばらく手を出すつもりはないなぁ
>>156 0 clearって-zeroオプションのこと?
-zeroはsaved属性でかつ初期化されてない変数を0にするものだよね
-automaticはローカル変数をスタックに置いちゃうから、-zero付けても初期化されないと思う・・・多分
>>157 -gってデバッグ関係だよね?
save効果もあるんだ
>>161 >0 clearって-zeroオプションのこと?
>-zeroはsaved属性でかつ初期化されてない変数を0にするものだよね
>-automaticはローカル変数をスタックに置いちゃうから、-zero付けても初期化されないと思う・・・多分
いや、32bit debugの時だけ変数0初期化が効かない。releaseではzero optionの有無で
0が出るか、ゴミが出るかが変わる。
最近、文法書を読んでいて知ったのだが、変数宣言時に初期値を与えると自動的に
SAVE属性になるそうな。漏れは、automaticなら、なんとなく毎回宣言時初期値に
初期化されるものだと思っていたよw
>>162 >いや、32bit debugの時だけ変数0初期化が効かない。
>releaseではzero optionの有無で0が出るか、ゴミが出るかが変わる。
じゃあやっぱりバグかぁ
>変数宣言時に初期値を与えると自動的にSAVE属性になるそうな。
そうそう、これ意外と盲点だと思う
今後、数百・数千CPU以上の並列計算になると、ファイル数を並列数分だけ分割するのは 管理上煩雑なので何とかしたいところですが、何か良い方法はないでしょうか? 例えば、今まで並列数分だけ分けていたファイルを1個のファイルにまとめ、 Fortran内でデータの場所(アドレス)を指定することで直接アクセスする ようなことができれば、かなり便利だと思うのですが。
>>164 DIRECT ACCESS でだめなのか?
サイズが一定でないと困るが
167 :
164 :2009/04/19(日) 20:21:55
>>165 directアクセスの存在を始めて知りました。
レコード長を把握しておく必要はありますが、効率は良さそうですね。
実際の使い方としては、recl指定子の値をデータの最小サイズで与え、
読みたいレコードの位置を逆算してread文のrec指定子に与える、
という方法で合っていますか?
>>166 なるほど。ということは、Fortranの実装とは別の機能を用いる方法もある、
つまりやり方は色々ある、ということでしょうか。
168 :
164 :2009/04/19(日) 20:54:59
>>167 の補足ですが
>recl指定子の値をデータの最小サイズで与え、
と言うより、そのファイルを作ったときのwrite文のreclと同じ値をread文のreclに与える、
と言ったほうが適切でしょうね。
あと、使っていて気づいたことなのですが、statusを指定せずにopenしてwriteする場合
sequential・・・いったん元のファイルを消した上で書き込み
direct・・・ファイルのレコード位置に対する書き込み
という違いに気をつけないといけませんね。文法的に正確に書けば
sequential・・・強制的にstatus='replace'
direct・・・ファイルがあればstatus='old'、なければstatus='new'
でしょうか。
169 :
デフォルトの名無しさん :2009/04/20(月) 17:42:55
ちょっと質問というか確認 ディスクがフラグメンテーションしてる場合、データの分断を許すような 実装だと、ディスクへのアクセスはアドレスのテーブルみたいのを参照 しながらじゃないと原理的にできないよね フラグメンテーションしててもデータの分断を許さないような実装なら、 ディスクスペースの使用効率は下がるかもしれないけど、テーブル参照が 不要になるからアクセスが速くなるはず・・・だよね? 速度を要するスパコン用のファイルシステムって、そういう実装なのかなぁと想像・・・
>>167 ダイレクトアクセス知らなかったのか。
>直接アクセスする
とか書いているから知ってるかとw
昔の映画のコンピュータで磁気テープがグルグル回っているのはダイレクトアクセス
ファイルを読み書きしているんだべなぁ。
テープが 今で言う、ディスクとメモリの両方を兼ねてたからね。 ほんのちょっと前にFACOMのやつにテープはめるのをした。 あれ、テープのはしっこを挿入口に近づけると空気で吸い込んでくれるのね。 人間の手で全部とりまわさないといけないのかと思ってたよ。
172 :
164 :2009/04/22(水) 15:52:56
>>170 不勉強故、失礼しました。
ところで、磁気テープというのは今も使われているものなのでしょうか?
今、20半ばの院生ですが、テープというのを見たことがありません。
173 :
デフォルトの名無しさん :2009/04/23(木) 01:43:48
fortranで円やら球を離散化?させたい。 円の場合 function X(a) X=cos(3.14*a/360) end function Y(b) Y=sin(3.14*b/360) end こいつを回せば、円をつくることはできる。でもXは小数点の数字になっているよね。 でもやりたいことは、2次元配列を作成して、F(x,y)のx-yのメッシュの中で 円を作成するには、x-yは整数である必要がある。どうすればいいの? わかる人いますか? この円・球構造について、拡散方程式やら偏微分方程式を解きたいと思っているんだけど、 こういうことってできますか?
すなおに極座標なり円柱座標にするがよろし
>>173 メッシュが正方格子でなければならない理由はあるんかいな?
Yesならメッシュを細かくするしかないなぁ・・・
節点座標値が整数でなければならない理由はないと思うょ
球や円を特徴的な構造として持つ系にカルテジアンを無理矢理持ち込むのは無理があるにょ ギザギザがでるし、30度とか45度回転させた初期値境界値で同じ計算すると結果が結構違うにょ。 査読受けたら絶対そこを突っ込まれるにょ。 んで満足いく事例を出せなかったらそこで終わりにょ。 学部生より上なら極座標なり175の言う通り非構造格子にしてきちんとするのがいいにょ。 学部生なら、卒研としてならまあ許されると思うにょ。・・・Fortranと関係なかったにょ。
>>173 どうしても直交座標にしたいなら、かなり細かくメッシュを区切って、
計算結果にある値をかけて、整数にするとか。
新しく買ったCorei7で計算させたら、滅茶苦茶速くてびっくりした。
PenMのノートで10分かかる計算が1分で出来て、しかも8個同時に走らせても余裕。
64bitOSを積んだから、というのもあるのかな。
>PenMのノートで10分かかる計算が1分で出来て、 まあ、これはそうだろうなあ。 >しかも8個同時に走らせても余裕 へえ。よさそうだね。 余裕、というのは「一個の時のまあ8割くらいのスピードで8個とも動く」くらいなの?
179 :
デフォルトの名無しさん :2009/04/24(金) 16:38:50
>>175 メッシュが正方格子でなければならない理由はあるんかいな?
教官から貰ったコードが正方格子のだったけど、
変更できない、とかかな?
そもそも173のやりたいことがいまいちよくわからない。
Fortranとは関係ないし、ここまでかな
>>178 特に並列化をしていない(というよりも、並列化がうまくいかなくて結局諦めた)ものを走らせると
大体16%ぐらいのCPU使用率になるから、
8個ぐらい走らせると100%使い切るようになるからね。
この使用率からすると、たぶんそれぞれ8~9割で動いているといったところかな。
うまいこともっと最適化できないかな・・・。
>>180 物理CPUは4個だろうから、よほど例外的な場合でなければ多分4つより大だと帰って遅くなるだろう。
178です
>>180 ありがとう。
少なくともOSが認識する使用可能なリソースはフルに使い切れるんだね。
>>181 Xeonの2コアが4つ乗ったマシンでOpenMPを走らせると
きれいに8倍になってくれたけど、これとはまたいろいろ設計が違うんだろうな。
>>181 よく考えたらそうだよなあ…
実際時間を計ってみたら、8個計算の時間 / 2 > 4個計算の時間だし。
ただ、実際には数百から数千個計算するし、それぞれ条件が違うから時間もバラバラで、
その待ち時間を埋めるために、まとめて計算するほうが速かったなあ。
プログラム内でうまく並列化をしてフルに使い切れればいいけれど、なかなかうまくいかないんだよな…。
OpenMPをコマンドを入れたら、かなり遅くなったし。
>>183 なるほど~。
どちらかというとたくさんある計算をぼんぼん
放り込んでおける、事がメリットなのかもね。
そうなるとqueueの管理の仕方がみそ?
>>183 Corei7は、物理4コアをハイパースレッディングで見かけ8コアにしている。
純粋に計算などが重い場合ハイパースレッディングは足を引っ張るだけ。
そのばあいは4スレッドで動かすほうがいい。
MKLのLinpackのBenchmarkをやってみるとどのくらい遅くなるかわかる。
OpenMPのオプションでスレッド数を物理コア数に合わせるようにすると本来の力を発揮する。
あるいはBIOSでハイパースレッディングを切るとかいう手もある。
ただハイパースレッディングが有効な場合もあるので、個別の事情に依る。
自分で試すしかない。
MPIなりOpenMPで4並列のジョブを放り込んだばあい、 ちゃんと1プロセス/1CPUにふってくれるのかな?
>>186 いや、なんか環境変数にそれなりの指定をしないと、1スレッド1物理プロセッサに
必ず行くとは限らないので遅いまま。
OpenMPのマニュアルの環境変数のところを読めば書いてあったはずだが、
詳しくは忘れたw
なるほど・・・。 どちらかというと、dplace や mpirun みたいな並列実行の環境を調えるソフトの とりあつかう領域だね。dplaceだと dplace -c1,3,5,7 かな?実機でもってるわけでもないし、いまマニュアルが見れないからわかんねw HTがあると並列しながら、ふつうの文房具的にPCやWSを使えるわけだから 使い方次第では結構いいかもなあ。
冗長な部分があってもいいから現在使っている配列の全てをバイナリに書き出して計算の中断ファイルを 作りたいんですけど、書き出す配列を全部列記する以外に楽な方法ってないでしょうか?
>>189 もう一回計算しなおせ!w
データを後生大事に取っておくのは演算コストが高かった時代の名残。
むろん演算量にもよるがw
>>189 目的がよく分からないんだけど
コード中の全ての配列をはき出すってこと?
>>189 行列がスパースなら,非ゼロ項を書き出すことにすれば,ちょっとはマシな気がする。
>>189 配列の全ての成分を書き出せば良いのであれば
integer a(1:10000)
real b(1:100,1:100)
write(10)a,b
とかではダメか?
>>190 デバッグとかあるし。
大型計算機とかだと、1計算の時間上限があるからね。
再開するのに必要な情報を全部ファイルとして書き出す選択肢は
持っていた方が良いと思うにょ。
>>193 それがいちばんだね。
書式指定無しでファイルにたたき落とす
違うシステムでは役に立たないけど、メモリの内容をそのままファイルに落とすので
書き込みも読み込み+計算再開も速い。
書式付きもできるけど、めちゃくちゃ遅いし。
>>194 デバッグ目的以外で、メモリの中身を全部ダンプする必要性が分からないんだが・・・
今時の計算は反復計算などの単純なループ部が計算のほとんどを占めてて
ループ開始前の前処理なんて全体から見れば知れてるわけで、
次回リスタート用のためにわざわざメモリのスナップショットを取る的な発想は今時ないでしょ。
メモリとストレージの速度差が開く一方の今日じゃなおさら・・・・
理由は194が最初に書いてね? 195はあまり大きな計算はしたことがないんだろうな
197 :
189 :2009/05/09(土) 15:11:48
遅くなりました。
あー…書き方があいまいですいません、答えてくださった方ありがとうございます。
えと、粒子法的計算なんですけど、191さんがおっしゃっている通りです。
コード中のすべての配列をはきだしたいです。
193さんのやり方は当然わかりますけど、それだとwriteの後に吐き出したい配列を
列記しないといけませんよね。そういうの無しで全配列をばーっと吐き出す方法ないかな、
と思ったわけです。やっぱ使う配列をコツコツ列記するしかないみたいですね。
>>195 非定常計算なんで状況によっては計算途中の段階から少しだけ条件を変えて
計算したいとかあるんですよ。正直にやったら一週間近くかかるので。
>>197 質問がひどすぎw
まぁベンダー拡張命令でメモリー全ダンプみたいなことが出来る機種もあった気がするw
199 :
195 :2009/05/09(土) 16:47:04
自分には
>>189 の理由がいまだに分からん・・・(別に分かんなくてもいいけどさ)
たしかに、スパコンでは数日~1週間程度の計算しかしたことない。
大きい計算とは言えんか。
スパコンのジョブってたいてい時間制限が数時間のオーダーだから、
例えば30000ステップ計算したいとしたら3000ステップのジョブを
10回投げるってのが普通だよな。
粒子法はよく知らないけど、格子点はどんくらいなの?
200 :
195 :2009/05/09(土) 16:49:29
あ、粒子法ってメッシュないんだっけか? 粒子数だっけ?
背景場を途中から変えた計算をしたいのかな? 普通は計算再開に必要な変数の数(配列の大きさではないよ)って知れてるよね。 粒子法なら、粒子の位置・速度と経過時間くらいか。 あとはiterationのプロセス毎に計算する量や座標系のように 再生成に計算量のかからないものがほとんどだろうから、 それをとっておく必要はないし。 ふつうに193のやり方で落とせばいいんじゃね?たいした手間でもなし。 ところで、ダンプして落としたとして、変数の変更はどういう風に再開時に反映させる つもりだったんだろうか?
>>199 同意。細切れ計算するときに継承すべき情報はあるけど、ダンプする理由はないやね。
ふと、189の「配列全部」は別にダンプではないのでは、と思ったけどオイラの勘違いかな?
読み返すと、「ダンプ」を最初に使ったのは195さんだw
204 :
195 :2009/05/09(土) 17:17:34
ダンプっていうのは大げさでしたなw イメージ的に使ってしまった
無料のfortran77向けのコンパイラで、高速なものはありますか? 用途はCFDです。 まあ趣味なので大きな計算は必要ないのですが。
fortran歴1週間の質問です 論理型を整数型その他に変換できますか? 例えば、いくつかの言語では (a>b) 等とすると0または1が得られますが これと同等なことをFORTRANでも行いたいのですが方法がわかりません 無理ならすんなり諦めます
>>206 一般的な回答としては、できない。
不可能ではないという意味では、IF THEN ELSE でやれば出来る。
意図しているイメージに一番近いだろうと思われるのは、TRANSFER関数で型変換をすること。
しかし、FORTRANの規格では論理型の内部状態を定義していないので
0/1に投影できるかは運しだい。普通は0/-1が多い(真:ビット全部0と偽:ビット全部1)。
>>207 早速ありがとうございます
何となくですができました
logical lonlon real a, b a=1.0 b=2.0 lonlon = (a .GT. b) write(*,'(i3)') lonlon なるものをつくると、 最後の行で型が合わないと怒られる 0がでてくる 1がでてくる -1がでてくる、 の4パターンあったw 危険だw
g77のよく使う高速化のためのコンパイラオプションを教えてくださいませんか。 それかコンパイラオプションをまとめているサイトないですか? gccのまとめを見ればよいのでしょうか?
>>206 どういう用途?
論理型が用意されてる言語なら、特に理由がない限りそういうマネはやめたほうがいいかと
シェルスクリプトレベルならよくやるけどさ
でも、コンパイラのドキュメントしっかり読んで全部の仕様を熟知してる人なんて、ほとんどいないよな こんなオプションあんだ・・・でも何に使うんだろ、ってのばっかだ俺w
論理型と整数型の混用は、非常に有用な場合もないではないけど、 基本的にはやるべきでない。
ちょっとインチキして logical:: L(1) L = (2.0 < 1.0) write(*,*) count(L) L = (1.0 < 2.0) write(*,*) count(L) とか
>>216 3つの条件abcのうち2つ以上が真なら、という場合に、
a = 条件式
b = 条件式
c = 条件式
if (a + b + c >= 2) ...
とか。Cの場合だけど。
後でメンテする時、無駄に手間食うからそういうのやめてくれ~
1960年代のおばあちゃんの知恵というかライフハックw風のプログラムだな。
>>218 4つの式が近くの行にあればいいけど、すごい離れた所にあるといろいろ嫌だよね
221 :
デフォルトの名無しさん :2009/05/22(金) 20:21:01
LOGON TSS
Intel Fortran 10 を使っています。 ifort独自文法のform='binary'でファイルを開いてデータ出力しています。 そのファイルはC言語のファイルフォーマットが公開されているんですが、 unsigned int となっている部分をifortで出力する方法がわかりません。 この部分だけC言語で記述して呼び出す形ならできそうな気がしていますが、 Fortranだけで完結させる方法ってありますか? アドバイスよろしくお願いします。
>>223 32bitのunsighned int?
読み込みのほうはINTEGER*4 でうけて、それをINTEGER*8にTRNASFER関数で
適当な位置にコピーするか、出力サブルーチンを作って負数の場合は
INTEGER*8でUINTの場合の数を求めて出すという方法が考えられる。
倍精度の変数宣言だけど、 real(8) a double precision a どっちやねん、と思ってた。 先日規格を見たら後者だったので、ウヒー! 今後は全部後者で統一する。行が長くなって、チョトいや。
>>225 どっちでもいい。後者は昔風の書き方。
今はむしろ前者が主流だと思う。
>>227 それは、規格違反ということを意味しているわけではない。
KIND種が規格で決められていないためにベンダー依存になっていることを
問題視しているのだろう。
kd = SELECTED_REAL_KIND(14) とかで、8などの定数べた書きをやめてkdなどに
すれば避けられる。
規格の整合性としては REAL ([KIND =] n) の方が統一的でいいとおもう。
4倍精度が大概のコンパイラでサポートされつつある現状を考えると、REAL(n)の
形式にそろえておいたほうが将来的にものぞましいのではないかと思う。
229 :
223 :2009/05/23(土) 20:23:06
>>224 回答ありがとうございます。
詳しくないですが、32bitです。
各bitにどうデータが並んでいて、、、ってのを学ばないと難しそうですね。
ちょっとがんばってみます。
>>227 むしろreal*8が普通だと思ってた。double precisionはむしろ非推奨って話も聞いたことあるぞ。
>>227 のnagのページは全部鵜呑みにして良いのか甚だ疑問だわ・・・
つーか、この問題の責任は100%規格にあるだろう。規格作ったやつ出てこい!
>>228 module xx
integer, parameter :: kd_re = selected_real_kind(16)
:
programm yy
use xx
real(kd_re) a
みたいな感じかな? 一理あるね。
>>230 JIS X3001-1に
『DOUBLE PRECISION型指定子は、組込みの
倍精度実数型のデータ要素を宣言するのに用いる』
とあるから、非推奨ってこともないだろ。
詳しくは覚えていないが・・・・
FORTRAN66までは倍精度宣言は DOUBLE PRECISION
だけだったのだが、その後の流れで FORTRAN77では REAL*8
Fortran90でREAL([KIND=]8)の形が出てきて、だんだんと
REAL([KIND=]8)の形に統一しましょうという流れだと思う。
>>230 Fortran90策定の頃は、ベンダー毎にアーキテクチャーも数値フォーマットも
文字コードもバラバラだったのでこのくらいは許してやってくれ。
やっぱKIND使った方がお行儀がいいのかなぁ 書き直すのマンドクサイっす ・・・あんま移植性に拘りすぎるのもどうかと思うけどね。どうせみんなインテ(ry
FORTRAN77では、いくつかのサブルーチンの間で共通の定数を使うとき それぞれのサブルーチンで何回も同じ宣言をしなければいけないのですか? このままだと定数の値を変えるのが非常に面倒なので 一回の宣言で済む方法を知りたいです
>>234 定数宣言だけのファイルを1つ作って、各サブルーチンの先頭でINCLUDEする。
FORTRAN77の規格外だが大抵のコンパイラはINCLUDE文に対応している。
>>234 PARAMETER文を用いてなら、標準では無いw
COMMON 変数でよければ BLOCK DATA 文で初期化できる。
ベンダー拡張機能を許せば、INCLUDE を使う手もある。
まぁ、横着せずにラインエディターで一括変換すればよろしいw
ありがとうございます とりあえずINCLUDE使ってみます
>>234 モジュールでもいいぞ
>>238 奴はFORTRAN77と縛りを入れている。
>>236 entry文を使えば、何とかならない?
とくに理由がない限り、77からはさっさと足を洗った方がよくない?
242 :
236 :2009/05/27(水) 23:27:51
>>240 たしかにENTRY文という手もあったな。
COMMONが嫌で、グローバル変数を実現する代わりに使ったことがあったが、
やっぱ変数全部がグローバルになるせいでデバッグが面倒で
よほど特殊な場合意外はやめたほうが良いと思った。
243 :
デフォルトの名無しさん :2009/05/31(日) 15:35:51
みなさまのお力をお借りしたく。 #FAQならすみませんが、ご容赦ください IVF10.1(11でも)動作したソースを、Linux上のintelに持ち込んでコンパイルしました。 すると、以下のケースに分かれました。 1)あえてコード変換をせずにコンパイル コンパイルOKも、当然、表示は滅茶苦茶(要するに2バイト系がだめ) 2)SJIS->UTF8にしてコンパイル FORMAT文の箇所でエラー発生、これがどうしても直らない。 ちなみにエラーメッセージは以下の通りです
244 :
デフォルトの名無しさん :2009/05/31(日) 15:37:35
test.for(14): error #5120: 終了していない文字定数です。 *//' ... ログ出力ファイルを入れて') --------^ test.for(14): error #5082: 構文エラー、END-OF-STATEMENT が見つかりました、 <FORMAT_ELEMENT> <FORMAT_INTEGER> < ) <CHAR_CON_KIND_PARAM> <CHAR_NAM_KIND_PARAM> ... の 1 つを指定してください。 *//' ... ログ出力ファイルを入れて') ----------------------------------------------------------------------------------------^ このソースは、 100 FORMAT(//' *** test を始めます。***', * //' ... ログ出力ファイルを入れて') です。 他にも日本語からの問題なのでしょうか、"認識できないトークンを'?'をスキップしました"というエラーもでます。 なおf77でも同様で、この場合には、 Error on line 14: unbalanced quotes; closing quote supplied Error on line 14: unbalanced parentheses, statement skipped となります。 お気づきの点があれば、すみませんが、ご指摘ください。 よろしくお願いいたします。
245 :
デフォルトの名無しさん :2009/05/31(日) 16:06:32
>>244 a) kterm上でトライ
b) 使ってる全角文字の中に ' ) あたりの半角と同じ値が混じっている
くらいしか思いつかないや。
少なくともf77のケースでのエラーはb の事を言ってるみたいだけど。
英数字以外は使わないのが一番だけどなあ~。どうしても使いたかったら
character*2 zenkaku
read(*,*) zenkaku
write(*,*) ichar(zenkaku(1:1)),ichar(zenaku(2:2))
で全角一文字の対応する半角2文字のアスキーコード数がわかるので、強引に出来そうな気もするけどな。
winだと実際上の3行の部分は動くとおもうけど、linuxだとよくわからんね。
linux + fortran+ 2バイト全角文字 の話題はあまりお話を聞かないからうまく行ったらここにも報告してよ。
246 :
デフォルトの名無しさん :2009/05/31(日) 17:12:19
早速ありがとうございます。ひとつ確認しましたので、ご報告をば。 a)kterm Ubuntu9.04にてktermを入れて、確認。 ・UTF8はコンパイル時、文字化け?でダメ ・同じくSJISもだめ ・eucではifortでのコンパイルメッセージの出力が化けている(どれでも同じ??)状況でしたが、実行時は日本語出力OK でした。 となるとintelFortranのインストールもkterm上から行う方がよかったのか? まだすべての確認はできていませんが、うまくいきそうという報告まで。b)も後日、試してみますので結果を報告致します。
247 :
デフォルトの名無しさん :2009/05/31(日) 17:36:04
あ、追加。 うまく表示できているのは、kterm上で、の場合。通常のconsoleでは(当然っちゃぁ当然ですが)化け化けです。
おつ~。やっぱりktermがいいのね。 245のbのやつは、対で使われることが多い文字 (ichar()関数の返す値が ' が39、Hexでは27 " が41、Hexでは29 ) が93、Hexでは5D ] は34(これはFortranではあまり意味がないか・・) のようなやつ)が全角に混じってるとダメそうな気がする、という程度の意味で書いてみた。 でも、win版やktermインストだと大丈夫なんだよね。 246さんの意見のとおり、インストール時の設定その他に依存する部分が大きそうな気もするな。
249 :
デフォルトの名無しさん :2009/06/01(月) 18:51:56
文字化けの件、追試結果(w まだf77は試してませんが、どうやら文字コードは確かに影響してるっぽい。 問題はUTF-8で、どうも旧人なので勝手に2バイトと思い込んでましたが、現在は最大4バイトらしい。 このため、見かけ上、1行内では2バイト換算で70文字程度にしていたものがオバフロしていた模様。 よってifortでは、-FI -132という固定ながら132文字にしたら通りました。 いったい何をしていたんだ…わしorz ちなみにIVFでUTF8形式でソース保存して、それをWin上でコンパイルしたら妙なゴミが出てました。 結構コード問題は奥が深そうです。
>>249 知ってる人のような気がする......
tt
> 問題はUTF-8で、どうも旧人なので勝手に2バイトと思い込んでましたが、現在は最大4バイトらしい。 なか~まw そっか、UTFだとエディタの見かけより実際のはるかに長いんだね。試しに vi でてきとうにUTF使ったファイル開いたら、たしかに row 数が多い。 気を付けよう。
Intel Fortran の使える KIND を関数呼び出しで見ると、ASCII だけになってたような。 確認してないw
253 :
デフォルトの名無しさん :2009/06/04(木) 23:06:43
モンテカルロ法の計算プログラムを流したら、 FORTRAN I/O ERROR 913: OUT OF FREE SPACE って出てきて途中で計算が止まったっぽいです。 なにやらメモリー不足とのことですが、どう解決すればいいのでしょうか?
>>253 I/O エラーだから、メモリーではなくディスクが足りないんだろう。
/tmp とかのスクラッチ領域がパンパンになっている可能性もあるが。
うほ
いや、I/O処理の最中に何らかのリソースが足りなくなったというメッセージだと思う。
http://www.uic.edu/depts/accc/software/compilers/forterr.html 913 OUT OF FREE SPACE
Library cannot allocate an I/O block (from an OPEN statement), parse array (for formats
assembled at run-time), file name string (from OPEN), characters from list-directed read,
ISAM key descriptor, shared COMMON descriptor, variable-format descriptor, or file buffer.
The program may be trying to overwrite a shared memory segment defined by another process.
Allocate more free space in the heap area (see the beginning of this chapter); open fewer
files; use FORMAT statements in place of assembling formats at run time in character arrays;
read fewer characters; user fewer ISAM keys; use fewer shared COMMON areas; use fewer
variable-format expressions; or reduce the maximum size of file records.
無書式での読み書きも、そのスペースを食うのかね。
fortranの超絶初心者です。 以下のプログラムをexitを使わないで同様の結果を得るには、 どうすればいいのでしょうか? ご教授願います。fortran90を使っています。 program real :: r,a integer :: io !入力結果の状態を表す変数 ! print *, 'CTRl-D を入力すると終了' ! do while ( .true. ) read(5,*,IOSTAT=io) r if(io /= 0 )then exit endif a = 4 *3.141592* r ** 2 print *, r, a end do ! end program
>>259 1.歴史と伝統のGOTO文で抜ける。
2.READ文で END=nnn で抜ける。
だが元のままEXITで抜けるのがもっとも行儀が良いとされる。
261 :
259 :2009/06/06(土) 21:28:47
>>260 授業の課題で、exitを使わないで書き上げろという事だったんですが・・・
どうも、ありがとうございました。
>>261 >exitを使わないで書き上げろ
exitで抜けるのが一番良いのに、何でこう言ったんでしょ?
世に蔓延るGOTO使いまくりのプログラムに慣れさせるため・・・ではないよな、多分。 READ文の指定子の使い方の勉強とかかな。
ここはFortranでプログラムを作ってという図々しいお願いはおk?
>>264 大丈夫。ただし、初心者にありがちな「エスパーさん、○○作って!」はやめて。
知っている情報をそのまますべて載せるべし。
266 :
259 :2009/06/09(火) 16:56:11
>>262 さん
>>263 さん
どうやら、説明が足りなかったようで、すいません。
今日授業に出たところ、
program
real ::r,a
integer ::io
print *,'CTRL-Dを入力すると終了'
do while (io==0)
if (io==0) then
read (5,*,iostat=io) r
a=4*3.141592*r**2
print *,'半径=',r,'面積=',a
end if
end do
stop
end program
が、答えだそうです。
でもこれを実行すると、CTRL-Dで終了するとき、
前回の計算結果が表示されてしまいます。
またまたすいませんが、何を付け加えればいいのでしょうか?
なんかアホらしい授業だけど。 program real ::r,a integer ::io print *,'CTRL-Dを入力すると終了' do while (io==0) if (io==0) then read (5,*,iostat=io) r if (io==0) then a=4*3.141592*r**2 print *,'半径=',r,'面積=',a end if end if end do stop end program どう考えてもexitを使うほうが素直だ。
ありゃ、間違えた。 program real ::r,a integer ::io print *,'CTRL-Dを入力すると終了' do while (io==0) read (5,*,iostat=io) r if (io==0) then a=4*3.141592*r**2 print *,'半径=',r,'面積=',a end if end do stop end program readをifの外側に出さないといかん。
ioの初期化も足りないし。ぐだぐだ。
exitの偉大さを実感すると言う狙いなのだろう。
蛇足だが
>>259 の
do while ( .true. )
は
do
だけでおk
まあ、
do while (io==0)
に直させるためにワザと do while にしたのかもしれないが
do while (io==0) if (io==0) then たまにこういうセンスなさすぎなコード書く人いるよね 他人が書いたコードをメンテするはめになったときに、こういうの見ると何とも言えない溜息がでるわ・・・ たとえバグはないとしても
>>272 まぁ待てw
Fortran で WHILE を使おうとするだけでも、きわめて開明的な人物ではないか!
> if (io==0) then これはどこがセンスなさすぎなん?
>>272 は「センス」って言葉を使いたかっただけなんだよ。
>>274 ループの脱出(継続)分岐条件である io==0 が
WHILE と IF の二箇所で判断されていることを言ってるんだろ。
>>272 の態度はむかつかせるだけから、くだすれ的には反省すべき。
277 :
デフォルトの名無しさん :2009/06/10(水) 15:02:05
将来コードをいじったときにそのループをスキップする場合があることを考えて
do while (io .EQ. 0)
みたいなのは意図的に書くことはあるけどね。
というか、
>>266 のは変数 io がゼロに初期化されることを
前提にしている時点であまりいい回答では無いように思うけどな。
278 :
259 :2009/06/10(水) 16:33:09
>>268 さん、
>>271 さん
どうも、ありがとうございました。
授業はどうもいまいちわかりません(笑)
これからも、ちょくちょく質問させていただきますので、
くだすれの皆さん、よろしくお願いします。
Visual Fortranについて質問してもいいですか?(VS2008スレよりもこちらのほうが適切っぽいので・・・) VBやC#でVS2005を使ってたのですが、Intel コンパイラv11を買って Visual Fortranを入れてみたところ、Intellisenseが効きません。 Visual Fortranでは使えないということですか? これだとVSをFortran開発環境とする利点がかなり消えてしまうと思うのですが・・・
>>280 そうですか・・・
計算はLinuxクラスタで走らすけど、開発は使い慣れたWindowsのVSで
っていう人を見たことがあって、それいいなぁと思って入れてみたんですが・・・
Laheyっていうの初めて知りました。intellisenseっぽいポップアップが出てますね。
これやNAGなど他の開発環境で良いのがないか当たってみようかなぁ
ちなみにNAGの↓の比較図ですが、他社製ってやっぱVisual Fortranですかね・・・(苦笑
ttp://www.nag-j.co.jp/nagfor/img/f95comp.jpg
>>281 PGI Visual Fortran というのもあって、これもVSと統合されているのだが、
確か今は米国内の研究機関に所属していればただで使える。
アメリカの研究機関に知り合いがいれば(略
SalfordというかSilverFrostのFTN95もVSと統合できる。
しかし、PGIもSalfordもインテリセンスは無かったような気がする。
最新状況はしらねw
IntelFortranは今月中にF2003対応度が高まったv11.1で出るらしいので、
あわてずゆっくりしていってね。
284 :
279 :2009/06/12(金) 21:26:08
さっそく以下の3つを試しました。 Silverfrost FTN95 Express PGI Visual Fortran NAG Fortran Builder SilverfrostとPGIはVS組み込みタイプで、IVFと同じくintellisense等の高度なものはありませんでした。 それ以外も、パッと見特に違いはなさそうで、結局は好みの問題ということになるんでしょうか。 NAGのIDEはVS組み込みではなくオリジナルで、唯一これだけキーワード補完ができましたが、 変数や関数の補完は×でした。 うーん、こうなるとこのままIVFを使い続けたほうがよさそうです・・・
285 :
279 :2009/06/12(金) 21:44:13
確かにfortranerの開発って時代遅れな感があるな
>>285 スティーブって森の熊さんホモ動画の熊さんの一匹に似てるよね。
Fortranの開発環境のヘボさにうんざりしてCに逃げる人も多いんだろうな ただ、今後のトレンドを考えるとやはりCは…
紙テープ・パンチカード・ラインエディター上がりも多いFortran界では、スクリーンエディターで シンタックス・カラーリングがあるだけでも極楽浄土のけだるい怠けた世界に見えるのさ。
これから並列数は増える一方だから、最適化は少しの妥協も許されなくなるんだよな そうなるとFortran一択しかなくなる… MSがVisualFortran出してくれれば(^q^)
>>290 っ [MS Fortran PowerStation]
>>291 そう、それをもう一度頼む!(><)
MSのFortran部隊はどこ行っちまったんだ?
>>292 Netscapeがブラウザー戦争を仕掛けたせいで、VC++部隊以外が全部IE開発に
回されたという噂が当時あった。
まぁMSの歴史をたどると、BASICの次に作って売ったのはFORTRANだから
MS Visual FORTRANは原点回帰といえなくもないが、VBすら捨ててしまうMS様は
容赦ないのだw
でも、高い金出してコンパイラ律儀に買ってくれるのはFORTRANユーザーくらい?
>>292 MS → DEC → Compaq → Intel
>>294 MSからDECに流れたとはしらなんだ
IntelとMSがもっとみっちり連携してくれればいいんだけど、またWintelって非難が起こりそうだな
時間がかかって仕方ないのだが何とかなりませんか? ifort 9.1です。 real(8)::x(25,25),y(50,50) x=なんたら y=0 y(1:25,1:25)=x(1:25,1:25) y=cshift(y,12,1) y=cshift(y,12,2) 特にy=xのところ。 なんでこんなんに時間食う?? (メモリ書き込みに難儀してるのはわかるが、 y全体がキャッシュ上に乗るから、キャッシュで整えてから書けば時間かからんはず・・)
>>296 それだけじゃ分からんっつの
時間食うってどれくらい?
92x49回で数秒のオーダー @xeon5160? 1core使用 なんかおかしいな・・もうちょっと調べます。
ド初心者ですが質問です。コンパイルできたファイルを実行すると fmt: end of file apparent state: unit 10 named inp-2.dat last format: (F9.5) lately reading sequential formatted external IO となるのですが何が問題なんでしょうか?プログラムは外部データ(inp-2.dat)から数値を読み最大値を求めるものです 数値は実数です
>>296 >y(1:25,1:25)=x(1:25,1:25)
なぜ素直にy=xとしない。
多分
ALLOCATE(TMP(26,26))
TMP=x
y=TMP
DEALLOCATE(TMP)
のように展開されるから遅いんだろ。
>>300 TMP(25,25)だったw 0:25と勘違いしたよ。1:25とか俺的にはあり得ないw
>>299 データ数が足りないように見受けられる。
F9.5に当たるところでデータが足りないか、変数の数が合わないかしてるのでは?
[hoge@xeon prog20]$ cat test.f90 program test implicit none integer,parameter::nx=25,ny=50 real(8)::x(nx,nx),y(ny,ny) integer::i x=reshape((/1:25*25/),shape(x)) do i=1,100000 call sub1(x,y,nx,ny) call sub2(x,y,nx,ny) end do end program test subroutine sub1(x,y,nx,ny) implicit none real(8)::x(nx,nx),y(ny,ny) integer::nx,ny y=0 y(1:nx,1:nx)=x(1:nx,1:nx) y=cshift(y,12,1) y=cshift(y,12,2) end subroutine subroutine sub2(x,y,nx,ny) implicit none real(8)::x(nx,nx),y(nx,nx) !nyでなくnx integer::nx,ny y=0 y(1:nx,1:nx)=x(1:nx,1:nx) y=cshift(y,12,1) y=cshift(y,12,2) end subroutine 続く
>>301 データ数ですか。それは入力元のファイルの値に問題ありということですか?プログラムは
IMPLICIT REAL(A-H,O-Z)
DIMENSION X(100)
OPEN(UNIT=10,FILE='inp-2.dat',STATUS='old',FORM='FORMATTED')
OPEN(UNIT=11,FILE='list-2.dat',STATUS='UNKNOWN',FORM='FORMATTED')
READ(10,100)N
DO 20 I=1,N
READ(10,200)X(I)
20 CONTINUE
IMAX=0.0
DO 30 I=1,N
IF(X(I).GT.IMAX)MAXN=I
IF(X(I).GT.IMAX)IMAX=X(I)
30 CONTINUE
WRITE(11,300)'MAX=',IMAX,'NO.=',MAXN
100 FORMAT(A5)
200 FORMAT(F9.5)
300 FORMAT(A4,F10.5,A4,I3)
CLOSE(10)
CLOSE(11)
STOP
END
となってます。サンプルプログラムを改変しただけなのでおかしいところが多いと思います。入力ファイルはとりあえず実数を5つ縦に並べてあります
[hoge@xeon prog20]$ ifort test.f90 -p [hoge@xeon prog20]$ time a.out real 0m2.359s user 0m2.357s sys 0m0.002s [hoge@xeon prog20]$ gprof -b Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls s/call s/call name 71.83 1.53 1.53 100000 0.00 0.00 sub1_ 28.17 2.13 0.60 100000 0.00 0.00 sub2_ 0.00 2.13 0.00 1 0.00 2.13 MAIN__
みにくてすみませんでした。 CPUはcore2の6600 2.4Gでcashe=4Mでした。 yとxの寸法が違うので、y=xにできないはずです。 逆フーリエ変換にかけるとき外を0にしておきたいので、 こんなになっています。 実プログラムでは逆フーリエ変換にかかる時間と 同じくらいの時間がかかって大損しています。
まとめると、 y(1:25,1:25)=x(1:25,1:25) を100000回実行すると、 real(8)::x(25,25),y(50,50) のとき =>1.53秒かかる。 real(8)::x(25,25),y(25,25) のとき =>0.60秒かかる。 2.5倍もかからんでええやろ ということです。
>>299 私もできる範囲で手伝い。
100 FORMAT(A5) が気になります。
実際に実行させたらNにどんな値が入るでしょうか?
思っている値かどうかwrite文で確かめるのが吉かと思います。
>>307 このままだと実行すらできないんですよね・・・
READ(~)N のあとに
N=5 としてみましたが実行エラーの文は変わりませんでした
>>296 corei7のifort 11ですが
$ cat test.f90
integer,parameter::n=25
real(8)::x(n,n),y(2*n,2*n)
x=0
y=1
!y=x
y(1:n,1:n)=x(1:n,1:n)
end
$ time ./a.out
real 0m0.001s
user 0m0.000s
sys 0m0.001s
n=25000だと
real 0m1.974s
user 0m0.754s
sys 0m1.217s
何か環境おかしいんじゃないんでしょうか?他のホストで試したどうっすかね
>>299 適当にinp-2.datに
5
1
12
123
1234
12345
123456
と入れてます。
read(~)Nのあとにwrite(*,*)Nとすれば、ここまでは走りませんか?
これで走らせると、私の場合はN= 538976288と、とんでもないことになってました。
数字を数として読み込みたいのに、文字として読み込んだらまずいですよね、やっぱり。
A5はI5ぐらいかと思いますが、どうでしょう?
>>309 情報ありがとうです。
corei7+ifort 11ですか・・
なるほど。別のマシンで試してみます。
>>310 inp-2.datに小数点以下1桁を含んだ実数を適当に5つ入れて、writeしてみたところN=1073741824となってました。
フォーマットをi5にすると実数を受け取れないのでF5.5にしてみたのですが、Nは上記の通りです。何が起こってるんですかね・・・?
>>309 すんません。メインルーチンで
do i=1,100000
と回してますので、timeの結果が直接比較できないです。
すみませんが追加でテストお願いできませんか?
>>299 Nはデータの個数ですよね。実数じゃまずいのでは?
inp-2.datは
データの個数
データ1
データ2
:
というような構造じゃありませんか?
少なくとも最初のデータだけは整数かな。
それとIMAXを実数宣言しなきゃいけないようです。
>>315 datファイルにデータの個数を入れてなかったんですね・・・やっとわかりました!ありがとうございます。実行できました
プログラム自体はうまくいってないんですが・・・w
実行結果がMAX=0.000・・・、No.=2となっているんでうまくいってないですね
>>314 お世話になってます。
確かにこちらでも結果0秒になりました。
いやしかし、たぶん0.000,0060秒(6マイクロ秒)くらいかかっているのが、
timeコマンドの分解能不足で測れてないだけの様な気がしてますです。
実際は100000x100000回とかもっとぐらい実行するので、何とかしたいです。
>>316 IMAXの方もよろしく。
318 :
309 :2009/06/17(水) 00:39:12
>>317 問題点を整理(できればテストコードを用意)して頂ければ協力できますよ
他のマシンもいくつかあります
>>317 実数宣言とは何でしょうか?imax=0.0ではダメなんですよね?
320 :
300 :2009/06/17(水) 01:02:12
>>305 >yとxの寸法が違うので、y=xにできないはずです。
すまんこw ようつべ見ながらだったので、よく見なかったww
こんなものに時間がかかるも糞もないだろと思ったが、
10^5*10^5回も繰り返すなら気になるかw
部分配列でメモリーが連続していないので、コンパイラのバージョンが古いと
余計なテンポラリを暗黙にとっている可能性が高いと思う。
DO i = 1, 25
y(1:25, i) = x(:, i)
END DO
と、でもすれば早くなるべ。最適化でアンローリングとかもあろうし。
>>318 ありがとうございます!
テストコードを302に書き込みました。これでお願いできたらありがたいです!
問題点のほうは、まとめると、
302のプログラムで
y(1:25,1:25)=x(1:25,1:25)
を100000回実行すると、
real(8)::x(25,25),y(50,50) のとき =>1.53秒かかる。
real(8)::x(25,25),y(25,25) のとき =>0.60秒かかる。
「2.5倍もかからんでええやろ」
ということです。
おわかりいただけたでしょうか?
ifort10.1を試みてみました。XEON5160です。
% time a10.out :ifort10.1
1.288u 0.000s 0:01.31 97.7%
% time a09.out :ifort9.1
1.916u 0.004s 0:01.96 97.4%
だいぶ差があるなあ・・というところです。
>>319 real imax
を宣言文のところに追加です。
FORTRANの慣習ではI~Nから始まる変数名は整数変数に使うことになっているので、
imaxのままだと動くけどちょっと減点かな?
imax->xmaxにするほうがいいかも。この場合real xmaxは不要。
>>320 ご指摘ありがとうですです。
さっそく試してみますです!
>>322 うまくいきました! なんとなくfortranがわかりはじめてきました!
ありがとうございます
初心者は呪文のようにimplicit noneを宣言しておきましょう。
325 :
309 :2009/06/17(水) 01:39:38
>>321 こんな感じでした。時間はreal timeです
Corei7 920、ifort 11.0
real(8)::x(25,25),y(50,50)・・・0m0.799s
real(8)::x(25,25),y(25,25)・・・0m0.255s
Xeon5472、ifort 10.1
real(8)::x(25,25),y(50,50)・・・0m0.922s
real(8)::x(25,25),y(25,25)・・・0m0.280s
Opteron2218、pgf90 6.2
real(8)::x(25,25),y(50,50)・・・0m9.821s
real(8)::x(25,25),y(25,25)・・・0m4.372s
>>300 さんの指摘通りってことですかね
Opteronが糞遅いのが気になりますが・・・(;^ω^)
>>309 様(325)
ありがとうございます!!お手数掛けました。
COREi7万歳というところですか。
320様のご指摘も含めていろいろ検討したいのですが、
今晩はこの辺で失礼します。
(いろいろありがとうございました。また明日頑張ります。)
corei7はかなり評判いいよね opteronを完全に引き離した
>>325 OpteronというよりPGIのコンパイラのせいのような気がする。
オプションがどうなってるのかわからんし。
最新版は8.0だし。
でもたしかにi7はなかなかいい。
329 :
309 :2009/06/17(水) 13:56:34
>>328 >OpteronというよりPGIのコンパイラのせいのような気がする。
その通りでしたw
>>325 のコンパイルは全てオプション指定なしでして、調べたところ
ifortはデフォルトで-O2が、pgf90は-O1がかかるようです。
-O2を付けた場合↓
real(8)::x(25,25),y(50,50)・・・0m1.306s
real(8)::x(25,25),y(25,25)・・・0m0.784s
>>301 >1:25とか俺的にはあり得ないw
Cみたいに0から開始ってこと?
Fortranだと1から始めるのが一般的だと思うけど
>>330 いや、:だけで済ますとか、それすら書かないと言うこと。
333 :
デフォルトの名無しさん :2009/06/18(木) 19:19:25
例えば、配列 data1 から data4 があって、次々にsubroutine に引き渡したい場合ですが、 call hoge(data1) call hoge(data2) call hoge(data3) call hoge(data4) しないで、 do i=1,4 call hoge( ) end do の様にまとめる事って加能ですか? もし可能ならやり方教えてください。
334 :
デフォルトの名無しさん :2009/06/18(木) 19:22:10
data1 から data4 は既に7次元配列なので、それらをまとめる事はできないです。
>>333 普通は配列をdata(n,4)と2次元にして
do i=1,4
call hoge(data(:,i))
enddo
>>334 7次元配列ってすごいなw
Fortranの配列って7が限界だったっけ?それなら無理じゃないかな
あきらめれ
>>332 新しいコンパイラでは、どれを書いても最適化で同じになるらしいが、
初期のFortran90コンパイラでは、n:nnみたいな指定子が入ると、
テンポラリをとることが多かったみたい。
それは多分一般的には、n:nn:mみたいな不連続の番地をとる可能性があるためだと思う。
>>333 ポインターの配列を、TYPEによって定義しておいて、それに配列を割り付けておいて、
それを引数に置けばいいんじゃないかな?
まぁポインターに割り当てるときに、だらだらとdata1~4を並べないと駄目なので
ゴミの位置が移動するだけだがw
338 :
337 :2009/06/19(金) 01:27:21
MODULE m_billy IMPLICIT NONE INTEGER, PARAMETER :: nmax = 2 TYPE :: t_billy INTEGER, POINTER :: mm(:, :, :, :, :, :, :) END TYPE t_billy CONTAINS SUBROUTINE anal(mm) INTEGER, INTENT(OUT) :: mm(:, :, :, :, :, :, :) INTEGER :: i1, i2, i3, i4, i5, i6, i7 DO i1 = 1, nmax DO i2 = 1, nmax DO i3 = 1, nmax DO i4 = 1, nmax DO i5 = 1, nmax DO i6 = 1, nmax DO i7 = 1, nmax mm(i1, i2, i3, i4, i5, i6, i7) = i1 + 10 * (i2 + 10 * (i3 + 10 * (i4 + 10 * (i5 + 10 * (i6 + 10 * i7))))) END DO END DO END DO END DO END DO END DO END DO RETURN END SUBROUTINE anal END MODULE m_billy
339 :
337 :2009/06/19(金) 01:28:03
!==================================================== PROGRAM herrington USE m_billy IMPLICIT NONE INTEGER, TARGET :: data1(nmax, nmax, nmax, nmax, nmax, nmax, nmax), data2(nmax, nmax, nmax, nmax, nmax, nmax, nmax) INTEGER, TARGET :: data3(nmax, nmax, nmax, nmax, nmax, nmax, nmax), data4(nmax, nmax, nmax, nmax, nmax, nmax, nmax) TYPE (t_billy) :: kazuya(4) INTEGER :: i kazuya(1)%mm => data1 kazuya(2)%mm => data2 kazuya(3)%mm => data3 kazuya(4)%mm => data4 DO i = 1, 4 CALL anal( kazuya(i)%mm ) END DO print *, data1 STOP END PROGRAM herrington
340 :
333 :2009/06/19(金) 01:58:08
サンクス。でも結構大掛かりだな。。。 real*8 data1(n,n,n,n,n,n,n), data2(n,n,n,n,n,n,n),....... char*1 cnum char*5 target do i = 1, 4 write( cnum, '(i1)' ) i target = "data" // cnum call hoge( target ) end do みたいにできんもんかね。。。 target と data$ は型が違うがな。
341 :
337 :2009/06/19(金) 02:24:46
>>340 77の掟破りでよければ、
real*8 data1(n,n,n,n,n,n,n), data2(n,n,n,n,n,n,n), data3(n,n,n,n,n,n,n), data4(n,n,n,n,n,n,n)
real*8 tmp(n**7, 4)
equivalence (tmp(1, 1), data1), (tmp(1, 2), data2), (tmp(1, 3), data3), (tmp(1, 4), data4)
do i = 1, 4
call hoge( tmp(i) )
end do
こんな感じでEUIVALENCEでいけるかな?
>>341 call hoge( tmp(1, i) )
の過ち。
ハルヒ新OP糞杉www
>>334 本当に7次元いるの? 変数設計を再検討した方がいいんじゃない?
座標3次元+時間で、4次元はざらにあるが。
>>343 の言うとおり。
変数設計は、アルゴリズム的な自然さ(人間にとっての見やすさ)と速度の
両方の観点から決めるべき。
7次元配列の数値計算ってどういう分野で出てくるの?
流れぶった切ってすいません。 n×n 次元行列 M と n 次元ベクトルa の積 b = Ma を計算するプログラムを 作っていたのですが、詰まってしまいました。 どこが、おかしいか教えていただけないでしょうか? program integer ::i,k,n integer,parameter ::limit=5 real ::M(1:limit,1:limit),a(1:limit),b(1:limit) do print *,'nの値は?' read *,n if ((n<=limit).and.(n>=1)) then exit end if end do ! print *,'行列Mの成分' do i=1,n print *,i,'行目?' read *,(M(i,k),k=1,n) end do print *,'ベクトルaの成分' do k=1,n read *,a(k) end do
347 :
346 :2009/06/20(土) 21:52:41
!
>>346 の続き
do i=1,n
do k=1,n
b(0)=0
b(k)=b(k)+M(i,k)*a(k)
end do
end do
print *,'b:'
do k=1,n
print *,b(k)
end do
stop
end program
よろしくお願いします
348 :
346 :2009/06/20(土) 21:57:18
たびたびすいません。 上のプログラムはfortran90を使っています。 コンパイルする際は、ifort (プログラム名).f90 -o (プログラム名) としています。
>>346 全く見ていないが、b(0)=0 がおかしい。
b(k)=0.0 でかつ一個DOLOOPの外。
ループのところ do i=1, n b(i) = 0 do k=1,n b(i) = b(i) +M(i, k) * a(k) end do end do 直接関係ないけど、Mの行と列を入れかえたほうがいいかも。
351 :
346 :2009/06/21(日) 18:17:49
>>350 さん
ありがとうございました。
うまくいきました!
PROGRAM GAUSS_SOLVER IMPLICIT NONE REAL,DIMENSION(100,100)::A !行列A(最大100元まで解ける) REAL,DIMENSION(100)::B,X !右辺Bと解Xのベクトル INTEGER::N !元数 INTEGER::I,J,K !制御変数 WRITE(*,*)'このプログラムは連立一次方程式AX=Bのい解Xを求めます' WRITE(*,*)'AandB.TXTの入力フォーマットは次のようです' WRITE(*,*)'たとえば,3元の連立方程式の場合' WRITE(*,*)'3 (元数を与えてください)' WRITE(*,*)'A11 A12 A13 B1 (データは空白やタブで別けてください)' WRITE(*,*)'A21 A22 A23 B2 (AIJとBIには実数を与えてください)' WRITE(*,*)'A31 A32 A33 B3' WRITE(*,*)'解XはX.TXTに出力されます' OPEN(1,FILE='AandB.TXT') READ(1,*) N DO I=1,N READ(1,*) (A(I,J),J=1,N),B(I) END DO CLOSE(1) DO I=1,N-1 DO J=I+1,N DO K=I+1,N A(J,K)=A(J,K)-A(J,I)*A(I,K)/A(I,I) END DO B(J)=B(J)-B(I)*A(J,I)/A(I,I) END DO END DO
DO I=N,1,-1 X(I)=B(I)/A(I,I) DO J=I+1,N X(I)=X(I)-A(I,J)*X(J)/A(I,I) END DO END DO OPEN(1,FILE='X.TXT') DO I=1,N WRITE(1,*) 'X(',I,')=',X(I) END DO CLOSE(1) STOP END PROGRAM GAUSS_SOLVER
このプログラムをもとにN次行列の逆行列をもとめるプログラムを作るのですが どうしたらいいかわかりません。教えてくださると助かります。。
ガウス・ジョルダン消去法でぐぐれ ちなみに逆行列を求める時は元の配列に逆行列を 入れる事が出来て効率が良い
subroutine gauss_jordan(a,b,flag) implicit none integer,parameter::N=3 double precision ::a(N,N),b(N) integer ipv,i,j double precision :: inv_pivot,temp double precision :: big integer pivot_row,row(N) integer flag do ipv=1,N !コヌツ酖ヘテオコ・ big=0.0 do i=ipv,N if(abs(a(ipv,i)) > big) then big = abs(a(ipv,i)) pivot_row = i endif enddo if(abs(big) < 0.0001) then write(6,*) "A is singular matrix" flag = 0 return endif
row(ipv) = pivot_row !ケヤ、ホニ�、・リ、ィ if(ipv .ne. pivot_row) then do i=1,N temp = a(i,ipv) a(i,ipv) = a(i,pivot_row) a(i,pivot_row) = temp enddo temp = b(ipv) b(ipv) = b(pivot_row) b(pivot_row) = temp endif ! ツミウムタョハャ=1(・ヤ・ワ・テ・ネケヤ、ホス靉�) inv_pivot = 1.0/a(ipv,ipv) a(ipv,ipv) = 1.0
do j=1,N a(j,ipv) = a(j,ipv) * inv_pivot enddo b(ipv) = b(ipv) * inv_pivot ! ・ヤ・ワ・テ・ネホ・0(・ヤ・ワ・テ・ネケヤーハウー、ホス靉�) do i=1,N if(i .ne. ipv) then temp = a(ipv,i) a(ipv,i) = 0.0 do j=1,N a(j,i) = a(j,i) - temp*a(j,ipv) enddo b(i) = b(i) - temp*b(ipv) endif enddo
enddo ! ホホニ�、・リ、ィ(オユケヤホ・ do j=N,1,-1 if(j .ne. row(j)) then do i=1,N temp = a(j,i) a(j,i) = a(row(j),i) a(row(j),i) = temp enddo endif enddo flag = 1 return end subroutine !### TEST MAIN ###### ! program MAIN ! implicit none ! integer,parameter::N=3 ! double precision :: a(N,N),b(N) ! integer :: flag
! a(1,1) = 0.0 ! a(2,1) = 1.0 ! a(3,1) = 0.0 ! a(1,2) = 1.0 ! a(2,2) = 0.0 ! a(3,2) = 0.0 ! a(1,3) = 0.0 ! a(2,3) = 0.0 ! a(3,3) = 1.0 ! ! b(1) = 3.0 ! b(2) = 4.0 ! b(3) = 5.0 ! call gauss_jordan(a,b,flag) ! write(6,*) b(1),b(2),b(3) ! stop ! end program
UTF-8か何かで貼ったのか? 文字化けしてて日本語部分読めないぞ
これのことですか?長々とすみません
ダウンロードしたものをノートパッドで開いてコピペしたんですが。。
で、わかったっしょ?ガウスジョルダン消去法を使うと逆行列が 求められるという事が もちろん行列式が零だと潰れてしまうが
半分くらい・・・(汗
Intel Fortran v11.1 が出たようだな。 まだ完全ではないようだが、ようやくF2003時代がやってきたw
去年も逆行列の質問をしていた奴がいたが、さては留年したかw 今年はがんばれ。 質問でうまくおだてて解答ゲットしろw
これでも分からないならネットに頼るのはやめて明日本屋に行け そして線形代数の本を買え 掃き出し法という名前で載っているかもしれないがとにかくそれだ 手で一回3×3程度の行列の逆行列を求めてみればおのずと プログラムでやっている事も理解できる
数学的なやり方そのものに疑問はないです・・・ ただプログラムできないです・・・ちなみにその去年の人じゃないよ
>>372 おk。
疑問点を具体的に書いてくれれば、具体的に答えられるが、
漠然と聞かれると、漠然としか答えられない。
まぁがんばれw
最初は誰でも、どこがわからないかわからない状態だよね まあがんばれw
>>372 というか、質問の仕方というものがあるだろう・・・。
いきなりソースコースばしばし貼りまくってから質問内容を言うのは、分かりにくいというか
それ以前のマナーの問題。せめて要点をまとめろよ。
いいやん こっちも動くソースをばしばし貼って、それで終わりにして 質問は一切受け付けませんよという態度を取れば
そしたらスレが汚くなるじゃないか。質問者はソースを貼るときは、必要でない限り ・ソース丸ごとではなく、最小限の部位に留める ・変数名を見やすい、もしくは一般的なものに変える ぐらいはやってくれよと。こんなの常識じゃないかと思うんだが。
>>377 それができたら初心者じゃないから、まあ、大目にみようよ
>>372 ですが今日一日教科書じっくり読み込んでだいたいわかりました
ぐだぐだとプログラムを貼り付けてすいませんでした。。
あと、教えてくれた皆さんありがとうございます
>>379 そうかそれはよかったな
君のした努力は決して無駄にならないと思うよ
これから線形代数・微積分学・複素関数論とかいろんな
数学をプログラミングする機会があると思うが、今した努力は
必ず生きてくる
特にFFTのプログラムなんか芸術的だぞ
バタフライ演算って言ってな
>>380 ありがとうございます
読んでる内にどんどん楽しくなってきて、一気に今やってるところまで
読み進めれました。
これからもっとがんばります(`・ω・´)
立派なフォートランナーになってくれ^^
>>377 おまえの常識なんか初心者はしったこっちゃねーんだよw
C IMPLICIT REAL(A-H,O-Z) REAL T(100),XZ(100,2) DATA GRAV,V0,ANGLE/9.8,30.0,45.0/ DATA T0,VINT,TMAX/0.0,0.5,7.5/ PI=ATAN(1.0)*4.0 R=ANGLE*PI/180.0 C DO 10 I=1,50,1 T(I)=REAL(I-1)*VINT IF(T(I).GT.TMAX)THEN STOP END IF XZ(I,1)=V0*COS(R)*T(I) XZ(I,2)=-0.5*GRAV*T(I)**2+V0*SIN(R)*T(I) 10 CONTINUE S=AREA(T,X,Z,T0,TMAX,R,GRAV) CALL OUTPUT(T,X,Z,S) STOP END
C FUNCTION AREA (T,X,Z,T0,TMAX,R,GRAV) IMPLICIT REAL(A-H,O-Z) XMAX=V0*0.5*COS(R)*TMAX X0=V0*0.5*COS(R)*T0 DO 20 I=1,16 AREA=0.0 DX=(XMAX-X0)/REAL(I) T=REAL(I-1)*VINT X1=V0*COS(R)*T X2=X1+DX Z1=TAN(R)*X1-0.5*(GRAV/(V0*(COS(R))**2))*X1**2 Z2=TAN(R)*X2-0.5*(GRAV/(V0*(COS(R))**2))*X2**2 AREA=AREA+(Z1+Z2)*DX*0.5 20 CONTINUE RETURN END
C SUBROUTINE OUTPUT(T,X,Z,S) IMPLICIT REAL(A-H,O-Z) INTEGER NO(100) REAL T(100),XZ(100,2) C OPEN(16,FILE='menseki2.res') WRITE(16,'(A)')' TIME CX CZ SPACE' DO 30 I=1,16 WRITE(16,'(F5.1,2F10.2)') T(I),(XZ(I,J),J=1,2) WRITE(16,'(F10.2)') S 30 CONTINUE CLOSE(16,STATUS='KEEP') RETURN END 物体の投げあげの時間、X座標とZ座標、台形積分の計算をファイルに出力したいのですが、コンパイルしてもファイルが作られません。 ファイルは時間が1次元配列、X座標とZ座標が2次元配列です。 どう改善すればよいのでしょうか
>>386 T(I) が TMAX (=7.5) を超えたところでSTOPするようになってるから。
てゆーかぱっと見、変数の使われ方が変だ。
XZ は宣言されてるが X とか Z が突然出てきてるぞ。
IMPLICIT NONEで動くところまで書き直せ。
>>384-386 あんた
>>352-354 か?
ソースを貼るなとは言わんが、まず「○○で困っています。××はどうすればいいでしょうか?ソースは以下の通りです」とか書いてから貼れよ
プログラムの書き型が相当古いから別人だろうな。
>>387 それ以前に、コンパイルが通らないんだろ。
AREAの引数のTが、スカラー定義なのに配列を渡している。
書き方は古いが、非常にオーソドックスで正当な書き方をしている。
しかし、実際の論理というか中身はかなり??
簡単には直らんw
391 :
1/2 :2009/06/27(土) 22:59:57
>>386 IMPLICIT REAL(A-H,O-Z)
REAL T(100),XZ(100,2)
DATA GRAV,V0,ANGLE/9.8,30.0,45.0/
DATA T0,TINT,TMAX/0.0,0.5,7.5/
PI=ATAN(1.0)*4.0
R=ANGLE*PI/180.0
C
C ! IMAX <= 100 no check www
IMAX = INT((TMAX - T0) / TINT) + 1
DO 10 I=1,IMAX
T(I)=T0 + REAL(I-1)*TINT
XZ(I,1)=V0*COS(R)*T(I)
XZ(I,2)=-0.5*GRAV*T(I)**2+V0*SIN(R)*T(I)
10 CONTINUE
S=AREA(IMAX, XZ)
CALL OUTPUT(IMAX, T,XZ,S)
STOP
END
C
FUNCTION AREA(IMAX, XZ)
IMPLICIT REAL(A-H,O-Z)
REAL XZ(100, 2)
AREA=0.0
DO 20 I=1, IMAX - 1
AREA=AREA+( XZ(I,2)+XZ(I+1,2) )*( XZ(I+1,1)-XZ(I,1) )*0.5
20 CONTINUE
RETURN
END
392 :
2/2 :2009/06/27(土) 23:02:17
C SUBROUTINE OUTPUT(IMAX,T,XZ,S) IMPLICIT REAL(A-H,O-Z) INTEGER NO(100) REAL T(100), XZ(100,2) C OPEN(16,FILE='menseki2.res') WRITE(16,'(A)')' TIME CX CZ SPACE' DO 30 I=1,IMAX WRITE(16,'(F5.1,2F10.2)') T(I),(XZ(I,J),J=1,2) 30 CONTINUE WRITE(16,'(A, F10.2)') 'AREA=', S CLOSE(16,STATUS='KEEP') RETURN END イマイチよく分からんが、こうかな? とりあえず放物線のようなものは描く。 しかし、地面をつきぬけていくので全積分面積は負になる。 この辺は適宜修正してくれ。
393 :
名無し :2009/07/01(水) 17:03:04
おそらくもう根本的なところから間違っていると思うのですが、間違えている点を教えていただけタラと思います。 あるデータを読みこんで画面に表示させるプログラムなのですがうまくいきません。よろしくお願いします。 implicit none integer MM,K,X,Y parameter (MM=500,K=100) integer year(MM),month(MM),day(MM),sl(K,MM) character cdummy,CFNAME X=0 CFNAME='/home/maekawa/numeric/kure.txt/' open(1,file=CFNAME,status='old') 1010 X=X+1 read(1,10,END=1020)cdummy,year(MM),cdummy,month(MM), @ cdummy,day(MM),(sl(Y,MM),Y=1,24) 10 format(A5,I2,A1,I2,A1,I2,24(a1,I3)) write(6,*)year(MM),month(MM),day(MM),sl(Y,MM) goto 1010 1020 close(1) X=X-1 end
394 :
名無し :2009/07/01(水) 17:03:54
上の続きです。引き続きよろしくお願いします。 コンパイルはできるのですが実行すると forrtl: Is a directory forrtl: severe (30): open failure, unit 1, file / Image PC Routine Line Source a.out 0809916D Unknown Unknown Unknown a.out 080986E5 Unknown Unknown Unknown a.out 0806B758 Unknown Unknown Unknown a.out 0804C153 Unknown Unknown Unknown a.out 0804BAB0 Unknown Unknown Unknown a.out 08052838 Unknown Unknown Unknown a.out 08049D6C Unknown Unknown Unknown a.out 08049CC1 Unknown Unknown Unknown libc.so.6 B7E7A3B0 Unknown Unknown Unknown a.out 08049C01 Unknown Unknown Unknown というエラーになります。 質問の仕方も上手ではないので分かりにくい点があるようでしたら申し訳ないのですがその点もご指摘いただけたらと思います。 よろしくお願いします。
CFNAME='/home/maekawa/numeric/kure.txt/' 最後の / が余計なのでは? CFNAME='/home/maekawa/numeric/kure.txt'
396 :
名無し :2009/07/01(水) 17:10:56
ご指摘ありがとうございます。 しかし直して見ましたがエラーは直りませんでした。 どうすればよろしいのでしょうか?
さらに character cdummy,CFNAME を character cdummy,CFNAME*80 にしてみて。
398 :
名無し :2009/07/01(水) 17:33:10
直しました。まだ同じエラーが出ますね…すみません。
forrtl: Is a directory forrtl: severe (30): open failure, unit 1, file / このメッセージは、open(1,file=CFNAME,status='old')の行で出力されていると思います。 メッセージの最後が "file /" となっていることから、 CFNAMEに格納されているファイル名が、"/" 一文字だけであると判断できます。 メッセージの"Is a Directory" は、 ファイル名として渡された "/"が、 ディレクトリなのでオープンできないことを意味します。
400 :
名無し :2009/07/01(水) 17:49:00
ファイルの場所を確認したら表示されました!ありがとうございます!しかし実行したあと write(6,*)year(MM),month(MM),day(MM),sl(Y,MM) の「sl(Y,MM)」の部分がずっとゼロで表示されます。 3けたの数字が24個よこに表示されるはずなのですが…
write(6,*)year(MM),month(MM),day(MM),sl(Y,MM) を write(6,*)year(MM),month(MM),day(MM),(sl(Y,MM),Y=1,24) に変えたらどうなりますか?
402 :
名無し :2009/07/01(水) 18:11:57
数字がたくさん表示されるようになりましたがどうやら欲しい値の他に538976300という謎の数字が間に挟まりまくっています。 自分でも調べてみたのですがそのような数字はデータに見当りませんでした。 作った私がいうのもなんですが配列の型宣言あたりでKやYや使っているのが間違いではないかと思うのですが…ここは大丈夫なのでしょうか?
次は @ cdummy,day(MM),(sl(Y,MM),Y=1,24) を @ cdummy,day(MM),(cdummy,sl(Y,MM),Y=1,24) に変えます。
404 :
名無し :2009/07/01(水) 18:36:59
ほとんど表示されました!ありがとうございます! 表示する量が多すぎて最初の方のデータが表示されないのですが、すべて表示するにはどうすればよいでしょうか? 細かいところまで大変お手数お掛けします…本当に助かります。
405 :
デフォルトの名無しさん :2009/07/01(水) 18:38:52
学校のレポートで4行4列の行列式を計算するプログラムを作れと言われたんですが、 まったくわかりません。 少ない行数でできるらしいのですが、どうか教えてくれませんか? fortran77を学校では使ってます。
>>405 まず、ちみが用いようとしている行列式の公式ないしアルゴリズムを指定してくれ。
いろいろやり方はある。
real(8)とrealで計算したときに足りない桁って0で補われるの?それとも動作不定?
質問です。 131 'Ashikaga' 65 31 54 101 'Miyoshi' 64 43 62 156 'Chousokabe' 82 58 48 86 'Imagawa' 55 60 72 53 'Houjou' 88 64 73 といったようなデータを読み込んで、 番号 名前 国語 理科 数学 合計 平均 ~何らかの値~ 国語平均 理科平均 数学平均 標準偏差 ~何らかの値~ といった、表を出力したいのですが おそらく、最後のprint文がミソだと思うのですがどうしたらいいかわかりません。 以下のプログラムに何を付け加えればいいのでしょうか? また、どこか間違っている箇所があればご指摘ください。 fortran90を使っています。
program integer::n,ten(1:3) real(8)::sum(1:3),sum2(1:3) real(4)::mean(1:3),sd(1:3),heikin integer::io integer::bango,gokei character*14::kamoku(1:3),namae ! kamoku(1)='国語' kamoku(2)='数学' kamoku(3)='理科' n=0 do i=1,3 sum(i)=0.0D0 sum2(i)=0.0D0 end do !
do read(5,*,iostat=io)bango,namae,(kamoku(i),i=1,3) if(io/=0)then exit end if n=n+1 do i=1,3 sum(i)=sum(i)+ten(i) sum2(i)=sum2(i)+ten(i)**2 end do end do gokei=ten(1)+ten(2)+ten(3) heikin=gokei/3.0 do i=1,3 mean(i)=sum(i)/n sd(i)=sqrt((sum2(i)-(sum(i)**2)/n)/n) end do print *,'人数=',n do i=1,3 print *,'科目',kamoku(i),mean(i),sd(i) end do stop end program ex8_1a よろしくお願いします。
>>407 足りない分は、ゴミが入る。
倍精度に定数を与えるときなども注意しなければならない。
413 :
デフォルトの名無しさん :2009/07/04(土) 10:00:10
>>411 ゴミが入るのは、
real(8) a
a=1.0
みたいに倍精度で定義したのに倍精度で代入しなかった場合だね。
宣言の精度が違う場合には407のいう「足りない桁」の部分は
そもそもメモリ上に存在しない。仮にあるとして説明すると、
足りない桁の直前の桁がランダムに切り上げられたり切り下げられたりする、といったところか。
>>408 三好君はもっと出来る子・・・・。
read文でkamoku(1:3)に点数が入ってるけどそのあと使われてないね。
おそらく、
sum(i) = sum(i)+kamoku(i) に変更。
sum2(i) = .... も同様。
goukei=sum(1)+sum(2)+sum(3) に変更。
配列 ten(1:3) はいらなくね?
414 :
408 :2009/07/04(土) 11:58:35
>>413 ありがとうございます。プログラムがすっきりしました。
ところで、
>>408 に書いたように、表みたいに出力したいのですが
以下のプログラムでは読み込んだデータの最後のものが繰り返されてしまいます。
どこがおかしいのでしょうか?
program integer(8)::n,kamoku(1:3) real(8)::sum(1:3),sum2(1:3) real(4)::mean(1:3),sd(1:3),heikin integer::io integer::bango,gokei character*14::namae ! n=0 do i=1,3 sum(i)=0.0D0 sum2(i)=0.0D0 end do
do read(5,*,iostat=io)bango,namae,(kamoku(i),i=1,3) if(io/=0)then exit end if n=n+1 do i=1,3 sum(i)=sum(i)+kamoku(i) sum2(i)=sum2(i)+kamoku(i)**2 end do end do gokei=kamoku(1)+kamoku(2)+kamoku(3) heikin=gokei/3.0 do i=1,3 mean(i)=sum(i)/n sd(i)=sqrt((sum2(i)-(sum(i)**2)/n)/n) end do print *,'人数=',n do i=1,n print *,'名前',namae,'国語',kamoku(1),'数学',kamoku(2),'理科',kamoku(3),'平均',heikin,'合計',gokei enddo do i=1,3 print *,'科目平均',mean(i),'標準偏差',sd(i) enddo stop end program
>>414 データを読み込む時に毎回kamoku(1)~(3)を上書きしてるから
gokei の計算、 heikin の計算と namae, kamoku(1),kamoku(2),kamoku(3),heikin,gokeiの出力は 最初のDOループの内側でやらないとだめでしょ。
科目名変数を定義しておいて character*6::kamokumei(1:3)=(/'国語','数学','理科'/) データを1行読むごとに、すぐに出力してしまう。 gokei=kamoku(1)+kamoku(2)+kamoku(3) heikin=gokei/3.0 print *,'名前',namae,(kamokumei(i),kamoku(i),i=1,3),'平均',heikin,'合計',gokei 最後に、科目ごとの平均と標準偏差を出力する。 print *,'人数=',n do i=1,3 mean(i)=sum(i)/n sd(i)=sqrt((sum2(i)-(sum(i)**2)/n)/n) print *,kamokumei(i)//'平均',mean(i),'標準偏差',sd(i) end do
420 :
414 :2009/07/04(土) 15:51:27
>>417 さん
アドバイス、ありがとうございました。
>>418 さん
なるほど、do文の中にprint文を入れるんですね!
おかげさまでうまくいきました。
>>419 さん
別にprint文は最後にまとめなくて良いんですね!
細やかなご指摘、ありがとうございました。
みなさん、本当にありがとうございました!
421 :
デフォルトの名無しさん :2009/07/04(土) 16:43:36
ここの板で質問するのが適当か分からないですが、 FORTRAN使いの方の中にはCとの連携をしている人も 多いと思うのでアドバイス下さい。 FORTRANで作成したサブルーチンを活用し、C++からコール する形でコードを再利用しようと考えています。 C++からFORTRANを呼び出すのはすぐに出来たのですが、 データの引渡しで困っています。 FORTRAN側ではグローバルな変数を多数(100個以上)宣言 しており、引数としては渡せないのでC++側でも同名の 変数を宣言して共用し、データのアクセスをしようと 目論んでいます。 しかし、FORTRANでexternに相当する宣言の仕方が分からず、 うまく同じ領域を共用できるようになっていません。 具体的にどんなことをすれば良いのかご存知の方がいらっ しゃいましたら、ぜひご教授願います。 環境は、WindowsでVisualC++とVisual FORTRANを使って います。 宜しくお願いします。
422 :
デフォルトの名無しさん :2009/07/04(土) 16:47:57
fortran77(g77)(90でもいいけど)で subroutine foo(nn,letter) character(len=nn) letter return end とかって出来ないの? コンパイルでエラーでるんだけど
>>422 gfortran では、エラーなくコンパイルできました。
エラーメッセージを貼ってみたら?
>>421 マニュアルにグダグダ書いてあるから読むがよろしい。
いくつか方法がある。
結構めんどい。
Fortran2003のCとの連携ルーチンを使うという手もある。
>>424 >>422 ではないけど、g77 でやってみた。
% g77 -c lett.F
lett.F: In subroutine `foo':
lett.F:1:
subroutine foo(nn,letter)
1
lett.F:2: (continued):
character(len=nn) letter
2
Invalid declaration of or reference to symbol `nn' at (2) [initially seen at (1)]
gfortran は問題なかった。そもそも FORTRAN77 の規格ではこんな書き方を許していなかったはず。
度々すいません、
>>408 ,414,420です。
前に質問したことは解決したんですが、
今度は書式制御でつまずいてしまいました。
変数等は
integer(8)::n,kamoku(1:3)
real(8)::sum(1:3),sum2(1:3)
real(4)::mean(1:3),sd(1:3),heikin
integer::io
integer::bango,gokei
character*14::namae
character*6::kamokumei(1:3)=(/'国語','数学','理科'/)
で、定義しています。
print "(a2,a14,a2,i7,a2,f7.2,$)",'名前',namae,(kamokumei(i),kamoku(i),i=1,3),'平均',heikin
と
print "(a2,a2,f7.2,a4,f7.2,$)",kamokumei(i)//'平均',mean(i),'標準偏差',sd(i)
は、どこがおかしいんでしょうか?
書式をこのように書いた場合、エラーが出てうまくいきません。
>>422 FORTRAN77しばらく書いてないから忘れちゃったけど、
CHARACTER*(NN) または CHARACTER*(*)でなかったかい?
g77なんてウンココンパイラ使うなよw
429 :
名無し :2009/07/09(木) 16:58:58
まずこのプログラムを見ていただけますか? implicit none integer MM,KK,M,K parameter (MM=100,KK=100) integer year(MM),month(MM),day(MM),sl(KK,MM) character cdummy,CFNAME*80 M=0 CFNAME='/home/maekawa/numeric/kure.txt' open(1,file=CFNAME,status='old') 1010 M=M+1 read(1,10,END=1020)cdummy,year(M),cdummy,month(M), @ cdummy,day(M),(cdummy,sl(k,M),k=1,24) 10 format(A5,I2,A1,I2,A1,I2,24(a1,I3)) write(6,*)year(M),month(M),day(M),(sl(k,M),k=1,24) goto 1010 1020 close(1) M=M-1 end SLの24の値を平均して一個のデータにして新しい配列を作って代入する、という事をしたいのですがどのようなことを付け加えればよろしいでしょうか。 おかしい質問かもしれませんがよろしくお願いします。
えー、そもそもまともに動くはずはないシロモノなんですが、 なぜこういうことが起きるのか教えてください。 A=X+1 (←XとYは未定義) B=Y+1 Z=1 (暗黙の型宣言) C=A+B というような場面でZ=1を入れるかどうかでCの値が変わるんですが。 XとYが未定義なのでどこかめちゃめちゃなアドレスを参照していて、 Zの宣言によって参照するアドレスが変わるとかそんな感じでしょうか? でも未定義とはいえ既に代入してあるんで結果が変わるのは不思議な気がします…
>>430 試してみましたけど、ifort 11.0とgfortran 4.3.2では再現されないですね。
処理系、教えてもらえますか?
432 :
デフォルトの名無しさん :2009/07/11(土) 05:27:22
そういえば似た感じでwrite文のある無しで結果が変わったことがあったな。
アドレス参照して値取り出して・・・は最近のCPUではある程度まとめて出来るだろうけど、
定数の代入とかI/Oみたいに、まとめてしなくても良い or まとめて出来ない処理が
混じるとそこで一度仕切るというかなんか処理が変わるんだろうな・・・と適当な事を書いてみる。
>>430 の Z=1 の代入文を
(なにもしない)continue文に変えてみたらどうなるのだろう?
FORTRANでオブジェクト指向ってできますか?
>>433 誰かの本にそういう話があったな。誰のだったっけ?
>>433 Fortran2003でOOP対応が一通りそろった。
皆さん実際、使ってます?>オブジェクト指向 Fortranが使われるような数値計算の分野で、どういう場面で有用なのか いまいちイメージ沸きません
行列とか?
>>436 MPIのルーチンとかがC++で書かれていて、引数の型がpolymorphism的に任意に
なっていたりすると、F90のPASCAL的な厳格な型判定では、インターフェースも
書けない。型判定を緩くしようというような消極的な事情もあるようだよ。
>>431 遅くなってすいません。OSはXP、intel fortranの11.0+visual studioです。
多分そちらと同じですよね?上のは少し単純化してありますけど、
AとBの右辺がもう少し複雑になってて既知の数で割ったり足したりしてるだけなんで
おかしなことに変わりはないと思いますが…
>>432 continueに変えても値が変わりました…ちなみに
write文のときは何が原因でしたか?
>>438 C++はよ消えてなくなれ、ということか。
あれはFortranやCとはあまり親和性が無いから嫌いだ。使うけど。
>>439 後半
原因不明のまま放置w 432でかいたけど
I/O の直前まで、I/O の行、I/O よりうしろ、
でコンパイラが作業を区切るからではないかと推定したw。
自分の時には write文でなくても read文でも同じだったから。
コンパイラにもよるのかもなあ。
同じ経験はDEC Fortranのころからあった気がする。というかIntelのはDECの系譜だろうし。
>>436 化学プロセスの設計のときとか
撹拌槽やら蒸留塔やらいろんなクラスを作っておいて
後で自由に組み合わせたりできそうだな。
問題は、うちのボスがオブジェクト指向を理解できない、ということだな…
自由に組み合わせる、だけならOOである必要もないけどな。まあ楽だけど。
問題解決の方法が、オブジェクト主体で考えるのが自然かそうでないかによると思うけど。 普通の数値計算は、方程式をいかに早く効率良く解くか、というのが主眼だから オブジェクトなんてものを持ち出す必要性も少ないってことじゃないかと。 計算資源の観点からはむしろマイナスだし>OO
10人分の受験番号と1教科の採点結果から、平均と偏差値を求めて、 成績順に並び替えるっていうプログラムを作りたいんだけど、 SUBROUTINEを、 ・平均を求めるもの ・偏差値を求めるもの ・成績に並び替えるもの の3つを作ればいいってこと? それぞれのサブルーチンの作り方がよく分からないので教えてもらえませんか? 最後の成績はSWAP・・・? 77使ってます
>>444 > ・平均を求めるもの
> ・偏差値を求めるもの
> ・成績に並び替えるもの
> の3つを作ればいいってこと?
> それぞれのサブルーチンの作り方がよく分からないので教えてもらえませんか?
> 最後の成績はSWAP・・・?
つまり
・平均値の求め方を知らない
・偏差値の求め方を知らない
・数の大小関係を知らない
ということですね?
FORTRAN 以前の問題なので、中学校あたりの数学からやり直すべきでは?
素直に課題ですといえば教えてやらんのに
mixiにも平均値の出し方教えてってのが土曜に出てきたけど 同一かなぁ、、。 こちらの質問より大分低次元な質問だけど、、。
宿題についての質問はいいとしても、丸投げは駄目だと思う。 まぁ宿題代行スレなら丸投げもいいのかもしれないけど。
ここは未来のフォートランナーを育てるスレです 宿題厨はカエレ
>>452 このご時世、Fortran の講義があるだけ、ありがたいと思わなければ。
我ら先達が、後進達を引っ張ってあげるのだよ。
>>452 ん?
このスレはFORTRAN IVの本スレで宿題厨を排除したので立った初心者スレだぞ。
ここって宿題代行スレなんですか? 新参者なので位置付けを分かってません。
>>455 代行するもよし、ヒント出しもよし、生暖かく見守るもよし。
>>455 >>456 の言うとおり。
スレタイにあるように超初心者用なのでネットマナー違反も大目に見る。
麻薬の売人と同じで、最初は無料で甘い汁を吸わせて甘やかして気持ちよくさせて
初心者をFortran依存症にするスレだ。依存症にした後は骨まで搾り取る。
いまどきFortranなんてはやりませんよw
Fortran95の言語仕様がベスト! Windowsプログラムを作ろうとは思わないが、 計算に使うのには理想的だと思う。 頼むから、もういじらないでくれ・・・
>>458 流行らないけど、廃れないから、一生役に立つ。
461 :
デフォルトの名無しさん :2009/07/22(水) 11:30:52
1 次元配列 a(k) = k (k は 1 から 100 まで) から、新たに 100 個の変数の組: a1 = 1, a2 = 2, ..., a100 = 100 を作りたいのですが、どうすればよろしいのでしょうか? (新しい変数名における数字は、配列の添え字 k に対応 させたいです。) 素人質問ですみませんが、どうぞよろしくお願いします。
>>461 それ無理!
強いて言えばポインターをつかうか。
しかし考え方を変えた方がいい。
>>457 >依存症にした後は骨まで搾り取る
ドカタ量産ですね^^
464 :
デフォルトの名無しさん :2009/07/22(水) 13:53:02
>> 462 さん 無理ですか・・・。今、A x = b (行列 A は複素三重対角行列) の 固有値問題を解こうと思っているのですが、手元のライブラリ (NEC 製科学技術計算ライブラリ ASL)は、行列 A やベクトル b が 多次元の場合には対応していないようなのです。 ですので、面倒ですが一旦行列 A(k) を A1, A2, ..., Ak に変換し、 その後に call subroutine(A1, b1, ...) call subroutine(A2, b2, ...) call subroutine(A3, b3, ...) ... call subroutine(Ak, bk, ...) と全ての k の場合について毎回サブルーチンを呼ぼうと考えていました。 たとえこのようなことが原理的に可能であったとしても、k が大きい場合には 現実的ではなさそうですね。 多次元の三重対角行列を高速に解くようなライブラリ(非商用含む)が あればいいのですが、何かありますでしょうか?
466 :
465 :2009/07/22(水) 14:29:55
若しかして、A が多次元というのは、例えば多次元配列 A の各要素が行列という意味? だったら、どうして良いか分かりません。外部ファイルにデータで置いておいて、1つ ずつ処理するとか?
467 :
デフォルトの名無しさん :2009/07/22(水) 15:36:37
テンソルのちょい面倒な計算なのかもな。 まあライブラリが一番得意なところまで 問題をdeductするのは人間の仕事だから・・・・・がんばってね!
468 :
465 :2009/07/22(水) 16:18:24
>>467 > テンソルのちょい面倒な計算なのかもな。
どうなんでしょうね。最初に
> 今、A x = b (行列 A は複素三重対角行列) の
> 固有値問題を解こうと思っているのですが
とあったので、単に行列 A の固有値問題だと即断しました。この書き方だと
単純な連立1次方程式を解きたいようにも見えるのは私だけでしょうか?
で、その後に
> 手元のライブラリ
> (NEC 製科学技術計算ライブラリ ASL)は、行列 A やベクトル b が
> 多次元の場合には対応していないようなのです
と来るので余計に混乱しました。「多次元の行列」、「多次元のベクトル」と
いう言葉をどういう意味で使っているのか分からない。単純に N×N 行列の N
の値が大きいという意味に解釈しました。
そういうわけで、行列 A の固有値問題を解きたいということと看做しました。
質問者自身が問題を理解していないという恐ろしい事態も有り得ますね…。
質問者はDimensionとRankを混同しているのではあるまいか。
むしろ、計算機科学でいうDimesionと、行列のDimensionの違いかな。
これじゃだめか? integer :: n, k complex(8) :: A(n,n,k), b(n,k), v(n,k), det(k) do i = 1, k call subroutine(A(1,1,i),b(1,i),v(1,i), det(i)) end do もしくは integer :: n, k complex(8) :: A(n,n,k), b(n,k), v(n,k), det(k) complex(8) :: A1(n,n), b1(n), v1(n), det do i = 1, k A1(:,:) = A(:,:,i) ; b1(;) = b(:,i) call subroutine(A1(1,1),b1(1),v(1),det) v(:,i) = v(:) ; det(i) = det end do マトリクスやベクトルをあらかじめ何組か準備して、 次々に解きたいだけじゃないかと解釈したが。
472 :
464 :2009/07/22(水) 17:18:39
皆さん、ご助言頂きありがとうございます。初心者なので (それが免罪符になるとは思えませんが)、 混乱もありくだらない質問をしているとは思いますが、どうぞご容赦ください。 >> 465 さん >> 若しかして、A が多次元というのは、例えば多次元配列 A の各要素が行列という意味? 言葉足らずですみません。今、数値的に解こうとしている方程式は2 次元複素ポアソン方程式 △f = g です。(△ はラプラス演算子。) y 方向にフーリエ展開 (f = Σ_{k} f(k, i)*expiky) し、x 方向のみ有限差分法 (分割数 n) で解こうとしています。各フーリエモードについて以下の n 個の連立方程式が得られますが、 a1_{k, i-1}*f_{k, i-1} + a2_{k, i}*f_{k, i} + a3_{k, i+1}*f_{k, i+1} = g_{k, i} ここで、 A : n 行 n 列の三重対角行列 x : f_{k, i} を要素に持つ n 次元の列ベクトル b : g_{k, i} を要素に持つ n 次元の列ベクトル とすると、各モードについて A x = b を解くことになります。A が多次元と言いましたのは、 このモード数の次元のことを指しておりました。 モード数が 1 の場合には、紹介して頂いた連立 1 次方程式のルーチンを使えば良いと思うのですが、 複数のモード数について解く場合には、毎回サブルーチンを呼ぶ必要があるのでしょうか? k 個の n 行 n 列の三重対角行列を一度に解く方法があればと思うのですが・・・。 >> 467 さん ありがとうございます。人間の仕事まで落としたいのですが、甚だ修行不足で・・・頑張ります。 >> 469 さん、470 さん A を多次元と言ったことは言葉足らずでした。混乱を招きすみません。
473 :
465 :2009/07/22(水) 17:36:55
>>472 > a1_{k, i-1}*f_{k, i-1} + a2_{k, i}*f_{k, i} + a3_{k, i+1}*f_{k, i+1} = g_{k, i}
>
> ここで、
>
> A : n 行 n 列の三重対角行列
> x : f_{k, i} を要素に持つ n 次元の列ベクトル
> b : g_{k, i} を要素に持つ n 次元の列ベクトル
>
> とすると、各モードについて A x = b を解くことになります。A が多次元と言いましたのは、
> このモード数の次元のことを指しておりました。
> モード数が 1 の場合には、紹介して頂いた連立 1 次方程式のルーチンを使えば良いと思うのですが、
> 複数のモード数について解く場合には、毎回サブルーチンを呼ぶ必要があるのでしょうか?
> k 個の n 行 n 列の三重対角行列を一度に解く方法があればと思うのですが・・・。
この中で未知数は x だとして、それでも a1 や a2 がイミフなので勝手に解釈します。
1 <= k, i <= n として
行列 A は固定する(つまり共通)。
縦ベクトル x_i の第 k 成分を f_{k,i} とする。b についても同様。
行列 X を X = ( x_1, x_2, ..., x_n ) で定義する。==> n×n 行列
行列 B を B = ( b_1, b_2, ..., b_n ) で定義する。==> n×n 行列
AX = B を解くということで終わらんか?要するに X = A^{-1}B で計算できるでしょ?
det A = 0 ではないとして。
線型代数のマトモなテキストには書いている話だと思うケド。
474 :
465 :2009/07/22(水) 17:44:47
結局、固有値問題ではないのね? で、私が問題を誤解している可能性は否定しない。莫迦でゴメンね。
>>472 昔のFORTRANならEQUIVALENCEで処理するところだけど、
ModernなFORTRANでは、どうするべ?
476 :
464 :2009/07/22(水) 21:59:49
>> 471 さん > マトリクスやベクトルをあらかじめ何組か準備して、 > 次々に解きたいだけじゃないかと解釈したが。 仰せの通りです。おっしゃる通りに書き換えてみたところ、 無事にライブラリを使うことができました!また、数値解と 解析解との一致も確認しました。 説明不足で大変混乱を招いたことと思いますが、的確なご助言 を頂き、誠にありがとうございました! >> 465 さん 説明不足なのは申し訳なかったですが、この問題は>> 471 さんが おっしゃっているように、「複数の行列 A (n × n 行列) と ベクトル b (n 次元の列ベクトル)の組について、次々に 固有値を求めていく」ということでした。ですので、おっしゃる ように固有値問題でした。 >> 475 さん EQUIVALENCE で、考えている配列から特定の要素を抽出することが できるんですね。これでも同様にできますね。アドバイス頂き ありがとうこざいました。
>>471 の言っていることは、77時代の基本的テクニック。
教科書には明示的には書いてないが、ちょっと複雑なプログラムするときには必ず使う。
他人のプログラムを見て覚えるのが普通のコースだから、2chで聞いてというのは
今風でもっともかな?
何でもいいからつくれといわれたので斜方投射のXY座標を求める プログラムを作ろうとおもったんですが、何度実行してもX座標が負の 値になってしまうのですがなぜでしょうか? PROGRAM VAT IMPLICIT NONE REAL::V,A,T,X,Y WRITE(*,*)'このプログラムは初速度V、角度A方向に斜方投射された物体のT秒後の位置を求めます' WRITE(*,*)'重力加速度は9.8m/s2とします' WRITE(*,*)'初速度V(m/s)を入力してください' READ(*,*) V WRITE(*,*)'投射角度A(ラジアン)を入力してください' READ(*,*) A WRITE(*,*)'T(秒後)を入力してください' READ(*,*) T X=V*COS(A)*T Y=V*SIN(A)*T-9.80619920*T*T/2.0 OPEN(1,FILE='XandY.TXT') WRITE(1,*)'X=',X,'(m)','Y=',Y,'(m)' CLOSE(1) STOP END PROGRAM VAT
>>478 実行結果も貼れ。こちらで試したところ、x 座標は正だった。
あとこの程度のプログラムでわざわざファイルに結果を書き込む理由が分からん。
これは好き好きだけど。
>>478 予想される原因:角度を弧度法ではなく、度数法で入れた
>>479 ラジアンで入れましたが、A=3.141593/3.0で入力しました
>>481 > ラジアンで入れましたが、A=3.141593/3.0で入力しました
それだと 3.141593 で解釈される。結果を比べてみたらいい。
だから cos( A ) = -1.00 となる。
>>482 ほんとだ・・。π/3を表したい場合はどうすればいいんですか?
>>483 >
>>482 > ほんとだ・・。π/3を表したい場合はどうすればいいんですか?
電卓で計算して出た値を直に突っ込むくらいしか思いつかない。
他には敢えて度数法で入れて、中で弧度法に変換するか。
>>484 解決しました。
ありがとうございました
関係ないけど、πって今は3なんだっけ?
>>486 内接正六角形で円周を近似すれば3となる。
根拠なしに妙な数を覚えさせるよりましとも考えられる。
逆に、根拠無くともマジックナンバーを覚えさせるのが重要だという考えもある。
近年の教育界の風潮では、素朴な情緒的な根拠付けを求めて、
それ以外(とりあえず覚えとけ的なものや複雑で論理的なもの)を拒否するので
正六角形で円周を近似させる方向に行くのもさもありなんと思える。
3.14で切れてると思っている輩も居るし、有理数だと思っている輩も居る。
素朴なモンテカルロ法でやっても中々小数点以下二桁までは出ない。
理系でも超越数であることを知らないものは多い。
古代エジプトでは円の面積は直径の(1-1/9)=8/9の自乗とされたが、これだと3.16だったか。
電卓で確認してくれw これはエジプト分数(分子は1)的にはかなりいい値。
実用レベルでは有効数字3桁あればおkって場合が多いから、 3.14と思い込ませるのも悪くないかと思うけど。 数学的素養のない一般人にはそれで十分でしょ。 「円周率?3だろ(キリッ」って言われるよかよっぽど良い。
背後にあるものを隠蔽して気がつかせないようにする教育は理由があっても気に入らないな こういう隠蔽が積み重なってあとで取り返しがつかなくなるんだよ 1度でいいからいろいろな性質があることを説明して、ポカーンとしてるところで 「でも今は君たちにはわからんだろうからおよそ3で覚えてください」 とはっきり言ってくれればおk
>>488 > 理系でも超越数であることを知らないものは多い。
事実として知っては居るが、証明できない。どのような知識が要るんだろう。
超越数って名前だけは知ってるが(あとπとeがそうらしいということも)、 具体的には代数的数ではない、んだっけ、ってことしか知らないな。
超越数って、たしか係数が全て有理数な多項式の解ではないものを言うんだっけ
494 :
デフォルトの名無しさん :2009/08/06(木) 05:28:00
forrtl: severe (67): input statement requires too much data, unit 50 このエラーを解決するには???
>>494 それだけで解決方法が分かったら素晴らしいエスパーだな。
>>494 英語を日本語に翻訳してほしいんですか?
forttl: 深刻 (67): INPUT文が要求するデータ量が多すぎます。 ユニット 50
>>496 その発想は無かった。他に翻訳してくれそうなところ無いかな?
Excite
forrtl: 厳しい(67): 入力文はあまりに多くのデータ、ユニット50を必要とします。
Yahoo!
forrtl:厳しい(67):入力声明は、あまりにたくさんのデータ(単位50)を必要とします
Google
forrtl :重度( 67 ) :入力文、大量のデータが、 50単位が必要
>>494 READ(50,*)
のように書いてあるところの変数の数を疑え
fortran90のallocateに関してですが、メモリ2GBの環境で、 allocatbleの配列A:0.3GB程度、配列B:1.8GB程度、配列C:0.3GB程度を使用するとします。 1)まず、配列Aをallocateし、使用後にdeallocate、 2)次に、配列Bをallocate、使用後に同様にdeallocateを行い 3)最後に、配列Cをallocateし、最終処理を行う。 上記一連の作業であれば、2GBの環境で動作すると考えたのですが、 ○実行すると最後の配列Cのallocateでメモリオーバーで落ちてしまいます。 ○試しに、EM64Tの環境(メモリ8GB)で実行し、topコマンドでチェックしたところ、 確かに最後の配列Cのallocate部分でメモリ使用量が2.1GB程度となっていることが分かりました。 つまり、配列Bのdeallocateを行っても、この部分のメモリが解放されていないということだと思いますが、 配列Bのallocate自体はできているので、配列Aのdeallocateによるメモリ解放はできているということになると思います。 allocatbleの配列でメモリが解放される場合と、されない場合というのはどのような条件で決まるのでしょうか。 (使用コンパイラーはIntel fortran Version 9.1)
質問させてください。 silverfrost FTN95 compilerとcpad for FTN77でコンパイルしようとしているのですが、 うまくいきません。以下のエラーメッセージがでます。 コンパイルに失敗しました ファイル"D:\My Documents\FORTRAN\sample.exe"は存在しません。 メッセージ *** Invalid executable file suffix - only .EXE is permitted どこに原因があるか教えていただけないでしょうか。 まだコンパイルすらしたこと無いド初心者ですが、よろしくおねがいします。
>>501 CPad for FTN77 は名前の通りFTN77用なので、そのままではFTN95では使えない。
どうしてもCPadを使いたければコマンドラインの並びを変えるバッチファイルを間に噛ますか
FTN77をDLしてきて使えば良い。
他のIDEでよければFTN95 Personal Edition に付属のPlatoを使うか(但し日本語未対応)
Visual Studioが付いてきてフリーなFTN95 Expressを使えば良い。
503 :
501 :2009/08/08(土) 03:22:49
>>502 ありがとうございます。
salfordからFTN77をダウンロードできなくなっているようなのでFTN95が使えれば…と思っていたのですが
やはりそこに無理があったようですね。platoを使うことにします。
連続で申し訳ないのですが、質問させてください。
platoで無事コンパイルはできるようになったのですが、コンパイル後にstart(緑の三角)ボタンを押しても
"Press RETURN to close window . . ."と表示されたコマンドプロンプトが開くだけでプログラムが走りません。
exeファイルは生成されているのでそちらから直接起動することはできるのですが、plato上で実行する方法は無いでしょうか。
また、起動したプログラムウインドウが一瞬で勝手に閉じてしまうのですが、表示させたままにしておくことはできますか。
>>503 FTN とかいうのを使ったことが無いので、少し調べてみました。で、分かった範囲のことを元に書きますので
結果は保証できません。
●先ず、どのようなプログラムを書いているか。
例えば例題でよくある2つの整数を入力すると、その和、差、積、商を表示するプログラムだとします。ボタ
ンを押してプログラムを実行すると、入力待ちになる筈です。で、2つの整数を入力すると次の処理に移って
計算をし、結果を表示して、プログラムを終了します。その時点で【プログラムとしてやりたいことが全て終
了して、やることが無くなった】ので、窓を閉じてしまう(とエスパー)。
●じゃぁどうしよっか。
計算結果を表示後に、更に何かを実行させる。例えば
続けて計算しますか?(Y/N)
みたいなので、次の動作を入れる。これだと入力待ちになる(ちゃんと書けばね)ので、窓は出たまま。用が
済んだら N を入力して閉じれば良いし、また別の数でやりたかったら Y を入力すれば良い。C の do while 相
当の処理が FORTRAN に有るのかは知らないけど、goto か無限ループで実現できると思う。
というのは駄目ですか?
お助けお願いします。
「y=x**3-5*(x**2)-2*x+24 のグラフを23行80桁の画面上に描画するプログラムを作成せよ。ただし、次の条件を守れ。
1)描画範囲のx (例 -1 から +6まで)をキーボードから入力し、
その範囲を画面全体に描画せよ
2)描画範囲のグラフが画面に収まるよう、
y軸の描画範囲を自動的に調整せよ。」
という課題をやっているのですが、完全に行き詰りました。
以下にとりあえずやってみたプログラムを
張って行きますので、
皆さんのお力で完成させていただけないでしょうか?
グラフの詳細は↓
ttp://skm.vip2ch.com/-/hirame/hirame051462.jpg に、はっておきました。
何卒、よろしくお願いします。
print *,"最小値は?" read *,readminx print *,"最大値は?" read *,readmaxx ! real function rtransx(i,readminx,readmaxx) real,parameter::readminx,readmaxx real,parameter::crtminx=1.0,crtmaxx=23 integer::i rtransx=((readmaxx-readminx)/(crtmaxx-crtminx))*(i-crtminx)+readminx return end function rtransx real function func(x) real::x func=x**3-5*(x**2)-2*x+24 return end function func integer function transy(y) real,parameter::miny,maxy real,parameter::crtminy=1.0,crtmaxy=80 real::y transy=(crtmaxy-crtminy)/(maxy-miny)*(y-miny)+crtminy return end function transy
program integer::i,iy character*80::line real::x,y do i=1,23 line(1:80)=' ' x=rtransx(i,readminx,readmaxx) y=func(x) iy=transy(y) line(iy:iy)='*' print'(a80)',line end do end program
>>503 > コンパイル後にstart(緑の三角)ボタンを押しても
> "Press RETURN to close window . . ."と表示されたコマンドプロンプトが開くだけでプログラムが走りません。
それでプログラムは走っている。
Plato上でプログラムを走らせると「Plato IDE」というタイトルのウインドウが開いて
そこで画面/キーボードからの入出力を行う。
「Press RETURN to close window . . .」はプログラムが終了すると表示される。
もしそれが望み通りの結果でないのなら、それはあなたのプログラムが間違っているのだ。
> また、起動したプログラムウインドウが一瞬で勝手に閉じてしまうのですが、
エクスプローラ上で実行ファイルをダブルクリックするとそうなる。
コマンドプロンプトから実行すればよい。
fortran最高! 今日で人生が変わった!
あの、
>>505 です・・・
どなたか、アドバイスください。
fortran90を使っています。
513 :
501 :2009/08/11(火) 01:11:27
>>504 ,508
レスありがとうございます!
アドバイスを参考にいろいろと試してみたいと思います。
まずはプログラムの書き方の基本から身につけないといけませんね。
514 :
デフォルトの名無しさん :2009/08/11(火) 03:37:27
Fortranでどうにもならん部分だけCで書いてリンクすればいいしな。 Fortranでやりにくい(出来ないわけではないけどシステム依存が強すぎるからいやだ)部分って Argumentをコマンドラインから取り込むとか、バイナリファイルの読み込みくらいだけど。 ・・・ってf77の話だな。F90や95だとどうなってるんだろう?
>>514 > Argumentをコマンドラインから取り込むとか、バイナリファイルの読み込みくらいだけど。
どっちも普通にできたと思うけど、環境依存大きいの?バイナリファイルの読み書きに関しては C と Fortran では
違いがあるので、成る可く Fortran で済ませてしまった方が良いと思うが…。
ただ市販の Fortran の本でこの辺を説明しているものは見た事が無い。あと倍精度実数も。科学技術計算云々とい
う割にその辺手抜きなのが解せん。そ~いやプリプロセッサの話も書いてないな。洋書は知らんけど。
>>514 STREAM I/O や コマンドライン引数の扱いはFortran2003で規格に入って統一された。
まぁそれ以前もベンダー依存の機能で実現できたが。
>>515 浮動小数点も世界がIEEE754で天下統一されて、かつその機能をFortran2003規格で
Fortran内部からアクセス出来るようになっている。
>>512 いきなり画面に書かずに、まず画面に対応する文字配列に書くといいと思う。
そうすると、座標軸とかキャプションのたぐいも別々に処理できる。
最後に配列を一括で出力する。
昔のマイコンのキャラクター用ビデオRAMの感じ?って言ってもわかんないかなw
お盆までまってくれ。
>>517 > お盆までまってくれ。
アンタ優しいな。
このスレには相当のベテランがいるんだろうな せっかくだから、本とか出版してみたらどうだ? 10万までなら出すw
>>516 これって、浮動小数点のビット配列とか丸め誤差が、
以前は処理系依存だったってこと?
>>515 処理系依存のものは本じゃなくて、
コンパイラのマニュアルを見るしかないんだろうね。
>>520 >これって、浮動小数点のビット配列とか丸め誤差が、
>以前は処理系依存だったってこと?
処理系依存というか、CPUアーキテクチャに依存していたでしょ。
太古のIBM S/360の浮動小数点とか、CDC 7600の浮動小数点とか。
>>521 そうなんですか。勉強になります。
ちょいとググってみたら、
S/360、CDC7600は60年代のメインフレームですね。
(初めてコンピュータ・アーキテクチャの概念が使われたとか、
初めてこれまでモニタと呼ばれていたOSが、
360からOSと呼ばれるようになったとか書いてある)
IEEE754が1985年だから、S/360からおよそ20年後で、
それからさらに20年ぐらいたって、Fortran2003に導入されたということですか。
それはそうと、
処理系がCPUアーキテクチャに特化してるんだから、
処理系依存という言い方はまずいんでしょうか?
>>522 10年前くらいまでは、浮動小数点はベンダー固有のものだった。
IBM、CRAY、DEC、NECとかはそれぞれに固有のフォーマットを持っていた。
IEEEフォーマットが支配的になったのは90年代後半くらいでは無いかな?
SX-3か4あたりは、IEEE(Big,Little Endian)、IBM、CRAYの4つのフォーマットに対応していた記憶がある。
数値コプロがCPUに標準装備される前のパソコンの浮動小数演算はソフトウェア毎に
実装が異なっていて、しかも精度はメチャクチャというのが普通。
Fortran90に精度に関する関数が多いのは、IEEEが普及する前だったため。
>>512 最小値は?
-1
最大値は?
6
| *
|
| *
| *
|
| *
|
| *
| *
| *
|
************** *
*** | *** *
| *** *
| *** *
| *** *
| ** *
| *** **
| ** *
| *** **
| *** **
| **** ****
-----------|----------------------------------**********------------------------
続行するには何かキーを押してください . . .
>>524 セルフアンカー
>>505 寝る前に全く考えずに作ったし、バグ取りしてないw 参考程度に
正直、自分で満足できないww でも休みに遊びに行くことになったので。
間違ってたら、ごめんw でも賠償はしない。
MODULE m_screen
IMPLICIT NONE
!
INTEGER, PARAMETER :: nx = 80, ny= 23
CHARACTER(LEN = 1) :: screen(nx, ny) = ' '
REAL :: valx(nx), valy(nx)
!
CONTAINS
!-----------------------------------
SUBROUTINE calc_range(xmin, xmax, fun)
REAL, INTENT(IN) :: xmin, xmax
INTERFACE
REAL FUNCTION fun(x)
REAL, INTENT(IN) :: x
END FUNCTION fun
END INTERFACE
INTEGER :: i
DO i = 1, nx
valx(i) = (xmax - xmin) * (i - 1) / (nx - 1) + xmin
valy(i) = fun( valx(i) )
END DO
RETURN
END SUBROUTINE calc_range
!----------------------------------- INTEGER FUNCTION iposy(i) INTEGER, INTENT(IN) :: i iposy = NINT( ( valy(i) - MINVAL(valy) ) / ( MAXVAL(valy) - MINVAL(valy) ) * (ny - 1) ) + 1 RETURN END FUNCTION iposy !----------------------------------- SUBROUTINE plot_screen() INTEGER :: ix, iy DO ix = 1, nx iy = iposy(ix) screen(ix, iy) = '*' END DO RETURN END SUBROUTINE plot_screen !----------------------------------- SUBROUTINE print_screen() INTEGER :: iy DO iy = ny, 1, -1 PRINT '(80A1)', screen(:, iy) END DO RETURN END SUBROUTINE print_screen !-----------------------------------
SUBROUTINE plot_xaxis() ! INTEGER :: ix, iy, k(1) IF ( MINVAL(valy) * MAXVAL(valy) < 0 ) THEN ! cross x-axis k = MINLOC(valy) iy = iposy(k(1)) DO ix = 1, nx screen(ix, iy) = '-' END DO END IF RETURN END SUBROUTINE plot_xaxis !----------------------------------- SUBROUTINE plot_yaxis() ! INTEGER :: ix(1), iy IF ( MINVAL(valx) * MAXVAL(valx) < 0 ) THEN ! cross y-axis ix = MINLOC(ABS(valx)) DO iy = 1, ny screen(ix(1), iy) = '|' END DO END IF RETURN END SUBROUTINE plot_yaxis !----------------------------------- END MODULE m_screen
!===================================== PROGRAM graph USE m_screen IMPLICIT NONE REAL :: read_minx, read_maxx ! PRINT *, "最小値は?" READ *, read_minx PRINT *, "最大値は?" READ *, read_maxx ! CALL calc_range(read_minx, read_maxx, func) CALL plot_xaxis() CALL plot_yaxis() CALL plot_screen() CALL print_screen() STOP CONTAINS !------------------------------------- REAL FUNCTION func(x) REAL, INTENT(IN) :: x func = x**3 - 5 * x**2 - 2 * x + 24 RETURN END FUNCTION func !------------------------------------- END PROGRAM graph うざくて、ごめんw
ごめw バグってるw X軸がちゃんと書かれない。 SUBROUTINE plot_xaxis() INTEGER :: ix, iy, k(1) IF ( MINVAL(valy) * MAXVAL(valy) < 0 ) THEN ! cross x-axis k = MINLOC(ABS(valy)) ~~~~~~ ABS( ) が抜けてた。入れといて。 連続投稿規制でかけない 汚しすまそ
>>524 ~
>>529 さん
ありがとうございました!
凄いです・・・
このスレは猛者の集まりですw
実行してみたところ、完璧に動きました。
まだまだ、私が知らない構文がいっぱいあるんですね!
これを元に、またちょっと勉強してみたいと思います。
本当に、ありがとうございました。
531 :
デフォルトの名無しさん :2009/08/17(月) 05:06:52
まったく関係ないが・・・ gfortranをVistaにいれてみた。 gfortran関連のpathを一番前に持ってこないと、実行ファイル作成リンクで落ちた。 ん~、なんだか。まあ自宅PCであそぶには十分か。OpenMPできるし。
Fortran の話ではないけど、PATH が異様に長いときに PATH の末尾に追加すると上手く動かない という話は聞いたことがある。Windows は色々とメンドクサイよね。もう使ってないから知らな いけど。
autoexe.bat なくしたのは失敗な気もするなあ。 せめてpath管理だけはテキストファイルで「も」出来る仕様を残しておいてほしかった。 Ghostscript、Latex入れると自然とパスが長くなるし。 Fortranの話でないけど・・・
まあ、バッチファイルとかsetxとか使えばそれなりに管理できる > PATH
でも若い人はそういうことを何処で学ぶんだろう。Windows 嫌いで使わない私には ほぼどうでも良いことだが。
>>534 そうそう。自分はgfortran用とlatex用の2つバッチ作ってる。Me以降はpathの管理が面倒だしね。
・・・・・なんだかwin3.1かDOS5.0の頃に戻ったようだw
setx.exe は使いかたがよくかわんないから使ってないけど、便利?
>>535 Win嫌いな人だとかえってPath関連は熱心になるんじゃないかなぁ?
どうだろう。
537 :
536 :2009/08/20(木) 03:42:55
gfortran -Wall foo.for で文句を言ってこなくなるまでソースを訂正すると、 他のシステムでもちょびっと速くなる気がする。気がするだけかもしれないけど。 gfortranって中で何やってるのかいまいちよくわからん。
>>537 -Wall の意味を考えると、気のせいだと思う。でも最低限 -Wall は付けている。
539 :
デフォルトの名無しさん :2009/08/21(金) 13:39:17
vineにintel fortran Compilerとmkl10.2.1インストールして、 ユーザーズガイド通りに環境変数を設定。 でlapac95をビルドした後サンプルのコードをコンパイルしようとするとエラーでます。 ifort gesv.f90 -L -I-lmkl_lapack95 -lmkl_intel -lmkl_thread -lmkl_core -lguid -lpthread gesv.f90(31): error #7002: Error in opening the compiled module file. Check INCLUDE paths. [MKL95_PRECISION] USE MKL95_PRECISION, ONLY: WP => SP ----------^ gesv.f90(32): error #7002: Error in opening the compiled module file. Check INCLUDE paths. [MKL95_LAPACK] USE MKL95_LAPACK, ONLY: GESV ----------^ gesv.f90(39): error #6683: A kind type parameter must be a compile-time constant. [WP] REAL(WP), ALLOCATABLE :: A(:,:), AA(:,:), B(:,:), BB(:,:) -----------^ gesv.f90(64): error #6406: Conflicting attributes or multiple declaration of name. [GESV] CALL GESV( A, B ) -----------^ gesv.f90(71): error #6406: Conflicting attributes or multiple declaration of name. [GESV] CALL GESV( AA, BB(:,1), IPIV, INFO ) -----------^ gesv.f90(31): error #6581: Unresolved rename. [WP] USE MKL95_PRECISION, ONLY: WP => SP ---------------------------------^ gesv.f90(32): error #6580: Name in only-list does not exist. [GESV] USE MKL95_LAPACK, ONLY: GESV ------------------------------^ compilation aborted for gesv.f90 (code 1) 何がいけないんでしょうか?よろしくお願いします。
>>539 >Error in opening the compiled module file. Check INCLUDE paths. [MKL95_PRECISION]
>>539 > vineにintel fortran Compilerとmkl10.2.1インストールして、
> ユーザーズガイド通りに環境変数を設定。
>
> でlapac95をビルドした後サンプルのコードをコンパイルしようとするとエラーでます。
lapack95 は自前でビルド?
> ifort gesv.f90 -L -I-lmkl_lapack95 -lmkl_intel -lmkl_thread -lmkl_core -lguid -lpthread
gfortran しか使わんので、この辺は知らん。
> -----------^
> gesv.f90(64): error #6406: Conflicting attributes or multiple declaration of name. [GESV]
> CALL GESV( A, B )
> -----------^
> gesv.f90(71): error #6406: Conflicting attributes or multiple declaration of name. [GESV]
> CALL GESV( AA, BB(:,1), IPIV, INFO )
> -----------^
これは明らかに可笑しくないか?そんな名前のサブルーチンは lapck にあるかどうか知らんが。
ウチに入れた lapack だと少なくとも man では引っ掛からなかった。
542 :
デフォルトの名無しさん :2009/08/21(金) 14:28:36
>>540 /opt/intel/mkl/10.2.1.017/include/にINCLUDE path通してます。
コンパイル時に必要なファイルは.modのファイルですか?
/opt/intel/mkl/10.2.1.017/include/32の中に
lapack95関係の.modのファイルが入ってるんですがそっちにパス通してもうまくいきませんorz
544 :
デフォルトの名無しさん :2009/08/21(金) 14:37:34
>>541 lapack95のビルドもユーザーズガイドにあった通りにしたんで、たぶんできてるはずです。
自前というのはどういう意味ですか?
opt/intel/mkl/10.2.1.017/examples/lapack95/source/内のサンプルコードなんでサブルーチンはあるはず?
545 :
デフォルトの名無しさん :2009/08/21(金) 14:42:34
export MKLROOT="/opt/intel/mkl/10.2.1.017" if [ -z "${INCLUDE}" ] then export INCLUDE="${MKLROOT}/include" else export INCLUDE="${MKLROOT}/include:$INCLUDE" fi ・ ・ ・ /opt/intel/mkl/10.2.1.017/tools/environment/mklvars32.shを実行すれば、 環境変数設定されるみたいにユーザーズガイドに書いてあったんですけど、 実行しても設定されないようなので上の文を.bash_profileにつけたしました。
546 :
541 :2009/08/21(金) 14:48:44
547 :
デフォルトの名無しさん :2009/08/21(金) 14:57:32
>>546 ソースは元々あって、それを自分でmakeしました。
リンクするっていうのはコンパイルのときの例えば-lmkl_lapack95とかのことですか?
そのホームページも見てやってみたんですが・・・
もうちょっとやってみます!!
548 :
541 :2009/08/21(金) 15:11:42
>>547 >
>>546 > ソースは元々あって、それを自分でmakeしました。
> リンクするっていうのはコンパイルのときの例えば-lmkl_lapack95とかのことですか?
そです。
それはそうと
echo $INCLUDE
の結果って、問題ないですか?設定さえチャンと出来ていれば、後はマニュアル通りにしたら
出来るはずなんですけどね。そのマニュアルってフリーで転がってんのかな。
エラーの中身見たら設定が出来てないようにも見えるけど…気のせいかな?
>>541 > これは明らかに可笑しくないか?
この部分、実は問題無いみたいですね。でもこれ、私にはとっても変態な仕様にしか見えない。
90 は余り使わないから、そう思うのかもしれない。そろそろ 90 もリハビリした方が良さそう。
再帰を書けるのは知っているけど書き方知らないし。
探せば他にも出て来ると思いますヨ。> 纏めページ
549 :
デフォルトの名無しさん :2009/08/21(金) 15:30:57
550 :
541 :2009/08/21(金) 16:03:10
書いてたら凄く長くなりました。他の皆さんスイマセン。
>>549 > echo $INCLUDEの結果は /opt/intel/mkl/10.2.1.017/include
> これで大丈夫ですか?
それが正しいかどうかは、mklvars32.sh が無いのでなんとも。晒さなくていいですよ。
やると問題になりそうですし。
あと、気になったんですが、コンパイル時のコマンドの書式はどこから拾って来たのですか?
私が先に挙げたリンク先のサンプルでは
$ ifort /opt/intel/mkl/10.1.0.015/examples/lapack95/source/gesv.f90
-L/opt/intel/Compiler/11.0/074/mkl/examples/lapack95/lib/em64t/
-I /opt/intel/Compiler/11.0/074/mkl/examples/lapack95/lib/em64t
-lmkl_lapack95 -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -lguide -lpthread
$ ./a.out < /opt/intel/Compiler/11.0/074/mkl/examples/lapack95/data/gesv.d
となっています。$ はプロンプトです。ここでは見易さのために改行して引用していますが、実際は改行無し。
バージョンのことはキニシナイ。
-lmkl_lapack95 ということは、libmkl_lapack95.a というファイルが何処かに在る。
多くの場合は -L で指定しているディレクトリになる。
(続く)
551 :
541 :2009/08/21(金) 16:06:20
(続き)
>>549 > 4章のAutomating the Processでmklbars32.sh実行すればいいとあるのですが、
> 実行してもダメみたいで、mklbars32.sh内のソースを.bash_profileにコピペしました。
そんなこと書いてないみたいですが?
In the above commands, mklvars<arch> stands for each of mklvars32, mklvarsem64t
or mklvars64.
だから
. <absolute_path_to_installed_MKL>/tools/environment/mklvars<arch>.sh
の mklvars<arch>.sh は mklvars32.sh か mklvarsem64t.sh に読み替えればいいのでは?最初の . は必要ですヨ。
553 :
デフォルトの名無しさん :2009/08/21(金) 16:51:46
>>550 -Lで指定しているディレクトリにパスを通してる(echo $PATHで表示される)ので、
-Lと-lの後のフォルダの指定は省いてるんですがダメですか?
コンパイルのコマンドは挙げていただいたサイトのをちょっといじって書きました。
ifort gesv.f90 -L -I-lmkl_lapack95 -lmkl_intel -lmkl_thread -lmkl_core -lguid -lpthread
>>551 最初の.が抜けてました。ありがとうございます。
>>552 linuxいじってる奴もfortran使いもいないんですwwwwwwwwwwwwww
やっぱりエラーなりますorz
何がいけないのか・・・
554 :
541 :2009/08/21(金) 19:18:08
>>553 >
>>550 > -Lで指定しているディレクトリにパスを通してる(echo $PATHで表示される)ので、
> -Lと-lの後のフォルダの指定は省いてるんですがダメですか?
ダメです。環境変数 PATH は ls や gcc、make などのコマンドが在るディレクトリを登録するものです。
なので、ここに何を書いていようとライブラリは無関係。普通はね。
>
>>552 > linuxいじってる奴もfortran使いもいないんですwwwwwwwwwwwwww
>
> やっぱりエラーなりますorz
> 何がいけないのか・・・
-L などを抜いたことが原因でしょうね。それだけが原因ではない気もしますが。コンパイラによって違います
が、-v または -V というオプションを付けてコンパイルすると、ライブラリなどの検索ディレクトリを表示し
ます。コンパイルもしますが、そういうものを画面に表示します。まぁ見てみると良いと思います。
で、デフォルトで登録されていない所に在るライブラリなどはコンパイル時に自分で指定しないとリンクして
くれません。しなかった場合は、そんなもの無いということでコンパイルに失敗します。例えば私の環境だと
/opt/lib に liblapack.a と libblas.a が在ります。標準的には /opt/lib なんて登録されませんし、登録する方法
も知りません。lapack のサブルーチンを使っているソースをコンパイルするときは
$ gfortran sample.F90 -L/opt/lib -llapack -lblas
とします。こうすることで、/opt/lib に在る liblapack.a と libblas.a をリンクするしろ、と指定しています。
スレ違いで恐縮ですが、どのライブラリにどのサブルーチンや関数が入っているか調べる方法ってありますか?
>>545 > /opt/intel/mkl/10.2.1.017/tools/environment/mklvars32.shを実行すれば、
> 環境変数設定されるみたいにユーザーズガイドに書いてあったんですけど、
> 実行しても設定されないようなので上の文を.bash_profileにつけたしました。
shellがbashなら .bash_profile に
source /opt/intel/fc/<IFCのバージョン>/bin/ifortvars.sh
source /opt/intel/mkl/<MKLのバージョン>/tools/environment/mklvars32.sh
を追加しとけ。
MKLは(IFCも)バージョンUP時にディレクトリ構成や必要なライブラリが変わることがあるんでヤヤコシイわ。
>>555 こんなんではダメですか?
% nm liblapack.a | head -20
liblapack.a(sgbbrd.o):
U _lsame_
00000000 T _sgbbrd_
U _slargv_
U _slartg_
U _slartv_
U _slaset_
U _srot_
U _xerbla_
U dyld_stub_binding_helper
liblapack.a(sgbcon.o):
U _isamax_
U _lsame_
U _saxpy_
U _sdot_
00000000 T _sgbcon_
U _slacon_
U _slamch_
>>556 勉強になります。ウチの Debian は1年ほど前に急に起動しなくなってから放置してますが。
>>558 それで問題なかったのなら何よりです。
使わないライブラリってリンクしたらまずいですか? サイズが大きくなって多少遅くなる?
561 :
デフォルトの名無しさん :2009/08/21(金) 21:27:53
>>554 丁寧に説明していただきありがとうございます。
やってみましたがなぜかエラーですwwwwwwwwwwwwww
>>556 環境変数の設定はできてるみたいです。ありがとうございます。
みなさんありがとうございました。もうちょいがんばってみようと思います。
確認したいんだけど、せいぜい Hello, world. を表示する程度のソースは 無事にコンパイルできる?ここで転けてたら話にならない。
563 :
デフォルトの名無しさん :2009/08/21(金) 23:22:39
>>562 簡単なソースのコンパイルはできます。
mklとリンクしてコンパイルすると、.aと.soファイル内に、
定義されてないサブルーチンを使用しようとしていますとか警告出ます。。
>>563 > mklとリンクしてコンパイルすると、.aと.soファイル内に、
> 定義されてないサブルーチンを使用しようとしていますとか警告出ます。。
これは簡単なソースをコンパイルするときに出るの?簡単なソース(Hello, World. 程度)と
ライブラリをリンクするときに出るのであれば設定が可笑しいと思う。それかコンパイル時
のコマンドの書き方か。両方の可能性もあるけど。
普通は、リンクするライブラリの中にある関数を使っていなくても、そんなことにはならな
い。例えば sin( 1.00D0 ) を計算して表示するだけのソースと FFT のライブラリをリンクし
ても文句は言われない。コンパイラはスルーすれば済むから。呼んでもないものをくっ付け
る必要は無い。
MKLのUser’s Guideに環境別に必要なライブラリファイルと使い方の例が載ってるから その通りにやればコンパイル/リンクできるはずだが。
566 :
デフォルトの名無しさん :2009/08/22(土) 10:01:37
>>564 /opt/intel/Compiler/11.1/046/mkl/lib/32//libmkl_lapack.so: undefined reference to `mkl_serv_load_fun'
/opt/intel/Compiler/11.1/046/mkl/lib/32//libmkl_lapack.so: undefined reference to `mkl_serv_load_dll'
/opt/intel/Compiler/11.1/046/lib/ia32/libiomp5.so: undefined reference to `___tls_get_addr'
このエラーが出ます。
リンクするときって.aと.soは混ぜない方がいいんでしょうか?
>>565 その通りにやってるつもりなんですが・・・
>>566 コンパイル時のコマンドを晒して。
あとリンクの順番を間違えるとエラーになることがある。要するに
ライブラリ A と B をリンクするとき A が B にある関数を呼んでい
るなら、例えば A の中にある関数 funcA がその中で B の中にある
関数 funcB を呼んでいるとき
-lA -lB
という順番でリンクしないと転ける。
リンクするときは .a だけで良いはず。あとは勝手にやるはずなん
だけどライブラリに依るかもしれんので何も。
マニュアル通りにしていると言う割には勝手なことをしている気が
する。
568 :
デフォルトの名無しさん :2009/08/22(土) 10:25:02
>>567 ifort test.f90
-L/opt/intel/Compiler/11.1/046/mkl/lib/32/
-I/opt/intel/Compiler/11.1/046/mkl/include/ -I/opt/intel/Compiler/11.1/046/mkl/include/32/
-lmkl_lapack95 -lmkl_lapack -Wl,--start-group
/opt/intel/Compiler/11.1/046/mkl/lib/32/libmkl_intel.a
/opt/intel/Compiler/11.1/046/mkl/lib/32/libmkl_intel_thread.a
/opt/intel/Compiler/11.1/046/mkl/lib/32/libmkl_core.a
-Wl,--end-group -liomp5 -lpthread
ちなみに簡単なソースでリンク無しだとコンパイルできます。
lapac95は.aなんですけどlapackは.soです。
ググってみたら全部.aでやる必要があるみたいです。
が、lapackの.aファイルがないんですが、勝手に持ってきてlibフォルダにいれていいんでしょうか?
569 :
デフォルトの名無しさん :2009/08/22(土) 10:44:08
>>567 ifort test.f90
-L/opt/intel/Compiler/11.1/046/mkl/lib/32/
-I/opt/intel/Compiler/11.1/046/mkl/include/
-I/opt/intel/Compiler/11.1/046/mkl/include/32/
-lmkl_lapack95
-Wl,--start-group
/opt/intel/Compiler/11.1/046/mkl/lib/32/libmkl_intel.a
/opt/intel/Compiler/11.1/046/mkl/lib/32/libmkl_intel_thread.a
/opt/intel/Compiler/11.1/046/mkl/lib/32/libmkl_core.a -Wl,--end-group
-liomp5 -lpthread
-libmkl_lapackいらないみたいです。
これでコンパイルしようとすると以下のエラーが出ます;
/opt/intel/Compiler/11.1/046/lib/ia32/libiomp5.so: undefined reference to `___tls_get_addr'
>>568 >
>>567 > ifort test.f90
(長いので中略)
> -Wl,--end-group -liomp5 -lpthread
このようにしなさいという説明は何処にあるのでしょう。
> が、lapackの.aファイルがないんですが、勝手に持ってきてlibフォルダにいれていいんでしょうか?
ということはビルドしていないということでは?やり方はマニュアルに書いているはず。因みに無いという
根拠はなんですか?それと
find /opt/intel -name "libmkl_*.a"
の実行結果は?
http://www.obihiro.ac.jp/~suzukim/masuda/ifc_lapack31.html にも書いていますが、LAPACK95 はラッパーのようなので、単体では動かないと思います。勝手に持って
来るったって何処から持って来るのだろう。そんなことしても意味ないと思うケド。あと
> -lmkl_lapack95 -lmkl_lapack -Wl,--start-group
これって BLAS はリンクしてないみたいだけど、しなくて良いの?
571 :
デフォルトの名無しさん :2009/08/22(土) 10:52:24
>>570 >このようにしなさいという説明は何処にあるのでしょう。
ユーザーズガイドのexampleにありました。
>find /opt/intel -name "libmkl_*.a"
lapack95.aはあります。.soはありません。逆にlapac.soはあって.aはありません。
lapack95のビルドはしました。が、.soはないです;
BLASリンクしてもダメでした;
>>569 > これでコンパイルしようとすると以下のエラーが出ます;
>
> /opt/intel/Compiler/11.1/046/lib/ia32/libiomp5.so: undefined reference to `___tls_get_addr'
iomp5 って OpenMP 用のものみたいだから、並列でもしない限りイラネ。と思うけど、どうなんだろ?
ということで、外してやってみて。
取り敢えずオプション付けとけって感じにしか見えない。それぞれのオプションの意味を調べ直した方が
早い気がして来た。どっかに日本語版も落ちてたし。場所は忘れた。
横からだけど、なんでも OpenMPのオプションを付けるといくつかのオプションを呼び出すことになって 非OpenMPでも最適化にプラスに作用するので 弊害がなければ付けておくといいよ、と奨められたことがある。 なくても良さそうだけど・・。
>>573 そんな話があるんですね。だったら最初から最適化しとけよ、と思わなくもないですが。
ずっと疑問なんですけど、元質問者ってそもそも何がしたいんだろう。
Fortran の勉強または単に Lapack を使う必要があるという程度なら、gfortran でも使っていれば良い。
Lapack なんてディストリビューションの公式ビルド(?)もあるだろうから、準備には手間取らない。
Debian なら Synaptic でも起動して検索すれば良いし、CentOS なら yum かな。
それでも基本的な知識が欠けているように見えるけど、考え過ぎかな。PATH の話を読んだときは噴き
ました。こちらが立ち入る話ではないんですが、何となく迷走しているように見えたので。
>>573 それってopenmp以外のオプションを何も付けてない場合じゃないの?
-fastや-O3などの普通の最適化オプションを付けている状態でopenmpオプションを足しても意味ないような
openmp つけると明示的に抑制しなければ auto やら (p)thread やらほかのも呼ぶはずけど、 どうだろうね。openmp 単独では最適化はデフォルトレベル以上はしないからどのみち -fast あたりと いっしょに使う前提だろうけど。
たぶん最適化されて速くなる、というよりは アドレスがらみのエラーが防げそう、とか 古い習慣のsave属性を仮定しないで処理する、とかがメリットなのではなかろうか。
578 :
デフォルトの名無しさん :2009/08/23(日) 09:35:37
>>572 iomp5外したらlapackとか使わない簡単なソースはコンパイルできました!!!
が、exampleのソースをコンパイルできないです。。。やっぱり同じエラーでます。。。
>>574 今やりたいことは逆行列求めるだけなんでlapackだけでいいし、
それぐらい自分で本見てプログラミングしろよって話なんですけど、
後々並列とかも使えるようにしたいのでmklを入れようとしたのです。
2週間ぐらい前に初めてvineインストールして、
環境変数とかも最近知ったので知識はまったくありませんorz
580 :
デフォルトの名無しさん :2009/08/23(日) 12:03:07
>>579 あああぁぁぁああああFedoraいれてみます!!!!
みなさんありがとうございました!!!
>>578 > が、exampleのソースをコンパイルできないです。。。やっぱり同じエラーでます。。。
エラー内容は分からんが設定が出来ていないか、コンパイル時の指定にミスがあるかのどちら
かだろう。
>
>>574 > 今やりたいことは逆行列求めるだけなんでlapackだけでいいし、
> それぐらい自分で本見てプログラミングしろよって話なんですけど、
> 後々並列とかも使えるようにしたいのでmklを入れようとしたのです。
だったら gfortran でいい。並列も出来る。MPI が使えることは確認済み。OpenMP は知らん。
使ってる PC に複数の CPU があるのなら並列で動かす努力に意味もあるが、マトモに Fortran
のコードを書けないうちから並列をやり始めても先に進めないまま時間が過ぎるだけのような
気がする。
知識も無いのに無理して intel を使う必要は無い。
ということで、自分でソース書けばよろし。あと Lapack のルーチンは処理内容に対して命名
規則があるので、それは自分で調べること。
しかし逆行列を求める程度のことで並列するヤツは居ないと思うが、そうでもない?>識者
>>581 スパコンのLinpack競争を知らんのかw
>>582 知りません。
並列については無知なので、だいぶイイカゲンなことを言っているとは思い
ます。でも3×3行列程度で並列というのはそれ自体がナンセンスな気はしま
す。3 が 10 でも 100 でも同様かと。100000 程度になれば意味はあるのか
もしれませんが。元質問者がどの程度の規模のことをしたいのかによって選
択肢も変わって来るでしょう。
そもそも Lapack って並列を意識して書かれてないと思いますが、そんなこ
とはないとか?
私は並列はやったことが無いですし、この先もやらないと思います。以前に
gfortran で MPI が動くことを確認したときも、リンクの仕方は私が調べて
から、「リンクの仕方は知らないけど、実行の仕方は知っている」コーハイ
君に簡単なプログラムで実行確認をしてもらっただけです。そのコーハイ君
はマトモなソースを書けな(ry
対象データを N 分割して、N 個の CPU に振り分け、個々の CPU で計算した
後に、それを1箇所にかき集めるというイメージしか無いです。間違ってる
かもしれませんが。
難しい話じゃなくて、サイズがでかけりゃ並列化するでしょ普通 問題は行列の性質。密行列なのか疎なのか、とか
>>583 逆行列計算にこそ並列化の最適化が進んでいる。
MKLなんか使えばCPU数に比例した効果が得られる。密行列だが。
そういう意味で、質問者は一応理にかなっている。
逆行列計算は、普通線形方程式を解く形で求めるが、線型方程式はアメリカの分散型の
スパコンに非常に向いていて、自分に有利なようにLINPACKという線形方程式用のパッケージで
スパコンベンチマークが行われている。
当然、その部分へのアルゴリズム研究や最適化がもっとも進んでいる。
ちなみに、おおよそLAPACK=LINPACK+EISPACK。LINPACKは線形演算、EISPACKは固有値演算
ライブラリで、1970~80年代の米英国家プロジェクトの産物。原型はFORTRAN66で書かれていて
NETLIB辺りに行けば今も拾えるはず。LAPACKは、それをFORTRAN77で統合したもの。
詳細は忘れたので間違ってるかもしれん(笑)LAPACKの前書きあたりを詳しく読んでくれ給へ。
これらの基底にBLASという基本サブルーチン集があって、この部分を書き換えることで
ハードウェアのアーキテクチャーの違いをうまく吸収して何十年も生き残っている。
なるほどそういう背景だったのか
GotoBLAS って、そのBLASを後藤さんが最適化したものなの?
LAPACKって疎行列も対応してるの? 密より疎のほうが一般的だよな
>>587 そのはず。
昔はベンダーがよくBLASだけアセンブラで最適化したのを配っていた。
ベクトル機時代はBLAS2あたりの行列*ベクトルが、今はBLAS3あたりの
行列*行列の最適化が肝らしい。
>>588 元々は密行列のみ。scaLapackとか、疎もじわじわやっている。
疎行列はベクトル機に向いていたので80年代以降すごく流行った。
数値計算のアルゴリズムも、ハードウェア・アーキテクチャに合わせて流行が変わる。
最近の並列計算機の進歩のせいで、たとえスカスカの疎行列でもメモリーに載るなら、
密に展開して密行列のライブラリを呼んだほうが有利なことがあるらし。
アメリカ人が必死になって分散メモリー・スパコン用のアルゴリズム開発をしている。
固有値問題も教科書的にはO(N^3)だが、並列機で密行列のO(N^2)のアルゴリズムが
見つかったとかいう話。詳しくは知らん(笑
590 :
589 :2009/08/23(日) 19:35:34
なぐり書いたがscaLapackは疎じゃなかったな。 上記は、話半分嘘半分で読んでおいてくれ(笑)
>>589 > 最近の並列計算機の進歩のせいで、たとえスカスカの疎行列でもメモリーに載るなら、
> 密に展開して密行列のライブラリを呼んだほうが有利なことがあるらし。
これってどんなメリットがあるの?
単純にメモリー消費の事考えると、無駄多すぎて話にならんし。
構造格子のFDMを例に取ると、隣接点が6だから、
マトリクスのサイズが100万だと、メモリー効率が16万倍くらい違う。
(本当はポインタやらあるけど、単純化すると)
それを帳消しにするだけのメリットというのがわからんのだけど。
>>591 スピードつーものは考えんのか?
スパースったって色々あるだろが、お前の帯行列だけがスパースなのかよ。
つーか帯行列は帯行列で別のカテゴリになってるだろ。
あんた相当頭が固くて視野が狭いから、お刺身の上にタンポポを載せるような仕事のほうが向いてると思うよ。
正しいことを言っているのに書き方一つで尊敬されなくなる好例 最近はメモリのペナルティーが大きすぎるから10倍ぐらい計算量が多くても ストールしないアルゴリズムを選んだ方が速くなるという話の一環だと思う
594 :
591 :2009/08/25(火) 11:27:29
> たとえスカスカの疎行列でもメモリーに載るなら、
> 密に展開して密行列のライブラリを呼んだほうが有利なことがある
の根拠は、
> 最近はメモリのペナルティーが大きすぎるから10倍ぐらい計算量が多くても
> ストールしないアルゴリズムを選んだ方が速くなるという話の一環だと思う
とういう話があるということか。なるほど。
ただ、これってかなり特殊なマトリクスに限定した話の気がするな。
物理シミュレーションの世界で出てくるスパース行列だと、
離散点の値を使って平衡方程式解くときには、微小領域近傍の値だけを使うので、
一行あたりの非ゼロ項の個数はせいぜい数十~数百のオーダーになるのが普通。
大規模なスパース行列だと10倍どころじゃなく超スカスカになるんで、
上記の根拠をもとにスパースを密行列で置き換えるのは難しいと思う。
と書くと、また頭が固いとか視野が狭いとか言われてしまうかw
>>592 プライド傷つけてごめんねw
595 :
デフォルトの名無しさん :2009/08/26(水) 18:45:09
大学の研究室でfortranを使い始めたんですけど、 プログラム1で出力した座標データを プログラム2でもう一度読み込みたいのです。 データの受け渡しの際に、x,y,z のように一行に三つの数字が並んでしまっている状態なのですが、 1.プログラム1において出力する座標データの桁数をそろえて座標データファイルを作り、 2.プログラム2において座標データファイル内のx,y,zの3つの数字をそれぞれ関数に読み込みたい と思っているのですがプログラム1のwrite文とread文をどのように書いてよいかが分からず困っています。 どなたか教えていただけますでしょか?
read(unit=11,fmt='(3(x,f10.5))') x,y,z write(unit=11,fmt='(3(x,f10.5))') x,y,z とか、かな。fmt= はなくてもいい。 複数の連続する空白はひとつの区切りとみなされるから 読み込む側では書式指定は必要でないから write(unit=11,fmt=*) x,y,z でも可。数字の11の部分は適当に自分で決める。
597 :
デフォルトの名無しさん :2009/08/27(木) 15:16:39
>>596 さんありがとうございます!
さっそく試してみます。
>>594 まぁそうだわな
> たとえスカスカの疎行列でもメモリーに載るなら、
> 密に展開して密行列のライブラリを呼んだほうが有利なことがある
は、せいぜい10^3以下のちっこいマトリクスにしか当てはまらんと思う
応用の人達にとってマトリクスソルバの開発・実装に時間なんて割きたくないし
数値計算の研究者には大いに頑張ってもらいたいね
Lapack スレとかあったらどんな具合に荒れるんだろうなどと考えてしまった。
荒れてるうちに入らんだろこんなの
CLAPACKのスレならシミュレーション板にあるw
fortran 90/95にはCのqsortのような汎用ソート関数は無いのでしょうか? Cのqsortはvoidポインタやら関数ポインタやら使ってるからfortranではやはり無理なのでしょうか?
subroutineを呼び出すときに、 ・ ・ IF ((N.eq.3950).or.(N.eq.2050).or.(N.eq.50)) THEN CALL DIST(N) END IF ・ ・ ・ SUBROUTINE DIST(N) ・ ・ だと普通に呼び出せるんですが、 IF ((N.eq.3950).or.(N.eq.2050).or.(N.eq.50)) THEN CALL DIST(N,M) END IF ・ ・ SUBROUTINE DIST(N,M) とすると「実引数の数は仮引数の数より多く出来ません」(callの行にエラー)と怒られます。 N,Mはそれぞれ暗黙の型宣言による整数で、念のためちゃんと宣言してみても同じエラーが出てコンパイルできません。 整数型2個で同じなはずだと思うんですが… ちなみに呼び出す側も別のサブルーチンの一部で、どちらも多くのmoduleをuse文で使ってますが関係ないですよね? 今のところ仕方ないんで別にmodule文を作って変数を共有してますが、何か気持ち悪いので考えられる原因を教えて頂けますか?
>>604 エラーメッセージを素直に解釈すると、サブルーチンの宣言で引数が1個しかないので
齟齬が生じていると言っている。
SUBROUTINE DISTの宣言の数行を貼ってもらえれば、なにか分かるかも。
>>605 うーん。でも下の例ではN,Mの二つを取ってるんですが。
>>SUBROUTINE DISTの宣言の数行
というのはこのサブルーチンの中の変数とかの宣言部ということですか?
SUBROUTINE DIST(N,M)
use cell
use sample
use comp
use gas
DOUBLE PRECISION VEL(3),T,TROT,DBOLTZ
use文は単に変数の定義を行っているmodule文に対するもので、
呼び出し元でも同様にuse文で参照してます。
DOUBLE PRECISION...の部分は呼び出し元にはありません。
>>606 わからんw
中間MODファイルが更新されてないとか、ありえなさげな事しか思いつかない。
まぁDIST2222とかありえ無そうな名前に変えて見てようすを見てみるとか。
>>607 MODファイルの事は思ったな~。念のため別なディレクトリでテストするとか・・・かな。あとは
IF ((N.eq.3950).or.(N.eq.2050).or.(N.eq.50)) THEN
CALL DIST(N,M)
END IF
を、
IF ((N.eq.3950).or.(N.eq.2050).or.(N.eq.50)) CALL DIST(N,M)
だけにするとか、
IF ((N.eq.3950).or.(N.eq.2050).or.(N.eq.50)) THEN
Iminashi=1
1374 continue
CALL DIST(N,M)
END IF
みたいに結果に影響しない行を一つ二つ添えてみるとか。う~ん。
>>607 >>608 ホンットすみません。DIST2222にしたら通りました。んで、OS再起動して元の名前にしても通りました。
なんかの理由で「中間MODファイルが更新されてない」になってたっぽいです。
プログラム上の問題じゃなかったですね…申し訳ない。
初心者ですみませんが質問させてください。 LINUXでintelのコンパイラ11をインストールしたのですが、 ifort 実行ファイル で命令すると、次のようなエラーが出てしまいます。 error while loading shared libraries: libstdc++.so.5: cannot open shared object file: No such file or directory ifort: error #10273: Fatal error in /opt/intel/bin/ia32/fortcom, それぞれ指定されたファイルを見てもよくわからなかったので、 どうしたらコンパイルできるようになるか、ご教授おねがいいたします。
>>610 ただLINUXと表現するのではなくて、
ディストリビューションとバージョンをさらすといいかもしれない。
612 :
610 :2009/09/18(金) 13:27:34
ubuntu 9.04 です。お願いします。
>>610 「intelコンパイラが想定しているc++の標準ライブラリより新しいものが入ってる」
に一票
どっかから, libstdc++.so.5を拾ってくるしかないと思われる
# これ以上は聞かないで, 犬のことはくわしく知らないw
614 :
デフォルトの名無しさん :2009/09/18(金) 13:55:39
>>610 ttp://beken.cc.miyakonojo-nct.ac.jp/wp2/?p=1208 によると
> 私の環境で前もってインストールしておくべきだったものは、以下のパッケージです。
> どちらも[システム]>[システム管理]>[Synaptic パッケージ・マネージャ]でインストールしました。
>
> * g++
> * libstdc++5
>
> libstdc++6は既にインストールされていましたが、libstdc++5はインストールされていませんでした。
> またlibstdc++5をインストールしなくてもifort自体はインストールできちゃいますが、
> プログラムのコンパイルの時に必要になります。インストールしておきましょう。
ubuntuとかfedoraとかは新しいのを積極的に取り入れるタイプだから、 こういう数値計算に使うときは少し古めのにするか、もう少し安定志向な ディストリにするのが良いと思う。豆知識な。
ifort 11.1、error #5082: 構文エラー やっと直った。
黒カエラーwwww
処理系:gfortran v4.2 したいこと:モジュールに関数オブジェクトを保持させたい。 例えば、モジュールに変数3をセットし後に取得するプログラム module Test implicit none integer,private::a contains subroutine set(x) integer,intent(in)::x a = x end subroutine integer function get() integer::get get = a end function end module program main use Test implicit none call set(3) print *,get() end program というものを書くことが出来ます。 同じように、モジュールに関数を保持させることは可能でしょうか?
オイラー法のプログラムを書こうと思っているのですが、関数渡しで subroutine proceed(f,x,y,step) interface double precision function f(x) double precision::x end function end interface ... end subroutine と引用仕様記述を書くのではなく、例えばtarget_functionという変数名 に保持してしまって、後は target_function(x) というのを呼び出すだけ、みたいなのにしたいのです。
>>618 integer, private, SAVE :: a
にすればおk?
save無くても大概大丈夫だと思うが。
>>620 値じゃなくて、できれば関数保持する方法が。
>>618 は何したいのかわかりやすくする為の例だったんですけど、
我ながら読むと分かりにくい。
似たような感じで、関数を保持させたいんです。
>>621 PROCEDURE POINTER で駄目かな?
インターフェースは要るが。
MODULE m_unko
IMPLICIT NONE
INTERFACE
REAL FUNCTION f1(x)
REAL, INTENT(IN) :: x
END FUNCTION f1
END INTERFACE
PROCEDURE(f1), POINTER :: unko
REAL, PARAMETER :: pi = 4.0 * ATAN(1.0)
END MODULE m_unko
!
PROGRAM omeko
USE m_unko
IMPLICIT NONE
unko => SIN
PRINT *, unko(pi)
unko => COS
PRINT *, unko(pi)
STOP
END PROGRAM omeko
横からですいませんが、PROCEDUREって何ですか? 90以降の機能ですかね?
>>623 Fortran2003 の機能です。
副プログラムのインターフェースを、一括化できたりします。
インターフェースを書く代わりに、 Procedure (sub0) :: sub1, sub2 など。
type っぽいかんじで。
>>622 ありがとうございます。
でも、gfortranの4.2じゃできないっぽいですね。
v4.3以降でサポートなので、v4.3入れてやってみます!
627 :
デフォルトの名無しさん :2009/09/27(日) 07:50:23
お礼はいりませんよ。
program orei implicit none do while (.true.) write(*,*) '627 ありがとう' end do end program orei
Fortranの名著的な入門書ってありますか?
森口繁一のFORTRAN入門?
それって77じゃない? あえて理由がない限りは、77はすっとばして90の勉強をしたほうがいいと思うけど
632 :
デフォルトの名無しさん :2009/10/03(土) 18:18:59
浦昭二編のFORTRAN77入門改訂版だろう やっぱ プログラミングの入門者には迷著かもしれないが
>>631 そうは言うがな、大佐。
F90以降は入門書どころか日本語の書籍自体少ないし・・・
倍精度の説明をキッチリやってる本ってあったっけ?見た 記憶無いんだが。 90 といえば bit の別冊であったけど、あれも絶版だよね。 単行本にしたらいいのに。あとソフトバンクからも90の本 は大昔に出てたそうだな。どっちも持ってないけど。
>>634 Bit別冊はMetcalf&ReidのFortran90 Explainedの訳本だから、まぁ今は最新版の原著を買えばいい?
入門書とはいえない気もするが。
C++は数年使ってるんだが大学で初めてFortran使わされることになった templateとかクラスがなくて心細いよ
まだFortranを使わせる所もあるんだ。 物理系?
うん物理
分野にもよるけど地球物理系もFortranがバリバリ現役 しかもFortran77 過去の資産有りすぎ Fortranのサブルーチンは変数が参照渡しだから 他の言語に移植するときめんどい
77はダイレクトに変数とかに触っている気がして気持ちいい。 90/95とかだと膜ごしに触っているような感触と言うか。 でもINTENTとかをガチガチに書いた90の方が全般的には気持ちいいが。 2003は実行時の多態化とか入れて便利そうなのは分かるが、また実行時バグが増えそうで 微妙な感じがする。
>>640 >INTENTとかをガチガチ
計算用の言語としては、この辺で十分な気がする。
十分具体的で十分美しい。かつ十分便利。
もう95位で仕様凍結してくんないかな・・・
>>641 > もう95位で仕様凍結してくんないかな・・・
同意。色々と弄られるとついて行けなくなりそう。個人的には
Fortran90 で十分と思ってしまうのだが、これは少数派かも。
intent の in out で変数値書き換えチェック interface 文で呼び出す側で心つもりも教え pure 属性をつけてインラインしやすくしてあげる だけど固定書式をつらぬくのが漢! うそだけど。 固定書式に目が慣れてるといまさら自由書式にしにくいのよね。 右側7文字が空いてないとそわそわしてしまう。
左側?
ひとつのモジュールのなかにオーバーロード?用のinterfaceと実装をまとめて記述したいんですがどう書いたらいいんでしょうか?
>>645 こんな感じ?
module mod1
interface sub
module procedure sub_int, sub_real
end interface
contains
subroutine sub_int(n)
integer, intent(in) :: n
print *, "INTEGER", n
end subroutine sub_int
subroutine sub_real(x)
real, intent(in) :: x
print *, "REAL", x
end subroutine sub_real
end module mod1
! ---------------
program prog1
use mod1
call sub(1)
call sub(2.0)
end program prog1
>>646 まさにこれです
ようやっと期待通りにコンパイルできました
有難うございました
648 :
デフォルトの名無しさん :2009/10/15(木) 04:55:19
通りすがりだけど、参考にしよう。 この例のは、引数の型で振舞を変える事ができるから、標準のmaxやmin関数を連想した。 ・・・引数の変数名の数の違いで振舞を変えるもの作れるのかな?
>>648 任意個数引数の副プログラムは作れないと思う。
Array Constructor で、見かけ上引数を沢山並べるが、引数的には配列として受け取るようにすれば
実現できる気もする。
Call sub( [a, b, c, d, e, f, g] )
Subroutine Sub( x )
Real, Intent (in) :: x(:)
みたいな。
650 :
デフォルトの名無しさん :2009/10/15(木) 14:41:54
おお、そういうやり方があるんだ。 今コンパイラを使えない状況にいるので・・、 とりいぞぎお礼まで。
>>650 補足するならば、[ ] はfortran2003での導入なので、f90的には(/ /)となる。
確定した有限個まででよければ、optional引数を使うとか、1個からn個までのサブルーチンを用意して、
総称名を与える方法も考えられる。
たった今Fortranをやり始めたものです。コンパイラーはg95を使ってます。 最初の宣言部であるパラメータのベクトル p を宣言しようと思って、 real, parameter, dimension(3) :: p(1)=0.5, p(2)=0.8, p(3)=1.6 のように入力したのですが、 Error: Symbol 'p' at (1) already has basic type of REAL というエラーメッセージが表示されました。ただ、このメッセージの 意味さえ解せない状況です。どなたか正しい方法を教えていただけ ないでしょうか。よろしくお願いします。
>>652 こうすれば、おk。
PROGRAM test
IMPLICIT NONE
REAL, PARAMETER :: p(3) = (/ 1.0, 2.0, 3.0 /) ! f90/f95
!REAL, PARAMETER :: p(3) = [1.0, 2.0, 3.0] ! f2003
PRINT *, p
STOP
END PROGRAM test
common文の代わりにmoduleを変数の共有に使ってるんですが、 そのサブルーチンの中で使ってないmoduleをuseしたりすると (バグの温床になる以外に)何か弊害ってありますか? どの変数を使ってるか確認する手間が大きくなり過ぎた場合に 全てのmoduleをどさっとuseしても構わないもんでしょうか?
>>655 依存関係が無くても、USEされているためにリコンパイルされる可能性があるが、
文法的には問題ないような。
>>655 ローカルの変数とコンフリクトしたらコンパイラが教えてくれるので
ぜんぜん問題ないと思うけど・・・
どっさりuseしなきゃならんサブルーチンの構成は、
見直した方が幸せになれるかもね
use 文って便利だけど不便だよねw
NaNが出てきちゃった時、どうやって原因を突き止めますか?NaNが発生してると思しきところと 発覚するところが離れてる上に乱数使う手法で、しかもたまにしか起こらないので手の付けようがありません。 ズバッと解決はしないかもしれないけど何か助言をもらえればうれしいです。
>>660 乱数を使っているなら、種を特定すれば良いんじゃないか?種を手で与える方法もあるんだし。
現象が起きるときの種が分かっていればバグ取りは出来るはず。それだけでは足りないかもし
れないけど、何も情報が無いよりはマシ。
あと、NaNが出る式の実行直前に、式で使う変数の中身を書き出せば何か分かるかもしれん。
何をやっているのか分からんので、それくらいしか言いようが無い。
なるほど…ありがとうございます。ちょっとその方向で試してみます。 Xの値を調べて場合分けするんですが、XがNaNなのでエラーが出て発覚する、って感じです。 その場合分けしてる位置よりかなり以前の複数の場所でXが代入されてる上にXの代入が多すぎて 全部調べるのが厳しいんです。といってもそれしか思いつかずちまちまやってました。
663 :
デフォルトの名無しさん :2009/10/26(月) 06:44:30
宣言した範囲外の配列値を参照すると subscription out of range のエラーを出さずに NaNや変な値を返して計算をぶっ続けるシステムもあるよね。一応配列もチェックすることをお薦めする。 システムごとにNaNやInf検出して停止させる機能があると思うけどな。 発生した場所をソースの行番号で教えてくれる・・・はず。 富士通Fortranはデバッグ機能が神がかり的に優秀だけどIntelその他にも似た機能はあるだろう。 自分で直接追求するときにはとりあえず if (.NOT. ((x .GT. -1.0) .OR. (x .LT. 1.0))) then ... の判定で場所を特定してるけど・・・みんなはどうやってNaN発生を見つけてるの?
>>663 配列の宣言外領域へのアクセスについては、実行時にチェックするオプションを
付けてコンパイルしている。でも個々の変数の中身がNaNになったら止める方法
は知らない。あれば知りたいくらいだ。
しかし変数にNaNが入った時点でプログラム自体に問題があるように思うのは間
違ってるだろうか?初期化の時にNaNを入れるのも可笑しいしなぁ。
>>664 Fortran2003ならIEEE754例外を拾う関数がある。
F2003でなくても最近のコンパイラはベンダー拡張サブルーチンでIEEE例外を検知できることが多い。
>>665 有り難うございます。貧乏なので gfortran しか持ってません。並列とかするわけでもないので
特に困る事もないのですが。で、その gfortran のマニュアルを見ていたら、isnan() という関
数がありました。これで検知だけは出来そうです。オプションでも -ffpe-trap というのがあり
ましたが、使ってみたら実行時に警告が出ただけで、プログラム自体は正常終了してた。使えな
いのかな。それとも PPC なのが悪いのか。取り敢えず気になる変数だけ、isnan() を使ってチ
ェックすれば良いかな、と思うことにしました。
C マニュアルに載ってたサンプル: test_nan.F90 とでもする
program test_nan
implicit none
real :: x
x = -1.0
x = sqrt(x)
if (isnan(x)) stop '"x" is a NaN'
end program test_nan
% gfortran test_nan.F90 -ffpe-trap=invalid
% ./a.out
Fortran runtime warning: IEEE 'invalid operation' exception not supported.
STOP "x" is a NaN
% echo $?
0
通りすがりがテストしてみた。
% gfortran test_nan.f90 -ffpe-trap=invalid
In file test_nan.f90:6
if (isnan(x)) stop '"x" is a NaN'
1
Error: Function 'isnan' at (1) has no IMPLICIT type
コンパイル止まったお! バージョンにも依るのかな?
SPARCかな、CPUによってはNaNやInfが出てくるとハード的にフラグをたててくれるみたいだけど
一般的じゃないからなあ。
>>663 の条件式はハードやコンパイラ関係無くNaNは見つけてくれそうだけど、
システムによっては+/-Infは判定できないんじゃないかな。
>>666 です
>>667 うちは
% gfortran --version
GNU Fortran (GCC) 4.4.1
だった。マニュアル(但し 4.4.2 版)によると、isnan は論理型とのこと。オプションの -ffpe-trap=invalid
は無くても isnan 自体には問題なかった。
自宅にある唯一の Fortran90 の本「Fortran90/95 explained (2nd ed.)」によると、ieee_arithmetic という
モジュール?には ieee_is_nan という関数があるとのことだけど、モジュールってどうやって使うの?ずっと
77でやってきたから知りません。イイカゲン90の勉強をした方が良さそうな気がして来たが、もうFortranを
使う用事ってないんだよなぁ。趣味で数値計算でもしない限り。
あと、名前付き定数?(named constants)というヤツの中に ieee_nan というのがあるらしい。取り敢えず
同書から引用しておきます。
ieee_nan The scoping unit must support NaNs for at least one kind of real.
これを何の目的でどう使うのかは分かりません。ゴメンナサイ。
ありがとう。 GNU Fortran (GCC) 4.1.2 20071124 (Red Hat 4.1.2-42) ・・・2年前のだった。 こんど再挑戦してみるよ。
そんな難しいことする前に、 ゼロ割とSQRTチェックがまだだったら、 そこ見た方がいいよ。 もうチェック済ならスマン
列の数が任意のテキストデータ(列間は空白など)を読む方法を 考えているのですが、上手い方法が思いつきません。 行の場合は、EOFのチェックをすればいいので簡単なのですが・・・
>>671 EOR end of record のチェックをするという手もある。自由フォーマットだとうまく行かないが。
あとは、一度一行を文字列として読んで、次にその文字列を内部ファイルとして、それから読み出す
というやり方も考えられる。
データの幅が一定フォーマットなら比較的楽。
空白で切ってるだけで可変長の場合は、ややめんどいかな?
673 :
672 :2009/10/28(水) 02:11:12
PROGRAM test IMPLICIT NONE ! INTEGER, PARAMETER :: iostat_eor = -2, iostat_end = -1 REAL :: a(20) INTEGER :: io, i, k CHARACTER (LEN = 136) :: text ! prepare data DO i = 1, 10 WRITE(9, '( 10(F10.5, X) )') (REAL(k), k = 1, i) END DO CLOSE(9) ! (2) ! DO READ(9, '(a)', IOSTAT = io) text IF (is_iostat_end(io)) EXIT ! f2003 a = a / 0.0 ! NaN READ(text, *, IOSTAT = io) a IF (is_iostat_eor(io)) EXIT ! f2003 PRINT *, a END DO STOP ! (1) ! DO READ(9, '(10F10.5)', IOSTAT = io) a IF (is_iostat_eor(io)) EXIT ! f2003 IF (is_iostat_end(io)) EXIT ! f2003 PRINT *, a(1:10) END DO STOP END PROGRAM test
質問です。 シンプソン法を用いてy=exp(x)の計算プログラムを作っています。 以下のプログラムの15、16行目のfun()の中には、 何を入れればいいのでしょうか?
program simpson1 implicit none integer::m,i real(8)::a,b,s,s1,s2,h,x,fun external fun 1 continue write(*,*)'INPUT DATA' write(*,*)'A,B,M ?' read(*,*)a,b,m if(m<=0)stop h=(b-a)/m s1=0.D0 s2=0.D0 do i=1,m/2-1 s1=s1+fun(i) s2=s2+fun(i) end do s1=s1+fun((m-1)*h+a) s=h/3*(fun(a)+fun(b)+4*s1+2*s2) write(6,100) s 100 format(2x,'IR=',D16.6) end program simpson1 ! function fun(x) implicit none real(8)::fun,x fun=exp(x) return end function fun
676 :
671 :2009/10/28(水) 16:19:35
>>672 ,673
ありがとうございます。
「一度一行を文字列として読んでから、その文字列を内部ファイルで読み出す」は応用が利いて便利ですね。
区切りを空白とする以外はフォーマットを限定しない仕様にしたかったので、
この方法がベストだと思いました。NaNのチェックはisnan()を使いました。
最後にもう一点お聞きしたいのですが、EORはformattedで読む場合も関係あるのでしょうか?
また、どういう使い方をするのでしょうか?
677 :
デフォルトの名無しさん :2009/10/28(水) 17:00:51
サブルーチンについての質問したいことがあるのでソース貼らせていただきます。 お忙しいとは思いますが、よろしくお願いします。まず下のソースを見てください。 このプログラム自体は完成しているのですが、 DO 1040 a=1,M DO 1030 k=1,24 AVE(a)=AVE(a)+(sl(k,a)) 1030 continue WRITE(2,*)AVE(a)/24 1040 continue の部分をサブルーチンで直して来いといわれたので、 サブルーチンについて調べて色々やりくりしてみたのですが サブルーチンについての理解が乏しいため上手くいきません。 もしこの箇所をサブルーチンを利用して書き換えるならどのようになるのか教えていただけませんか? よろしくお願いします。
678 :
デフォルトの名無しさん :2009/10/28(水) 17:02:47
上の続き(ソース)です。よろしくお願いします。 implicit none integer MM,KK,M,K,a parameter (MM=400,KK=100) integer year(MM),month(MM),day(MM),sl(KK,MM),AVE(MM) character cdummy,CFNAME*110,CFNAME2*80 M=0 CFNAME='/home/maekawa/numeric/kure.txt' open(1,file=CFNAME,status='old') 1010 M=M+1 read(1,10,END=1020)cdummy,year(M),cdummy,month(M), @ cdummy,day(M),(cdummy,sl(k,M),k=1,24) 10 format(A5,I2,A1,I2,A1,I2,24(a1,I3)) write(6,*)year(M),month(M),day(M),(sl(k,M),k=1,24) goto 1010 1020 close(1) M=M-1 CFNAME2='/home/maekawa/numeric/aki.txt' open(2,file=CFNAME2,status='old') DO 1040 a=1,M DO 1030 k=1,24 AVE(a)=AVE(a)+(sl(k,a)) 1030 continue WRITE(2,*)AVE(a)/24 1040 continue CLOSE(2) end
>>676 EORはF90以降だったようだ。
昨日は勘違いして77時代からあった気になっていた。使い方を良くわかっていなかったww
文法書を見てもらった方が早いが、そもそもFORMATつきでADVANCE='NO'でないと駄目のもよう。
77だとIOSTATでエラー番号を見ればEORを検出できるが、I/Oエラー番号はベンダー依存。
他のI/Oエラーが出ない自信があれば、ERR=nnで飛ぶことも可能。
77だとブランクを数値ゼロに解釈するので、文字列を内部ファイルとして読む場合に
色々前処理をしないとうまくいかないかもしれない。
90なら文字列をTRIMするなり、フォーマットをBNにするなりで対処しやすい。
まとまり無くてスマソ
そもそもFortranは「任意のサイズの○○」というのがやりにくい言語だよね そういうもんだと思って諦めてるけど
最初に1回から読みして要素数(行数)確認してから Allocate...とか、かな。 でもこの辺の取り回しはどの言語も同じだよね。 使っていくうちに増える場合には 一度既存のデータ配列と同じサイズのTempな変数をAllocateしてそこに移して、 元のを開放してからまた同名で要素一個大きいのをAllocateして TEMPのを移して、TEMP開放、の流れは基本同じだし。
終始一貫変化しない任意のサイズ、でなかったら77だときついな。 データを一度ファイルに落として、そのファイルの行数を数えてから 自動配列で配列生成してそのファイルを読む・・・・・とか。 不可能じゃないけどイヤだなw。
>>681 Fortranに限らず、データの個数が任意に変わる場合は
ポインタ使ったリスト構造を作るのが普通じゃない?
>>682 結局は、「Fortranでそういうことスンナ」って話になるよねw
速度的にも宜しくないし、データ量の多い科学計算には相容れない
684 :
デフォルトの名無しさん :2009/10/30(金) 04:46:30
・・・馬鹿でかい配列を最初に定義してそこで処理するのもなあ。 メモリがもったいない事は今はあまりないけどやはり非効率だし 場合によっては十分大きくとったつもりでも足りなかったり。
IBMのFortranのオンラインマニュアルにも、Fortran77と違って 大きな配列を最初に定義しなくて良くなりますよ~、という事を Allocateのメリットの例にしてるくらいだからな。
FORTRANは言語仕様が堅くて大変だねえ C/C++ならそういう問題で頭を悩ます必要もないのに
>>686 最適化がしやすいようにわざと堅く作ってあるんだよ
C/C++は確かに自由な文法だが最適化がしにくい
最適化しにくいし、コンパイラ毎に推奨される書き方の違いは Fortranより大きいと思う。個人的にはこっちがいやで Fortranを中心に使っている。 でもやはりというかCのI/Oその他の自由度の高さゆえに 最終的には混ぜこぜコードの出来上がり、になる事も多いけど。 Cはコーディングの自由がありすぎて、結局サイトや教科書の 部分的丸写しが多くなっちゃうから上達しないだけなんだろうけどな。
689 :
671 :2009/10/30(金) 18:45:48
>>679 レス遅くなりましたが、ありがとうございます。調べたところ、要するに
「form='formatted' かつ advance='no' の場合に限り、 eor=文番号 が使える」
ということなんですね。
↓のコードでテストしてみました。
<ソース>
real :: f(5)
write(10,*) 1.0 , 2.0 , 3.0
write(10,*) 4.0 , 5.0 , 6.0
write(10,*) 7.0 , 8.0 , 9.0
rewind(10)
do i=1,2
f=0./0
read(10,'(3f)',advance='no',iostat=io,eor=999) f
print *,'io=',io
print *,f
enddo
stop
999 print *,'EOR detected!'
print *,'io=',io
print *,f
end
<出力>
io= 0
1.000000 2.000000 3.000000 4.000000 5.000000
EOR detected!
io= -2
6.000000 0.0000000E+00 NaN NaN NaN
690 :
671 :2009/10/30(金) 19:00:00
ふと思ったのですが、「レコード」というのはunformattedの場合の概念であって、
単なるASCIIであるformattedでは関係ないはずですよね。
そうすると、EOR(End Of Record)ではなく、EOL(End Of Line)などと
呼ぶほうが適切なのでは、と思ってしまいました・・・。
いずれにしろ、私的には文番号はデバッグ時を除いて使いたくないので、
>>676 の方法がベストですね。
>>690 IOSTATの番号で見ればいいので文番号は必須ではない。
しかし、いったん1行を文字列に読んで、加工するなりして、
内部ファイルで読むのがいろいろ出来て便利。
EORの呼び名に関しては、御説ごもっともだが、多分ADVANCE=’NO'によって、
逐次型本来の行単位のアクセスではなく、その内部の要素ごとで、ファイルの現在位置を
止めうるようにしたので、ダイレクトアクセス的なネーミングにしたのではないかと想像?
692 :
671 :2009/11/01(日) 21:01:41
>>691 ほんとですね。ありがとうございます。
iostat= と eor= の少なくともどちらか1つを指定していないと、
EORになった時点で↓のようにエラー終了するようですね。
forrtl: severe (268): end of record during read, unit 10, file ・・・
693 :
デフォルトの名無しさん :2009/11/04(水) 05:59:17
IOの挙動がらみで複数の行き先指定すると その後にgotoスパゲッティになることがあるからムズムズする。
メジャーな環境で動く汎用的なコードを書こうという場合、 安心して使えるFortranのバージョンってどれでしょうか? 少し前は「90にしとけ」って話をよく聞きましたが、最近は 95や2003も問題なく通用すると思って良いんでしょうか?
>>694 F95が標準の地位を占めたという感じでないか?
更新していないシステムでは、まだF90の環境が結構残っている。
F77はコマンド名として存在していてもF90のコンパイラを固定カラムなどのオプションで
呼び出していることが多い。
F2003はようやくCRAYが完全対応したところで、ベンダーごとに独自の部分的な対応に
とどまっているのが実情。簡単なところから対応しているから大体は重なっているが。
696 :
デフォルトの名無しさん :2009/11/05(木) 05:21:56
もともとがF77で始めたせいで、いまでは固定書式&左側6文字空白&72文字制限つきで でも命令文はF77~95の混在したコードになってもうた。プリプロセスも混ぜてるから拡張子は.fppだ。 まあでも、gfortran と intel fortran はちゃんと処理してくれるから、いいや。 FujitsuのもOKみたいだし。 無駄に行数が増えてしまうけど左側が空いてるとなんか安心するw
>>695 ありがとうございます。
F95で書こうと思います。
698 :
デフォルトの名無しさん :2009/11/06(金) 02:03:35
今から始めるんならF95でいいと思うよ。Fortranは古いコードと混ぜてもトラブルは 少ないように規格されてるから過去の資源も使い易いし。 2003でスコープ範囲指定が出来るようになるらしいけど、いつ出るんだろう? まだ見たことないや。
たいていの商用コードはIntelとAMDのx86環境を前提としてるよね。 昔はIBM、日立、富士通、Sun、SGIって色々あったけど、今はそれらは ほとんど淘汰されてスパコンレベルしか残ってないし。 ま、コードを開発する側としてはやりやすくなったんだろうけど。
>>698 >2003でスコープ範囲指定が出来るようになるらしいけど、いつ出るんだろう?
>まだ見たことないや。
変数のスコープか?
PRIVATE、PUBLICは今あるままで、PROTECTED(いわゆるリードオンリー)が加わる程度だと思ったぞ。
他にもあんのかな?
COMMON文ってmoduleみたいにスコープを指定ってできないの?
名前を共有するんじゃなくて、メモリブロックを共有するための仕組みだからねえ。
お寿司ってハンバーグみたいにソースで食べるってできないの?
ああ、普通そうやって食べる。
www 両方ともマヨネーズならアリだよな
・・・だめ?
本物のプログラマはマヨネーズは使わない。 Quiche Eaterはマヨネーズを使う。
質問です。 割り付け配列って何ですか?
711 :
710 :2009/11/18(水) 19:33:35
710です。たとえば以下のプログラムの変数A,B,Cを割り付け配列すれば どこを変更すればいいのですか? program matrix_wa implicit none integer::N,I,J integer,parameter::IDIM=100 real(8),DIMENSION(IDIM,IDIM)::A,B,C ! write(*,*) 'INPUT MATRIX DIMENSION' read(*,*) N write(*,*) 'INPUT MATRIX ELEMENTS OF A' do I=1,N read(*,*) (A(I,J),J=1,N) enddo write(*,*)'INPUT MATRIX ELEMENTS OF B' do I=1,N read(*,*) (B(I,J),J=1,N) end do CALL MATADD(IDIM,N,A,B,C) CALL MATOUT(IDIM,N,C) stop end program matrix_wa
!============================================== SUBROUTINE MATOUT(IDIM,N,X) !============================================= implicit none integer IDIM,N,I,J real(8),DIMENSION(IDIM,IDIM)::X write(*,*)'C=' do I=1,N write(*,*) (X(I,J),J=1,N) end do return end subroutine MATOUT !=============================================== SUBROUTINE MATADD(IDIM,N,A,B,C) !============================================= implicit none integer::IDIM,N,I,J real(8),DIMENSION(IDIM,IDIM)::A,B,C DO I=1,N do J=1,N C(I,J)=A(I,J)+B(I,J) end do end do write(*,*) 'C=' do I=1,N write(*,*) (C(I,J),J=1,N) end do return end subroutine MATADD
713 :
デフォルトの名無しさん :2009/11/21(土) 10:18:39
ちょっとお聞きしたいのですが、 3つの物理量の実測(とびとびのデータ)からある答えの物理量 がわかるデータがあるとき、 3つの物理量がある入力値の場合の答えの物理量を出すときに、 データの線形補完をしたいのですが そういうやり方とかないでしょうか
>>713 言いたいことがよく分からないのだけど、補完みたいなことをしたいの?
回帰分析とかいう分野の事?
>>714-716 ありがとうございます。
あまりうまく伝えられなくて申し訳ないです。。
詳しくないのですが多分回帰の範囲と思います
3変数から一つの解を出す方法なのですが、
データから多項式で式が一発で出せるようなのがあればいいのですが、
そういうのはないでしょうか。。
それを求めたいのか、求めるプログラムを作りたいのか。 前者ならR言語が使えるらしい。
>>717 y=a*x1 + b*x2 + c*x3
のような式において、x1、x2、x3、yのリストから係数a、b、cを
導きたいなら、Excelの関数で1発でできる。重回帰分析でググれ。
>>713 > データの線形補完をしたいのですが
最小二乗法使っとけ。
線型でいいということは測定できる変数x、y、z とそれらから分かる量wの間に
w = a*x + b*y + c*z
という関係があると仮定できるってことでしょ?で、係数a、b、cは分かんない。
この分かってない係数を測定データから決定することで、測定データの中には無
いx、y、zの組のときにwがどんな値になるかを知りたいのだと邪推してみる。
>>713 の頭の中を覗けるわけではないので間違ったこと言ってるかもしれんけど。
それをどうしてもFortranで書かなければならないのなら仕方が無いが、そうでも
なければ
>>718 が言うように R でも何でも使ってればいい。
でも最小二乗法ならwのデータも要るのか?元質問だとwは測定して無いっぽいな。
こういうときはどうすんだ?
元質問がグダグダなので無責任に色々と言い放ってみた。グダグダじゃなくても
責任ある発言なんてできないけど。
Windows 用の Fortran 95 コンパイラを買おうと思っているのですが, NAG Fortran Builder 5.2 と Intel Visual Fortran 11.1 日本語版の どちらにしようか迷っています。すみませんが,以下の疑問それぞれに ついて判るかた,教えてください。 【1】 以下の項目について,どちらが優れているのでしょうか? (A) コンパイルしてできた実行ファイルの処理速度の速さ (B) 開発環境の使い勝手の良さ(入力補完など) 【2】 Intel Visual Fortran でも NAG Fortran Builder のように GUI アプリケーションが作れるのでしょうか? 【3】 Intel Visual Fortran と NAG Fortran Builder の2つ以外に 日本語版の Fortran 95 コンパイラはあるのでしょうか? なお,私のパソコンは, Windows が XP Home Edition SP3, CPU が Intel Pentium 4 (2.40GHz), RAM が 512MB です。
>>721 1) (A)処理速度で言うならIntel。NAGは文法的な厳格さ、厳密さが売りで速度は二の次。
(B)Intelの統合環境はMSのVisualStudioで、入力補完などは無い。シンタックスカラーリング程度?
VS2010あたりで色々対応したいと言うようなことは言っているが未定。
NAGの方は独自の統合環境で、こちらもシンタックスカラーリング程度だったような。
Fortranの入力補完は、ほとんど存在しない。
昔の(10年以上前の)LaheyについてきたWin3.1時代風のEDくらいか。
Polyhedron社が今のLahey用にVisualStudioの拡張を売っていたような気もするが詳しくは分からん。
Laheyのサイトを見てくれ。
2.IVFでのGUIは、Win3.0時代から続くQuickWin互換の初歩的なものと、Win32APIを直接叩く方式がある。
サンプルプログラムが提供されているが、Fortranの呼び出し規約とCの呼び出し規約が違うので
Win32APIに習熟しているとともに、呼び出し規約等に惑わされない必要があって、理解が困難。
OpenGLで絵を描くだけならサンプルの改造で済むのでまだやさしい。
3.日本語版があるかは知らないが、Winで動くものとしては
有料 商用
・CUDAに対応するなどアグレッシブなPGIのFortran。
・富士通とコンパチなLahey-Fujitsu Fortran (.Net対応とか、SSLライブラリがある)
・MacやCrayとの親和性が売りだったAbsoft Fortran (今はその利点もあまり無いが)
無料系
・広告がうざいが、ただで使えるのがSilverFrostのFTN95。(商用は.Net 対応らしい)
・GNU系がよければ、g95 または gfortran. (この二つは同じ先祖から分かれた別物)
参考:非Win
*FreeのSUN OS上でよければ、SUNのFrotran95もただで使える。
*Linux上なら Intel Frotranが学術目的ならただで使える。
>>722 OpenGLで絵を描くだけならサンプルの改造で済むのでまだやさしい
なつかしす。結局コレで遊んだ以外はコマンドラインでしか使わなかったな・・・
もっとも自分の古いマシンに乗ってるのは DEC のVisual Fortran だけど、まあ同じようなものだからいいか。
追加、というか・・・ QQで始まるGUIその他用の拡張命令サブルーチンが一杯あって訳わからんかったなぁw GUIアプリ作るときには do while ..... enddo でコード全体を無限ループで囲む、 アプリ終了=ループ脱出はwhile()内に来る条件のフラグをいじる、だったような。 Fortran 文法に可能な限り沿いながらGUIアプリに必須な マウス操作とかのいつ起こるか未然にわからないアクションを扱う苦悩が味わえたw
725 :
721 :2009/11/25(水) 21:53:03
>>722 すべての質問に対しての丁寧な回答,本当にありがとうございました。
とても助かりました。
>>724 基本的に割り込み処理ののりだよな。
BASIC全盛時代のINKEY$でリアルタイム・キー入力処理を書いているようなもの。
>>722 *Linux上なら Intel Frotranが学術目的ならただで使える
正確には純粋な私用ならタダ、ね。学生がFortranやCで遊ぶだけならLinux版はタダだけど、
それを論文にしたり研究発表で使うデータ計算に使うのならちゃんと有償版を買わないといけない・・ハズ。
まあ、いまのところはIntel自身もあまりねちねちチェックしてないけど、
将来Intelの気が変わるとややこしいことになる大学や研究室や個人は多いと思われる。
小さいメーカとか10万円をけちって将来の生殺与奪の権をIntelに捧げてるところは多いのでは?
質問です。処理系はintel fortranです。結果に怪しいところが多いので浮動小数点例外を "アンダーフローは 0.0 にする。他の IEEE 例外は異常終了する (/fpe:0)"にしてます。 以下の行で、floating invalid を吐いて計算が止まります。変数は全て暗黙の型宣言です。 time=time*(xa-xb)/dx ちなみに直前でそれぞれの中身を表示したところ、 time=5.0E-07 xa=0.5368819 xb=0.5368840 dx=-2.0805840E-06 でした。 上の値はかなり長い計算の途中で出てくるので、手っ取り早く原因を探ろうと、 直前に上の数値を強制的に書き込んで回してみましたが再現しません(止まりません)。 floating invalidが上記の計算の行で起きているのはエラーメッセージのLineから明らかです。 正直意味不明過ぎて何を言ってるのか分からないかもしれませんが、何か 原因に思い当たること、もしくは他に何か必要な情報があれば教えていただけないでしょうか?
-r8 や -r16 付けて倍精度や4倍精度で計算するとか、かな。 あとは・・・・規格化(無次元化)する際の典型量を見直す、とか。 系全体の長さを1にするのではなく、関心のある現象の空間的なひろがりを1にとるとか。
dx って負になるのは正しいの?
>>729 キミに「プログラムは書かれいる通りに動く」という格言を進呈しよう。
とても高い確率でキミが何処かで間違えている。
>>731 一般論として考えた場合は負でも問題無い。というのは飽くまでも或る点からのズレ(変位)という意味し
かないから。
プログラムの中で何らかの約束がある場合には、その約束のために正の値でなければならないことはあるだ
ろう。そういう時に負になってしまうのはバグでしょ。その場合はプログラムを書いた人の検討不足かタイ
プミスかだ。デバッグができていないんだろう。他の理由もあるんだろうけど思いつかん。
>>729 > ちなみに直前でそれぞれの中身を表示したところ、
これは本当に直前なのか? 正常に動く一回前の値じゃないのか?
>>729 多分、ただのゼロ割だろう。
Intelのコンパイラのバージョンはいくつかな?
新しい奴ならNaNにして続行するが、8.1とか古い奴はFloating Invalidで即死する。
状況的には
>>734 の言っていることが正しいであろう。
>>730 倍精度は文字どおり精度を上げるのに有効だけど・・・
単精度でコケて倍精度で動く奴は、モデルを間違えてるかコードがおかしいかのどちらかだから
根本的には解決にならないね。
微妙なケタ落ちを救済する事が出来るが、ケタ落ちが発生しない アルゴリズム/コードに代える方がまっとうな道。
738 :
729 :2009/11/29(日) 13:14:09
みなさん、レスありがとうございます。まだ全部追えて無いんですが…
>>730 実は無次元化してません…
>>731 733が仰ってますが、単に変位です。負値は大丈夫です。
>>732 もちろんそうなんですが、どこで間違えてるのか分からなくて。
>>734 計算の一行前にwrite文で表示させてるので一回前の値と言うことはないはずなんですが、
この値で止まるのも同程度におかしいので何か間違えてるんだと思います。
>>735 ver.11です。デフォだとNaNで続行されますけど、NaNだと粒子が行方不明になってしまって困るので
トラップして原因を突き止めようとしてるのです。開放系ならごく稀に粒子が居なくなるくらいは問題ないんですが、
閉鎖系だと粒子がどんどん減ってしまうので…
>>737 こういう問題が発生しないアルゴリズムってどういうものでしょうか?原理的に発生しないんですか?
今自分で思いつくところだとNaNを検出して適当な座標を振りなおしてやるくらいしか思いつかないんですが…
ちなみにゼロ割した場合、floating invalidじゃなくてfloating divide by zeroとでました。分子も0だと
floating invalidになるのでこっちなんでしょうか?まだ不可解なところがあるのでもう少し見直してみます。
出力のバッファリングで一回前を見ている可能性が有る。 デバッガで調べた方が良い。
>>739 じゃ、出力先をファイルか標準エラー出力に切り替えてみるのもありだな。
そんで結果を見る。デバッガなんて使いこなすまでに時間が掛かりそうだし。
バッファリングはファイルの方が積極的。 もうひとつの可能性: floating invalidは表示ルーチンで出ている。
>>738 あとの安直な手は別のコンパイラで実行してみることかな。
g95あたりで一回やってみればいいのでは。
バファリンの半分はやさしさでw バッファリングの半分は嘘のデータで出来てます。 あとは・・・Write 文つかったデバッグの場合でかつ元のをUnrollingしていると Write文挿入する・しないで演算順序が変わることがあるから UnrollingやできればInlineを抑制したコンパイルをすることをお薦めしてみるテスト
744 :
デフォルトの名無しさん :2009/12/01(火) 05:51:21
Fortranをはじめたばかりです * *** ***** ******* を描けという問題で、1.2.3行目のスペースの出し方がわかりません・・・ $を使えばできるのかと思いましたが、わかりません どなたか教えていただけないでしょうか?
745 :
744 :2009/12/01(火) 05:52:09
スペース消えてる・・・
>>744 はピラミッド形です
do i = 1, 4 do n = 1, 7 if (n .GE. (5-i)) .AND. (n .LE. (3+i)) write(*,'(A,$)') '*' else write(*,'(A,$)') ' ' enddo enddo write(*,'(A)') '' enddo かな?
あら、一個 enddo -> endif にしとかんといかんかったね
748 :
744 :2009/12/01(火) 06:26:33
>>746 早速のレスありがとうございます
書いてくださったのを参考になんとか書けました><
お、かけましたかw if の行に then がなかったりしたけど、 えがったえがった
750 :
デフォルトの名無しさん :2009/12/01(火) 23:10:57
FORTRAN初心者です。。 1000以下の整数のうち、7で割ると2余る数を全て合計するプログラムをつくりたいのですがわかりません… どなたか教えてください。
>>750 integer i, s, n
n = 1000
s = 0
do i = 1, n, 1
s = s + i
end do
write(*,*)'sum =',s
続きは誰かヨロ。みんなで完成させようぜ。
if (mod(i,7) .EQ. 2) then s = s + i write(*,*) i, s endif 途中経過表示はいらないけどね。
753 :
sage :2009/12/02(水) 07:28:33
>>751-752 ありがとうございます。
本当に助かりました
自分でやったのでは実行できなかったので;;
また機会があればよろしくお願いします。
754 :
デフォルトの名無しさん :2009/12/03(木) 13:16:46
初めまして。 最小二乗法のプログラム(放物線近似)をつくっているのですが、 "dot_product"文がうまく使えません。 実行すると下記のようなエラーが出ます。 x4 = dot_product(x2,x2) 1 Error: 'vector_a' argument of 'dot_product' intrinsic at (1) must be of rank 1 In file test02.f90:28 x4 = dot_product(x2,x2) 1 Error: Function 'dot_product' at (1) has no implicit type 長くなりますが↓にプログラムを貼ります。
755 :
デフォルトの名無しさん :2009/12/03(木) 13:20:29
program saishou implicit none real(8)::a,b,x,y,y_b,xi,x2,yi,y2,xy,d,x4,x2y integer::n,i allocatable x(:), y(:), y_b(:) write (*,*) 'input number of data ' read (*,*) n ! input size of dimension write (*,*) 'number of data is ',n allocate (x(n),y(n),y_b(n)) !------------------------- do i = 1,n read(*,*) x(i), y(i) write(*,*) x(i), y(i) end do !------------------ xi = sum(x); x2 = dot_product(x,x) yi = sum(y); xy = dot_product(x,y) x4 = dot_product(x2,x2) x2y= dot_product(x2,y) d = n*x4-x2**2 a = ( n *x2y - x2*yi ) / d b = ( x4*yi - x2*x2y ) / d write (*,'(1x,2(3x,a,f7.3))') 'a =',a,'b =',b write (*,'(a8,a9,a10,a11)') 'x','y','y_b','dif' end program saishou
dot_productは引数に同じ要素数の配列しかとれない。 x2はスカラーなので引数にできないですよ。 ちなみにdot_productが返すのはベクトルの内積を求めるので、戻り値はスカラー。 ・・・とfortran歴1年の俺がいってみる
前から思ってたんだけど、dot_productみたいなデフォで用意されてる関数を使うのって、 ベクトル化などの高速化・最適化を妨げるリスクはないと思っていいよね? それとも、doループをいちいち書いた方がやっぱり速くなったりする?
758 :
デフォルトの名無しさん :2009/12/03(木) 21:10:12
fortranの初心者です 彗星の軌道をプログラミングしたいのですが上手くいきません どこがおかしいか教えてくださいませんか? program main integer i,j real ms,me,x,y,vx,vy,t,dt,G ms=1.989*(10**30) dt=100 G=6.673*(10**(-11)) K=G*ms/R**2 x=0.8826*(10**(11)) y=0.0 R=sqrt(x**2+y**2) vx=0.0 vy=55000 do i=0,1000 x=x+vx*dt*i y=y+vy*dt*i R=sqrt(x**2+y**2) vx=vx-K*(x/R)*dt*i vy=vy-K*(y/R)*dt*i write(6,*) x,y enddo end
759 :
デフォルトの名無しさん :2009/12/03(木) 21:42:09
>>756 なるほど・・・ご指摘ありがとうございます。
では行列の4乗はどう書けばよいのでしょうか。。
>>759 そういうサブルーチンを自作すれば良い。幸いなことにFortran90からは再帰も使えるしね!
気付いた所だと、 xnext=x+vx*dt*i ynext=y+vy*dt*i R=sqrt(xnext**2+ynext**2) vx=vx-K*(x/R)*dt*i vy=vy-K*(y/R)*dt*i write(6,*) x,y x=xnext y=ynext vx,vyはdtずらす前のx,yを使うのがオイラー法の正しいやり方ですよ。 これだけで直るかは自信がありませんが。
下記のIを求めるプログラムを組もうとしているのですが、フォートランはさっぱりで… どなたか本当にお願いします。 Zは3×3の行列で、V、Z、Iの各要素は複素数とするそうです。 確かに複素数を扱うにはCよりはフォートランだとは思うのですが… [V1] [Z11 Z12 Z13] [I1] [V2]= [Z21 Z22 Z23] [I2] [V3] [Z31 Z32 Z33] [I3] よろしくお願いします。
>>757 たぶん弊害はない。たぶん、なのは実装によるので。ベクトルがでかくなると、
出来合いのルーチンの方が速いね。そういうチューンしてると期待していいとおもう。
3次元くらいだったら自分でループ書くか、
naiseki=a(1)*b(1)+a(2)*b(2)+a(3)*b(3)
みたく成分を明示したほうがいいことがおおいけど。
>>762 複素数扱うならFortranのがいいよ。
んで、3x3行列なら (-1)^(i+j) * (小行列の行列式)_{j,i}/(全体の行列式)
を明示した方がいいよ。
>>763 thx
そのうち自分で試してみようかな
fortranで複数ファイルの結合ってどうやってやればいいですか? もちろん中身を読み込んで新しいファイルに書き込むなら出来ますが、 cat みたいな感覚で使える命令ってあるでしょうか?
>>766 system() を使って cat で繋げるとか?
Fortranが内部で持っている方法は聞いた事が無いです。
>>758 G=6.673*(10**(-11))
この辺は
G=6.673E-11
とするべし。
あと77なのか90なのか判然としないが、暗黙の型を破る気ならIMPLICIT NONEを
つけておくほうが吉。
>>766 catだって中では読んで書き出しているだけだろうに
>>768 >
>>766 > catだって中では読んで書き出しているだけだろうに
そういえばバイナリファイルをformattedで開く場合ってケッコウ難儀なことになりそうな気がして来た。
catはその辺はクリアしてるけど(でないとバイナリファイルの結合なんて出来ないよね?)。
自分だったらfortranでやらずにシェルでも書いてそっちで済ます。WindowsならPerlか何かを使うかな?
dosのコマンドで出来たっけ?やりたいことによって道具を使い分けるのが良いと思うけど。
>>766 catと等価な、つまりバイナリレベルでの結合は無理じゃない?
fortranって、せいぜいレコードを扱うくらいで、バイトレベルでの操作は普通しないし、そもそもできないと思うけど
いちおうAppendで既存ファイルに追記することはできるけどバイナリだと 追記するデータを別なファイルから読み込む段階でコケる事多々アリで面倒だよね。 Bit 単位での操作って Fortranで出来ない&やりにくい典型例だ。
FORTRANやCOBOLのような古い言語は、 ファイルはレコードの集合という考え方をするから、 前提のないバイト列は扱いにくい。
NAG Fortran Builder 5.2 をインストールして使ってみたのですが, program main print *, 'Hello World !' stop end のクイック実行のコンパイル&リンクに12分50秒もかかります。 NAGのコンパイラはこういうものなんでしょうか? それとも,もっと早くコンパイル&リンクのできる設定が何かあるのでしょうか? 私の環境は,OSはWindows XP,RAMは512MB, HDDの空き領域は,Cドライブは706MB,Dドライブは1.92GB, Fortran Builder は Dドライブにインストールしています。 # NAGの統合開発環境は,Intelのと違って,キーワード入力補完機能がありました。
RAM 少なくね?
776 :
773 :2009/12/05(土) 10:51:47
>>774 NAGのホームページには 「メモリ:256MB以上(推奨 512MB以上)」 と
書いてあったので,大丈夫かなと思ったんですが,
やっぱり足りないですかね。
他に Fortran Builder 5.2 のユーザーさん,いませんか?
RAMはどれくらい積んでますか?
>>773 キーワード補完だけじゃ、あってもなくてもほとんど変わらんよなぁ・・・
もっとリッチなFortranのIDEが早くでないものか
>>776 その前に今どき512MBというのがなあ。増設はできないの?
779 :
773 :2009/12/05(土) 13:38:40
別のパソコン (let's note) で試してみました。
CPU: Pentium M 1.20GHz
RAM: 1GB
OS: Windows XP Pro. Ver.2002 SP3
これで
program hello
print *, 'Hello World'
stop
end program hello
をやってみたんですが,こちらのPCでもコンパイル&リンクに
12分25秒かかりました‥‥ orz
>>778 う~ん,6年前のVAIOノートなんで,買い替えしたほうが良いかもしれません。
780 :
773 :2009/12/05(土) 13:52:17
Intel Visual Fortran 11.1 のほうの動作環境ページを見ると RAM 1GB (2GB 推奨) と書いてあるんですが, CPU: Pentium M 1.20GHz,RAM: 1GB のPCにインストールしても, Fortran Builder と同じくコンパイル&リンクに10分くらい 時間かかっちゃうでしょうか?
メモリが足りないせいで異常に遅いときは、 大量にスワップが発生しているせいなので、 一定量メモリを増やせば急に早くなるものだが、 512MBでもその有様とはすごいね。 fortran 77でよければ open watcom fortranとかいいんでない?
>>779 まさかとは思うが、メモリの空きは大丈夫なんだよね?
動画のエンコしながらコンパイルとかはさすがにないだろうけどw
コマンドラインからコンパイルとかできないの? IDEが重いのかもしれない。
あと仮想メモリを増やしてみる。無駄かな?
785 :
773 :2009/12/05(土) 16:01:16
>>781-784 レスありがとうございます。
>>783 さんのレスを見て調べたら,
コマンドラインからコンパイルする方法が NAGのサイトの
FAQページに載っていました。
今度は数秒でコンパイルできました!
# しかも,できた実行ファイルのサイズが,IDEのときは 266KBだったのに対して,
コマンドラインからのときはわずか 18KBとずいぶん小さくなりました
ちなみに,g95でコンパイルしたときは 339KBでした。
本当にありがとうございました m(_ _)m
もしかしてNAGが駄目駄目ってオチなのかな? でもそんな悪い評判は聞いたことないが・・・
>>770 バイナリファイルも、F2003ならSTREAMファイルとしてあけることで扱える。
F2003以前でもベンダー拡張でSTREAMアクセスできることが多い。
また規格の範囲内でもDIRECTアクセス・ファイルの属性で代替できることがある。
(独自フォーマットのDirectFile形式のベンダーもあるが、垂れ流し的に書いているものも多いので、
実質ストリームとして使える)
ただFortranの規格ではレコード長が処理系依存なので、バイトかワードかが確定できない。
でもコンパイラのオプションで単位をバイトに指定出来ることが多い。
>>785 それって単にランタイムDLLになっただけじゃ?
IDEの時はスタティックリンクなんでしょ
IDE経由とコマンドラインの場合とで、デフォルトの動作が違うってこと? IDE使ったことないんで分からないけど、そういうもんなのかね でもスタティックリンクにしたら、サイズが増えるのはいいとして 10倍以上の時間がかかるなんて、あり得るの?
デバックシンボルでも埋め込んであるんだろ それに実行ファイル自体が最適化がかかってないかもしれない 環境を聞かないと何とも堪えようがない
791 :
773 :2009/12/06(日) 08:35:45
>>788 > IDEの時はスタティックリンクなんでしょ
IDEの設定を見たら,おっしゃるとおりで,
「nagforランタイムライブラリの非共有(静的)バージョンを結合」
となっていました。ひとつ勉強になりました(汗)。
>>790 > 環境を聞かないと何とも堪えようがない
環境は……
【1つめのパソコン VAIOノート】
OS: Windows XP Home edition Ver.2002 SP3
RAM: 512MB
HDDの空き領域:Cドライブは 706MB,Dドライブは 1.92GB
Fortran Builder 5.2 は Dドライブにインストール。
【2つめのパソコン let's note ノート】
OS: Windows XP Professional edition Ver.2002 SP3
RAM: 1GB
CPU: Pentium M 1.20GHz
HDDの空き領域: Cドライブは数十GB
Fortran Builder 5.2 は Cドライブにインストール。
……です。
NAGのお値段を考えたら・・・おニュウPCを買うべきだとおもう
793 :
773 :2009/12/06(日) 08:42:25
あ,【1つめのパソコン VAIOノート】の CPU は Pentium 4 の 2.40GHzです。
次の行列の演算を2次元配列を用いて行うプログラムを作りたいのですが; どなたか教えください。 [123] [13] [ ]×[23] [045] [46] です。 わかりにくいのですが、2行3列と3行2列の乗算です。。
見づらくてすみません。。 [123] [13] [ ]×[23] [045] [46]
行列成分は実数にした。違いは無い real a(3,2), b(2,3), o(2,2) a(1,1) = 1.0 | a(3,2) = 5.0 b(1,1) = 1.0 | b(2,3) = 6.0 do j = 1, 2 do i = 1, 2 o(i,j) = 0.0 do m = 1, 3 o(i,j) = o(i,j) + a(m,j) * b(i,m) enddo enddo enddo で o が結果の2x2行列ね。習慣で(i,j)=(列、行)の番地にしてもうたけどいいやね。 そういや行列のサイズ数をいうときの行と列をよく間違えてしまうw
797 :
デフォルトの名無しさん :2009/12/07(月) 23:28:25
>>758 x=x+vx*dt*i
y=y+vy*dt*i
R=sqrt(x**2+y**2)
vx=vx-K*(x/R)*dt*i
vy=vy-K*(y/R)*dt*i
上のiがすべていらない。
>>798 同意w
でも知らないうちにコードミスで転置行列にしてしまうことがあるw
do 800 i = 1, 800 write(*,*) '800 get' 800 continue
はじめてきました。 ド素人質問失礼します。 コンパイラはG95で、Fファイルで実行します。 OSはVISTAです。 N個の値(整数値0~100)の中から最大・最小・偏差値を出したくてこうしました。 DO 10 I=1,N READ(5,*) SC(I) MA=MAX0(SC(I)) MI=MIN0(SC(I)) 10 CONTINUE するとエラーが MA=MAX0(SC(I)) 1 MI=MIN0(SC(I)) 1 に Intrinsic'max0'at(1)must have at least two arguments Intrinsic'min0'at(1)must have at least two arguments と出ます。 配列を組み込み関数の引数に使ってるのが違うのかと思うのですが、配列を使えるようにする方法が何かないかが主に知りたいです。
>>801 すみません、、、
改行でずれました、、、
MA=MAX0(SC(I))
___1
MI=MIN0(SC(I))
___1
です。
MAX0というのがどういう関数なのか知らないが、 MAXと同じなら MA = MAX( MA, SC( I ) ) MAは要初期値。 配列に全部読み込んでから最大値を求めるなら MAXVAL( SC )
フォートランを研究室で指定されて使おうとしてるんですけど
http://www.salfordsoftware.co.uk/ のどこからダウンロードするのかみつからないんですけど教えてくれますか?
あとフォートランは遺産が多いと聞きましたがうちの研究室は転用が禁止らしいのですが
フォートランの意味はあまりないということでしょうか?
簡単な質問ですがお願いします
806 :
805 :2009/12/14(月) 02:35:45
なんとかなりそうです スレ汚し失礼しました
ああ、Fortran依存症がまたひとり・・・・いらっしゃい!
>>805 転用禁止は、遺産うんぬんの前に、「理解して勉強しろ」ということだろう。
結局わからなくてゼミの先輩にインストールするためのプログラム(ftn77pe.exe)を貰ったんですが 64ビットバージョンのwindowsでの非互換性のためプログラムまたは機能である~~を開始または実行できません ソフトウェア製造元に問い合わせて64ビットWindows互換バージョンが利用可能であるかどうか確認してください とでました。OSはwindows7です。7に対応していないんでしょうか? こういった場合どういう解決策がありますか?お願いします。
今、浮動小数点例外を握りつぶす処理を入れてるんですが、 処理を入れた部分以外のところをコンパイルオプションでトラップしたいです。 が、オプションを入れると既に処理を入れた部分の判別条件で引っかかってしまいます。 未処理の部分だけトラップしたいんですが何かいい方法はないでしょうか。
サイトを隅から隅まで探してもfortranをダウンロードするページみつけれませんでした・・・ 64ビットのがあるんでしょうか
>>810 トラップって何?
具体的にどうしたいのか分からないけど、ソースの或る特定の部分を無視して
コンパイルしたいのであれば、プリプロセッサを使ってみたら?
>>810 CALL IEEE_SET_HALTING_MODE(云々)
あたりでなんとかならんか?
Fortran2003の機能だが、最近のコンパイラはサポートしているので・・
Sun solais10のSunStudio12(SunFortran)で書かれたプログラムが動かなくて困っています 浮動小数点例外でcore吐いて停止していますが ファイルがバッファに残ったままとまっている為 どこまで進んでから落ちたのか良く判りません 環境変数かなんかでバッファサイズを0若しくは充分小さく出来ないでしょうか? ソースをゴタゴタと生成している部分がありコンパイルが容易ではなく 出来ればflushを挟んでの再コンパイルを避けたいのです intelのfortranなら出来るチックな話はぐぐったら出てきましたが......
815 :
773 :2009/12/17(木) 23:42:36
NAG Fortran Builder 5.2 で, program main print *, 'Hello World !' stop end のクイック実行のコンパイル&リンクに12分50秒もかかった現象について,先週の土曜日に ここで質問をした者ですが,パソコンにインストールしているウイルス対策テスト F-Secure Internet Security 2010 のメーカーであるエフセキュアのサポートセンターにも 問い合わせたところ,解決案を幾つか提示されました。 結局それらのうちの1つの『 ディープガードの無効化 』をすることで, コンパイル&リンクにかかる時間が通常どおり大幅に短縮されて,約10秒で 終わるようになりました。 アドバイスを下さった方々,ありがとうございました。
816 :
773 :2009/12/19(土) 11:37:10
↑のその後です。 昨日,エフセキュアのサポートセンターとメールでやり取りし, 「『 ディープガードの無効化』をするとセキュリティレベルが下がるので, その代わりに『高度なモニタリング』を無効化する。 それで駄目なら『ファイルを除外スキャン』でスキャン対象から除外したい ファイル・フォルダを選択する」 という対処方法に変わりました。 これで F-Secure Internet Security 2010 の『 ディープガードの無効化』と 『高度なモニタリング』の両方が有効な環境下での NAG Fortran Builder の 動作の正常化が確保できました。
817 :
773 :2009/12/19(土) 11:43:02
↑書き間違えました。 (誤)『 ディープガードの無効化』と『高度なモニタリング』の両方が有効な環境下 (正)『 ディープガード』と『高度なモニタリング』の両方が有効な環境下
818 :
デフォルトの名無しさん :2009/12/19(土) 13:30:00
とりあえず、おめ! なるほど、そっちか
セキュリティかよw 確かに最近のセキュリティソフトは色々とガチガチだからな
820 :
デフォルトの名無しさん :2009/12/22(火) 16:23:38
なるほどー
ググってもなかったんで、質問させてください。 fortranのプログラムみてると、ccccccc ~~ ccccccc って感じでcに囲まれてる文字があるんだけど、このcの意味ってなんなんですか? すいません。教えてください
>>821 1桁目が 'C' かアスタリスク '*' の行はコメント行。
だから 'CCC…' はプログラム上は意味はないけど、
人間が読む時に処理の内容や区切りをわかりやすくするため等によく使われる。
>>822 ありがとうございます。
コメントは「!」とどこかでみたので、cは違うのかと思ってました。
本当にありがとうございました
>>823 ! で始まる部分をコメントとするのは,Fortran 90 以降の自由形式で書かれるソースコード。
この場合は ! は必ずしも1桁目でなくても良い。
2桁目以降でも良いし,実行分の後ろに付けるのでも構わない。
一方,1桁目が C か * で始まるのをコメント行とするのは,FORTRAN 77 の固定形式ソースコード。
↑[訂正] × 実行分 ○ 実行文
>>824 丁寧にありがとうございます。
すごい勉強になりました!
今日、入門用の本を買ってきたので、頑張って勉強したいとおもいます。
すみません,ちょっとスレ違いな質問で申し訳ないのですが‥‥ ここにならご存知の方が誰かいるかもしれないと思ったので, 質問させていただきます。 Fortran の後継言語として Sun が開発中だった Fortress は 今はどうなってるんでしょうか? お蔵入りなのでしょうか?
オラクルに買収されたけど、Sunの手から離れたから関係ないのかな?
質問です。あるファイルが存在したらそのファイルをread、 存在しなければ別の処理をする、という分岐を作りたいのですが どうすればよいでしょうか?ファイルの有無で0か1を返すような 関数があれば手っ取り早いんですが、見つかりませんでした。
>>831 stat() を使ってゴニョゴニョとできんじゃろうか?
open文でerr=指定子を使うのがfortran流だろう。
INQUIRE(FILE='hage.dat', EXIST=LHOGE)
>>832-834 最後のinquire使うのが王道かのぅ。
logical lhoge
character*100 fname
do i = 1, 100
write(fname,'(i5.5,''.dat'')') i
inquire(file=fname,exist=lhoge)
if (lhoge) then
read.....
else
nanka....
endif
enddo
とか、いろいろ。
ERR子はたしか返す値がシステムごとに違った記憶があるから怖い。
・・・気のせいな気もするけどね。
いままでコンパイルを行うとき、サブルーチンとmainファイルを同じディレクトリに置き * ifort.f90 でコンパイルしていたのですが, サブルーチンを別ディレクトリにし,コンパイルするにはどうしたらよいのでしょうか。 たとえばサブルーチンをSubというディレクトリに置き、 mainファイルをMainというディレクトリに置いて実行ファイルを作るにはどうしたらよいのでしょうか。
ifort90 main.F90 Sub/sub1.F90 Sub/sub2.F90 ... でいいんじゃね?あと Makefile 書いちゃうとかかな。 何をムズカシイと思っているのかがよく分からない。
838 :
デフォルトの名無しさん :2010/01/13(水) 15:03:32
>>837 そうしたいのですが,mainファイルをコンパイルしようとするとサブルーチンが定義されていないと言われ,
サブルーチンをコンパイルしようとするとmainファイルがないとエラーがでるんです
>>838 ifort90ってどこのコンパイラ?
-c付けて.oファイルがどこにできるか確認してみたら?
intel fortranだが普通にカレントディレクトリに全部の.oが出てくるけど
unixでのコンパイルに耐えられずに、VisualStdioとintelのコンパイラを教官殿に買ってもらった俺と比べてみんな偉いな
>>839 > ifort90ってどこのコンパイラ?
ifort のことだろうけど、OS は何なんだろうな。どうにも挙動が変態だ。
Windows だと変な動きするとかあるんだろうか?
前に、担当の人が気を利かせてaliasというかいくつかオプションをつけたコマンドを作ってくれていて それが他のと干渉して・・という事があった気がするけど、そのifort90 もそれの類の匂いがするが、 いかがか?
>>838 皆様のレスのおかげで解決できました、ありがとうございます
ifort90はifortの打ち間違えです、申し訳ない
なんという・・・w
打ち間違え? じゃあ command not found って出てたはずだよな・・・ まぁ、頑張ってくれや
すみません インテル Visual Fortranコンパイラ9.1を使用したいのですが、インストール後 サンプルプログラム(int_sin.f90)をコンパイルしようとしたのですが、下記のエラーがでてしまい、うまくできません。 エラー内容: ifort: error: unable to run '<Microsoft VC++ Dir>\\Bin' Microsoft Visual C++ 2008 Express Editionはインストール済みです。 OSはVista Home premium32bitです。 どなたか助けてくださいorz
>>832 ,833,834,835
大変遅くなりましたがありがとうございました。
inquire文で行けそうです。
もう一つ質問ですが、動的配列を宣言するときにある次元だけ固定って
できますか?まあ別にそうする必要は無いといえばないんですが、
宣言部を見ただけでどこが動的である必然性があるのか分かった方が
自分としてはスッキリするので。ちなみに
DOUBLE PRECISION,allocatable::a(10,:,:)
…
allocate (CS(10,10,10))
とやったら金比羅にしかられました。
よろしくおねがいします。
>>847 > DOUBLE PRECISION,allocatable::a(10,:,:)
> …
> allocate (CS(10,10,10))
>
> とやったら金比羅にしかられました。
CS ってどこで宣言してんだ?
どう呵られたのかはしらんけども、こっちでも呵られた。
ということで無難に
DOUBLE PRECISION,allocatable::a(:,:,:)
としておけば良いと思う。それで問題になることは無いだろうから。
>>848 すいません、CSじゃなくてaですね。中途半端にコピペしてしまった…
やっぱそうするべきみたいですね。コメントでもつけてそうしておきます。
ありがとうございました。
一瞬、金比羅って何って思ってしまった 中国系の上司の名前かとw
下記のようにimplicit none 付きで、 算術関数 cos 及び derf に関する実験をしているのですが、 cosはreal(8) derf のような宣言が必要ないのはなぜでしょうか。 derfに関しては宣言をしないと、コンパイラ(pgf95 ,7.2-4)に文句を言われます。 program main implicit none real(8) derf real(8) x x = dble(0.7) print*,derf(x) print*,cos(x) end よろしくお願いいたします。
>>851 COSはFORTRANの規格で規定されているINTRINSICな関数で、COSは総称名になっている。
引数の型で関数の値の型も決まる。
ただ、66時代の互換性などから、個別の型をあらわに指定するDCOSなどもある。
しかし77時代以降は総称名を使うのが推奨されていたはず。
さて、ERFの方だがこれはFORTRANの規格にはないベンダーの提供する独自関数である。
したがってその実装や用法はベンダーに依存する。
たとえばINTEL FORTRANの場合は、REAL(8)の宣言無しにDERFが使える。
PGIでは、外部関数扱いで、関数の型を宣言しておく必要があるのだろう。
なお、ERFというのはUNIX系の多くのFORTRANで使えた関数で、半ば標準化している。
Fortran2008ではそれらのエラー関数、ベッセル関数などが正規の規格に入ることになっている。
853 :
851 :2010/01/19(火) 00:21:02
>>852 大変分かりやすい解説をしていただき、ありがとうございました。
derfもintrinsicな関数だと思い込んでいました。
>>852 >しかし77時代以降は総称名を使うのが推奨されていたはず。
マジ?
律儀にD*使ってた・・・
人のデータ使う場合、単と倍精度が入れ乱れるし・・・ 普通にd* で明示してもいいと思うけどな。 単精度に揃えたい!とかはコンパイルオプションで出来るし。
やっぱ総称名って使わないほうがいいの?
857 :
デフォルトの名無しさん :2010/01/19(火) 21:21:43
インテル Visual Fortranコンパイラ9.1を使っているんですが、インストール後 サンプルプログラム(sample.for)をコンパイルしたところ、下記のエラーがでてしまい、うまくできません。 エラー内容: ifort: error: unable to run '<Microsoft VC++ Dir>\\Bin' このため、.objファイルは出力されるのですが、exeファイルが出力されません。 よろしくお願いします。
859 :
デフォルトの名無しさん :2010/01/24(日) 21:39:26
"2500/500"のような文字を読み込んで、 2500 / 500 = 5 を計算したいのですが、下のコードでは "/"が読み込めないみたいです。 改善方法を教えていただけないでしょうか? できれば、"2500"や"500"の部分を任意の桁数でできると幸いです。 コンパイラはG95です。 IMPLICIT NONE CHARACTER :: A*5, B, C*5 REAL*8 :: Num1, Num2 PRINT*, "Input" READ*, A, B, C PRINT*, "A=", A, " B=", B, " C=",C READ(A(1:), *) Num1 READ(C(1:), *) Num2 PRINT*, Num1/Num2 END よろしくお願いします。
>>859 FortranのI/Oでは「/」は改行を意味している。
よって文字と解釈していなのだろう。
前にもそんな事を聞いていた奴がいたような・・・
回避する方法は、わからん。
文法書のI/Oのところをじっくり読んで自分で考えてくれ。
861 :
860 :2010/01/24(日) 22:27:59
>>859 しらべたw
READ文にFORMAT指定をすればよろし。
READ '(3A)', A,B,C
とすれば多分おk
862 :
859 :2010/01/24(日) 22:57:22
>>860 "/"を文字として認識することができました。
ありがとうございます。
863 :
860 :2010/01/25(月) 00:38:43
>>859 おk。
任意の桁数でやるには
INTEGER :: kslash
CHARACTER(128) :: text
READ '(A)', text
kslash = INDEX(text, '/')
READ( A(1:kslash - 1), * ) num1
READ( C(kslash + 1:), * ) num2
という感じだろう。TRIMでtextの尻の空白を切ったほうがいいかもしれん。
むろん任意と言ってもREALの範囲内の数だが・・
訂正www READ( text(1:kslash - 1), * ) num1 READ( text(kslash + 1:), * ) num2
865 :
859 :2010/01/25(月) 07:35:21
>> 863 おお!重ね重ねありがとうございます。 無事に作ることができました。
初心者すぎて笑われるかもしれませんが平面上の3点の座標で三角形つくるときの面積を求めたいのですが 当然ながらヘロンの公式でやりました 辺の長さが出てる場合であればうまくいくのですが長さの計算も入れようとするとどう座標を扱えばいいかちんぷんかんぷんで X(I)とY(I)で1~3まで動かしかたがわからないというか…その考えが間違ってるのかもわからないです
>>863 Fortran兄貴降臨!いつもお疲れさまっす。
ただ、Fortranの思想的に
>>859 みたいなことは、やるべきではないとは思う。
perlでもpythonでもシェルでもいいが、Fortran実行ファイルを適当なラッパーで
くるむほうが、素直で良いと思う。
>>866 君なりのソースをここに書けば直して貰えると思うよ。
>>866 数学がわからんの?
Fortranがわからんの?
上の方も書いてるけど、わかってるところまでのソースを書くとよろし。
>>867 Fortranでパーサー書こうぜ!
再帰があるから、77時代ほど難しくないはず・・・
871 :
デフォルトの名無しさん :2010/01/26(火) 14:19:14
>>870 とてもうろ覚えだけど・・・
DECのVMSってFortranでかなりの部分は書かれていたような。
IMEというか英語を日本語に変えるやつは堂々Fortranだったような。
・・・とてもうろ覚えだけど。
872 :
デフォルトの名無しさん :2010/01/29(金) 08:26:49
はじめまして。初心者ですがよろしくお願いします。 突然ですが、この問題を解ける方いらっしゃいますか。 学校の宿題なのですが、どうしても分からないのでここにきました。 お願いします。 問題こちら↓ 階乗 n! を計算する関数を作成し, 順列 n個の異なるものからr個取り出して並べる。 このときの順列の総数をnPrとあらわす。 nPr=n(n-1)(n-2)・・・(n-r+1) を計算する関数を作成し, 組み合わせ 異なるn個からr個取り出して組を作る。 このときの組合せの総数をnCrとあらわす。 nCr = nPr/r! を計算するプログラムを作成しなさい。(問題終わり) よろしくお願いします。
Permut[n_, r_] := Pochhammer[1 + n - r, r] Permut[n, r]/r!
オープンしている特定のファイルのバッファを フラッシュする方法はありますか。コンパイラはifortです。 出来ればクローズしないでフラッシュしたいのですが、 どうしてもバッファにたまってしまいます。 よろしくお願いします。
872の丸投げぶりはすごいな。 途中まで書いたソースコードでもここに貼ったら?
C/C++の宿題スレが丸投げだからその流れがこちらまで来たか
初秋の青空を連想するくらいのすがすがしい 丸投げw
879 :
874 :2010/01/31(日) 04:55:24
丸投げ、流行ってるな。
ifort -g -check all traceback
とかでNaNにかぎらず異常値が発生したらその行を教えてくれるような実行ファイルをつくってくれる
オプションがあるはずだから、マニュアルよんでみよう。
>>878 それ、よさそうだね。
ログ生成がゆっくりの場合、あるていど溜るまでディスクには書かれないから不便な事がおおかったけど、
いろいろと助かりそうだ。参考にするよ!
へぇそんなんあったんだ
>>880 66スタイルで何やってるかわからんなw
NUMPACK使っているところを見ると、富士通、名大・九大・京大あたりの流れか。
ライブラリ関数が無いから実行することもできないしもっと詳しく書いてくれないと誰も答えられないだろう。
まぁ定数や関数の一部が単精度のままなので倍精度にしている意味がない可能性が高い。
その辺かな?w
>>882 FLUSHはFortran2003で導入された命令。
IntelのHELPはF2003命令がいまいち入ってなかったりしてアレなので、
文法解説書を買って学ぶがよろしい。
>>885 そうなんだ。何年か前に g77 でサブルーチン版の flush をつかったことあがった。
今確認したら、やっぱり使えた。因みに g95 だと関数版の flush が使えた。関数
版だと戻り値でエラーチェックできるから有り難い。
887 :
デフォルトの名無しさん :2010/02/07(日) 15:54:15
FFTについて質問させてください。 大学の講義で、離散フーリエ変換のプログラムについて勉強中です。 講義の最後に、「バイオリンの音のデータをフーリエ変換し、 フーリエ変換した結果を横軸:周波数、縦軸:振幅としてグラフ化せよ」 という課題が出ました。 配布されたデータの読み込みを試みたのですが、どう読み込ませたらいいのかが分かりません。 配布されたデータは2列で構成されており、左の列が時刻データ、右の列は音の振幅を表しています。 ↓にプログラムを書きます。よろしくお願いします。
888 :
デフォルトの名無しさん :2010/02/07(日) 15:56:08
--前半-- program fft implicit none !======================================================================== include "fftw_f77.i" integer*8 ::plan !======================================================================== !サンプリング条件の設定 !サンプリングデータ数N , aの数Ma , bの数Mb !サンプリング間隔dt = 1/44100 [s] , サンプリング周波数 f0 = 44100 [Hz] , N, Ma, Mb !周波数分解能df=1/(N・dt) integer,parameter:: N=10000,Ma=5000,Mb=4999 real(8),parameter:: df=44100/dble(N) , dt=1.0d0/44100 !入力波形のデータの設定fin=100Hz real(8) ::fin,a0 !作業用の変数 complex(8):: in(N),out(N),c(0:n-1) integer ::i real(8) ::t,a(0:Ma),b(1:Mb),x,y
889 :
デフォルトの名無しさん :2010/02/07(日) 15:57:26
--後半-- !入力データの設定 write(*,*) 'Input data:' open(unit=11,file='violin.dat') do i=1,N ※ここが分かりません!※ end do close (11) !======================================================================== !ライブラリを利用したフーリエ変換(作業領域作成と実行) call fftw_f77_create_plan(plan,N,FFTW_FORWARD,FFTW_ESTIMATE) !準備 call fftw_f77_one(plan,in,out) !実行 !======================================================================== !結果の変換 c(0:N-1)=out(1:N) a(0)=c(0) a(1:Ma)=dble( c(1:Ma)+c(N-1:N-Ma:-1) ) b(1:Mb)=dble( (c(1:Mb)-c(N-1:N-Mb:-1))*(0.0d0,1.0d0) ) !======================================================================== !結果の出力 write(*,*) 'Output data after forward FFT:' open(unit=22,file='ab-.csv') open(unit=21,file='c-.csv') do i=1,N write(21,'(i6,'','',1pe16.8,'','',1pe16.8)') i,out(i) end do write(22,'(1pe16.8,'','',1pe16.8,'','',1pe16.8)') 0.0,a(0),0.0 write(22,'(1pe16.8,'','',1pe16.8,'','',1pe16.8)') (i*df,a(i),b(i),i=1,Mb) if (Ma/=Mb) write(22,'(1pe16.8,'','',1pe16.8,'','',1pe16.8)') Ma*df,a(Ma),0.0 close (21) close (22)
890 :
デフォルトの名無しさん :2010/02/07(日) 15:59:09
--ラスト-- !======================================================================== !フーリエ変換(作業領域消去) call fftw_f77_destroy_plan(plan) end program fft
むしろ、データファイルの中身が必要なんじゃね?
894 :
デフォルトの名無しさん :2010/02/07(日) 22:48:06
そうなんすよ。 彼女と遊びすぎて留年しちゃったもんで・・・。
お前はこのスレを敵にまわした。
自分が今いるサブルーチンの名前を取得する方法ってありますか? デバッグするときにどのサブルーチンで止まってるか確かめたいんですが。
終了したのが なんていうサブルーチンで何行目か、とか ソースファイルの何行目だったか、とか教えてくれるようにする オプションってあったと思うけどなぁ。というわけでマニュアルを読もう! Fujitsuだと超最適化かけてもこの機能はついてくるのが素晴らしいが PC向けではなかったような・・・。出してくれんかねぇ
>>898 いえ、それがめんどくさいことに終了せずにどこかで停止してるんですよ。
write文の中身をいちいち変えてもいいんですけど、
出来るだけコード汚さないように書きたいので。
すみません、もう一つ。subroutineの最後に return end って書くのはなんででしょう。サブルーチンでのendってreturnと 同じ意味じゃないんでしょうか?returnが無いと困るケースってあります?
ヒント: returnはサブルーチンの最後である必要は無い。
大昔はEndSubroutineが無かったから、 このEndはサブルーチンのですよ、とチェックをいれる意味で 推奨されてた名残だね。ぶっちゃげ無くてEndだけでもいい。 Returnはサブルーチン抜けを意味するのだからメイン階層では絶対出てこないので。
900じゃないけどreturnとか使った事ありませんでした 勉強になるスレです
>>897 __FILE__ を使って後はゴニョゴニョとよくやってた。
Fortran 自体を使わなくなって数年(足を洗ったので)。
>>899 Fortranにはそういう命令はない。
しかしコンパイラのtracebackオプションを使えばいい。
大抵のコンパイラにはそういう機能がある。
だがそれは、処理系に依るのでマニュアルでオプションを調べるしか無い。
コンパイラの種類とバージョンを言えばわかる可能性はある。
__LINE__使えるんじゃないの?
>>906 標準のFortranにはないべ。
Unix系のプリプロセッサの機能だろ。方言のなまりがきつすぎる。
908 :
ごめんなさい、お願いです。 :2010/02/10(水) 00:51:22
このプログラムを 明日までに作ってください!!お願いします。 Fortranで, 階乗 n! を計算する関数を作成し, 順列 n個の異なるものからr個取り出して並べる。 このときの順列の総数をnPrとあらわす。 nPr=n(n-1)(n-2)・・・(n-r+1) を計算する関数を作成し, 組み合わせ 異なるn個からr個取り出して組を作る。 このときの組合せの総数をnCrとあらわす。 nCr = nPr/r! を計算するプログラムを作成してください。 おねがいします。
>>908 最近勉強しているのでFortran95 で書いてみた。
たぶん君が求めているのはF77ヴァージョンだろうw
MODULE m_2chan
IMPLICIT NONE
CONTAINS
ELEMENTAL INTEGER FUNCTION factorial(n)
INTEGER, INTENT(IN) :: n
INTEGER :: i
factorial = PRODUCT( (/ (i, i = 1, n) /) )
RETURN
END FUNCTION factorial
ELEMENTAL INTEGER FUNCTION permutation(n, r)
INTEGER, INTENT(IN) :: n, r
INTEGER :: i
permutation = PRODUCT( (/ (i, i = n, n - r + 1, -1) /) )
RETURN
END FUNCTION permutation
ELEMENTAL INTEGER FUNCTION combination(n, r)
INTEGER, INTENT(IN) :: n, r
combination = permutation(n, r) / factorial(r)
RETURN
END FUNCTION combination
END MODULE m_2chan
!
PROGRAM twochannel USE m_2chan IMPLICIT NONE INTEGER :: n, k PRINT *, 'INPUT n and k' READ *, n, k PRINT *, 'nCk = ', combination(n, k) STOP END PROGRAM twochannel 77育ちの俺様は、暗黙の型に従っていないのですげー気持ち悪いぜwww
>>908 数学的にチューニングすべきだが、提示された式のとおりに作った。PROGRAMは改行多杉になるので省略
integer function factorial(n)
implicit none
integer i, n
i = n
factorial = 1
do while(i .gt. 0)
factorial = factorial * i
i = i - 1;
end do
end
integer function permutation(n, r)
implicit none
integer n, r, i
i = 1
permutation = 1;
do while(i .le. r)
permutation = permutation * (n - i + 1)
i = i + 1
end do
end
integer function combination(n, r)
integer n, r, factorial, permutation
combination = permutation(n, r) / factorial(r)
end
908の人気に嫉妬
913 :
デフォルトの名無しさん :2010/02/10(水) 08:58:43
>>901 >>902 あ、そうなんですか。別に書かなくてもいいってことですね?
>>904 >>905 >>906 ありがとうございます。でも、エラーが出て終了するんじゃなくて、
ジョブは走ってるんですけどどこかで止まってるっぽいんですよ。
出力ファイルが計算途中で更新されなくなるんです。
で、どこまで進んでどこでどうなってるか調べたいのでいちいちwrite文挟んでるんですが…
tracebackって終了したときしか使えないですよね?
デバッガー無いのか? アタッチ出来れば楽勝だな。
915 :
908です。 :2010/02/10(水) 11:57:13
みなさん、ありがとうございました!!(泣
>>913 仰る通り Traceback は異常終了しないとでない。
しかし、望みの機能が存在しないのは、世の中の人がその機能を欲していないということなので
がんばってPRINT文をばらまいて解決しなさいw
プログラム相談員とか、そういう人に聞くのも、連中の人を小馬鹿にしたような寝言を我慢しないと
駄目だが、有効w
>>916 >連中の人を小馬鹿にしたような寝言を我慢しないと駄目だが
ワロタw
あの目線はどうにかならんのか
918 :
デフォルトの名無しさん :2010/02/11(木) 22:18:28
ちょっとお聞きしたいのですが、 fortranでguiプログラミングはできないのでしょうか?
>>918 C用のライブラリのAPIを呼びまくるという形ではできる。
920 :
デフォルトの名無しさん :2010/02/13(土) 17:03:50
つ Digital Visual Fortran
AbsoftもLaheyもQuickWin相当のGUI開発用の付録は付けている。
>>920 なつかしいw
use dflib
(中略)
call YesOrNo()
で「はい・いいえ」ボタンが出てきてそれだけで感動したなw
924 :
デフォルトの名無しさん :2010/02/25(木) 07:35:58
絶対に通らないIF文が速度に与える影響ってどんなもんでしょうか つまり、IF(ndebug==0) THEN....って感じでデバッグ用の表示を各所に 挟みこみたいんですけど、これってndebug.ne.0の時でも速度に影響しちゃいますか?
ndebug の値が静的に(Paramete文とかで)与えられていると そのIF~Endifブロック全体を無視するコンパイラ(IntelとFujitsuはそうだった)も あるよ。その場合には速度に影響なし。 Ndebugが動的に変わる数の場合にはいちいち判定処理するから 少しは遅くなるだろうね。でも、検算やデバッグの部分は躊躇せず ガンガン埋め込んで使うほうが(精神的にw)いいとおもう。 プリプロセス有りのコンパイラなら #if 文つかっていろいろ出来るけどね。 Fortranの標準機能ではないからなぁ。
タイトなループ中だとパイプラインが乱れて遅くなる場合もある。 投機実行等の手法もあるけど、分岐は無い方がCPUに優しい。
くだすれがなんの略語なのか最近気付いた…
なに?
皆さん専門はなんです? 今時FORTRAN使ってるてことはアカデミックな人ですよね? 私は物性物理です。
930 :
デフォルトの名無しさん :2010/03/07(日) 06:35:47
流体
全然気付かないというか気にもとめてなかたぜよ
プログラム技術 くだすれFORTRAN(超初心者用) くだすれC++Builder(超初心者用) くだすれPython(超初心者用) くだすれDelphi(超初心者用) くだすれCUDAスレ WEBプログラミング くだすれPerl くだすれPHP
web制作管理 くだすれAjax(超初心者用)
936 :
デフォルトの名無しさん :2010/03/08(月) 06:11:10
で、なんで「宿題」が「くだすれ」になったの?
CUDAスレ
>このスレッドは、他のスレッドでは書き込めない超低レベル、 >もしくは質問者自身何が何だか分からない質問を勇気を持って書き込むスレッドです。
939 :
デフォルトの名無しさん :2010/03/20(土) 00:06:59
fortran77です 各サブルーチンでcommon文をまとめてincludeしようと思いますが、 当然サブルーチンによっては使用しない箇所も出てきます。 この場合、各サブルーチンで最小限のcommonを設定するのに比べて 速度が遅くなったりするのでしょうか?
940 :
デフォルトの名無しさん :2010/03/20(土) 03:01:50
しない。 Commonブロックそのものを一つにまとめるのならメモリ番地走査が遅くなって悪影響が出るかもしれないけど。 Commonブロックのリストを使わない分まで書いても悪さしない。
commonなんて使うな
>>940 たぶんそうだと思うのだが、改めてF77の規格を読んでみると、名前付きCOMMONはSAVEで
ないから、動的に取られたり消えたりしてもおかしくない気もする。
ただ、慣例から静的にとられていると思うが。
943 :
デフォルトの名無しさん :2010/03/21(日) 05:46:40
ね。 Commom使うな教の教義は静的であることの保証がないという点にある。 でもDEC神がCommonはLabelアリ無し関係無しに静的配置にしますと規定したので後続もしたがった。 だから、規格原典にしたがえば、Allocateした変数をCommonに関連付けることもできるけど、 ほとんどのコンパイラは警告するか処理を打ち切る・・のが普通だけど、 やはり規格外のベンダ依存な部分は恐いやね。うっかりやっちゃいそうだし、 複数人でなんかコード作るときは禁忌にしておかないとあとで悲惨な事になる>< 以前はコモン使いまくりだった(実際その方が速かった時期が長い、とおもう)けど 最近では固定サイズなら配列名をArgumentに羅列しても速度は違わんね。 動的配列やら自動配列みたいにコンパイルする時点でサイズ不明だと遅くなる事がおおいけど、 これはループの終端値が不定なせいでUnrollingが抑制されるからで メモリ配置最適化ができないことの影響は無いか小さいとおもう・・・ので最近 コモン使うよ教から使わないよ教に主旨かえしたw。 コモン使うなよ教になる気はないけどね。
毎年入ってくる新入生がfortranを勉強しようと77の本を手に取るのを 黙って見過ごすのはえも言われぬ空しさがある・・・ 嗚呼負のスパイラル
Visual Basic のように簡単に Windows用 GUI アプリケーションが作れる Fortran のベンダーを知りませんか。 Intel の Visual Fortran だとなんだか難しそうで‥‥。 Absoft Pro Fortran や PGI Visual Fortran なら簡単にできますか?
>>944 これ以上77なソースを増やさないでくれ
たのむ
>>945 DEC神wの系列の quickwin 以上に簡単なもの無理じゃないかねぇ
>>944 ,946
wwww
F77より後の機能をちゃんと間違えなく使おうとするとF77しらないと、
ということも多いからね。LatexとTexみたいなもので知ってても困らん。
まあ学生のうちに複数の計算機なり人間の言語に触れることは良い事だ
>>947 しかし、大概の77のテキストは
100 FORMAT(1H , ・・・・・
などとなっていて、「この1H っては何ですか?」などと聞いてこられるので、
66から勉強しろとも言えず、ホレリスからイチイチ説明するのもメンドイので
いい加減に流すのであった。ラインプリンタも見ることも無いし。
テキスト書く人は、もう少し頑張って欲しい。
ほとんど情弱化している。
最近出た入門Fortranとか、g95とGNUPlotでFortranとか期待したのに、中身があまりに古くて爆死した。
なるほど、Hは・・・聞かれるといろいろ困るなw どこまで・どこからの線引きは難しいなあ。 Doループも長~いやつだと意図して番号+Continueするとかあるし・・・ gfortran -Wall だと年代wのチェックはしないしねぇ。いいチェッカがあるといいんだけど。 教科書は・・・英字のも含めてあまり進歩はないような。 教科書的なのは儲からんのだろうね。 漫画でわかる・・とかでないといかんのかね。だれか 「やる夫がFortranで何かするようです」でも作ってよ。
やる夫がやる気のない教科書を参考にしたようなコードを書こうとする度に やらない夫のツッコミが入るとかw
>>947 >F77より後の機能をちゃんと間違えなく使おうとするとF77しらないと、
“ちゃんと”学ぶのであればそれでいいんだけど、大半はそこまでの探求心を持たないんだよね。
つーかこの手の問題はFortranに限った話じゃないのかもしれん・・・
(AA略) いまどき固定書式~ 固定書式が許されるのは50過ぎだけだよね~ ・・・むかつくな
まったく関係ないけど、gfortran を入れるとおまけ(?)でgccも入ってくるのね。 Win機に一年前にいれてたのに今気づいた・・・
>>953 gfortran が gcc のオマケ
>>954 そうなんだけど、このスレ的には指摘してほしくなかったw
Intel Visual Fortran と PGI Visual Fortran のどちらを買おうか迷っています。 Intel Visual Fortran に対する PGI Visual Fortran の優位性は何かあるでしょうか?
ない
958 :
956 :2010/03/24(水) 05:49:41
速さとかどうなんでしょう?
959 :
デフォルトの名無しさん :2010/03/24(水) 06:46:56
GPGPUとかやるならPGI。MPIの並列デバッグとかもやりやすいはず。
960 :
デフォルトの名無しさん :2010/03/24(水) 09:16:36
ほうほう、いいこと聞いた。 Intel のをずいぶんながく使ってきたおかげ(これはこれでよいものではある)で 他のをあまりしらない通りすがりだけど、ありがとう。参考にしよう。
GPGPUねぇ Fortran対応してるってのが売りだったっけか 実際使いもんになるの?
ちょちょいとやってぱっというわけには行かないけど、 OpenMPみたいに対象のループ前後にディレクティブ挿入するだけのやつでも それなりの高速化は図れる。MPIと同等かそれより簡単なくらい。 CUDA fortranは敷居高いけどきちんとチューニングしたらかなり早い。 勉強中だけどMPIより難しいと思う。もちろん元の計算の並列性にもよる。
CUDAに限らないけど、CPU外部のユニットに計算を依頼するタイプのは データ格納の配列を大量に宣言するからメモリがんがん喰うよね。
964 :
958 :2010/03/25(木) 17:32:41
>>959 >>962 いい情報が聞けました。ありがとうございました。
他にもPGIの優れた点があったら,ぜひ引き続きお教えください m(_ _)m
CUDAは難しすぎる・・・
cuda openmp mpi...特性というかいろいろ前提が違うからねぇ。 ま~3つとも使えるからしばらくは Fortran を使いつづけてもいいか
openmpは簡単
>>967 元のコードに付け足すだけだからね。簡単だしお手軽。Coreが2個以上のPCがあればWinでもLinuxでも
自宅でおてがるに並列計算ができてしまう。gfortran ならタダだし。Macはしらん。
OpenMPだけで一生めしが喰えるとは思えないけど、100CPUくらいならあんまり激烈に能率は落ちない
システムも多いし、知っていて損はしないとおもう。
・・・まあFortranの話じゃなかったね。
>>950 文関数使ったやる夫がやらない夫に殴られる・・とか
暗黙の型宣言つかったやる夫が(略)
do 30 i = 1. 5 (なんとかかんとか) 30 continue に気付かないやらない夫を笑うやる夫、とか。
素朴な質問なんだがC/C++を使わずにFORTRANのみを 使う人って数値演算用ライブラリを使いたいためか?
>>968 SMPで100CPUって当分先じゃない?・・・と思ったが、
今出回ってるのがせいぜい12コアのCPUが4つ(4way)で
計48コアだから、そう先の話でもないか
>>971 >FORTRANのみを使う人
イマドキこんなやつはいないか、いても老人。
FORTRAN使う理由云々ならわかるけど
ふと思ったんだが、大文字でFORTRANって言うと、通常は77のことを指すんだよね?
77「以前」が正解 77だけじゃなくて66なども含む
大文字とか小文字とか些末なこと2ちゃんで気にするなよ
>>973 いやいやw
本職メインで、計算機はしょうがないから使ってるタイプは、Fortranしかやってないよ。
コンピュータ嫌いだから。
本職メインの意味が分からない
頭痛が痛い
>>972 疑似共有ならSMP100コア以上というのは大学の計算機センタなら帝大でなくてもわりとあるよ。
980番になるとおもうけど・・・スレ立て能力ないので、どなたかプリーズ。
>>977 だろうね。オレもそうだった。計算論いじりなんぞに費やす時間があるなら
他の事に回したい。
>>980 そうなの?Intel、AMD系のシステム?
SGIのAltixなら使ってる(た)が、あれも100まではなかった希ガス
>>981 そういう人達のニーズもきっちり取り込むのが、Fortranが今も続いている理由だからな
>>871 うちの職場の仕事は流体解析分野などなんだけど,C/C++ は使わず,
Intel Fortran(と Cシェル スクリプトと GMT と AWK と たまに
ExcelVBA)を使っている。
仕事は外部の研究者からの計算依頼でコーディングする,という
パターンだけれど, 過去に他人が作った FORTRAN プログラムを使ったり,
自分で Fortran 90/95 プログラムを作ったりで,C/C++ は今のところ
必要ないので俺は全然使ってない。
ただ同じ職場でも人によっては VC++ で OpenGL やってる人もいる。
どちらにせよ,俺は C/C++ が大嫌いで(←良し悪しではなく完全に
好みの問題。気を悪くされたらごめん)Fortran が大好きな Fortranist だから,
今の環境にはとても満足している。
984 :
983 :2010/03/27(土) 17:22:04
アンカー間違えた。
>>971 でした。ごめんなさい m(_ _;)m
FortranはCに乗り換える必然性があるほど問題のある言語でもないし、 むしろ配列演算が便利で並列化コンパイルに有利だし、 別にFortran一本でやっててもいいと思う ただしFORTRAN、てめーはダメだ
配列演算って、A(:)=B(:)+C(:)みたいな? Cでは出来ないの?
forで回すしかない せいぜいそういう関数を作って誤摩化すのが関の山 C++ならそういうクラスを(ry
>>978 大学とかにいれば本職メインでない人いっぱい見てるだろw
10年くらい前の、自作クラスターブームの頃、その手のシンポジウムとかに
物理学科の奴らが大挙して出てきたので、情報学科の奴らがあいつら何者だよwwwと
生暖かく見ていたのが思い出される。
本職メイン
>>988 ないのかぁ
規格にはなってなくても、ベンダー独自で拡張してるかと思ってた