楕円積分を数値計算で求めようとしています。
Fortranを使っているのですが、まずニューメリカルレシピinCをFortranに直して実行しました。
きちんと翻訳して直したはずなので、それなりの値が出るのですが、どうも誤差が大きいようです。
それはMathematicaでの組み込み関数による計算と比較したことによります。どちらがより近いのかはわからないのですが・・・。(Mathematicaでの計算は正しい(かなり近い)値を返してくれているのでしょうか?どなたか知っておられたらそちらも教えていただけるとありがたいです。どの程度信用できるのか。。。)
どちらにせよ、いいプログラムはないでしょうか?
ちょっと難しいかもしれませんが、よろしくお願いします。

このQ&Aに関連する最新のQ&A

翻訳 比較」に関するQ&A: 翻訳ソフトの比較

A 回答 (1件)

わざわざ翻訳しなくても


Numerical Recipes in Fortranを
使えばよいのでは

参考URL:http://www.library.cornell.edu/nr/
    • good
    • 0
この回答へのお礼

はい、もちろんそうしようと思ってみたのですが、同じプログラムが見つからなかったんです。
日本語版の方では内容が違うようで。。。(他な項はきちんとそのまま直訳してあるのですが。)
でも、よく見たら見つけることができました。
+Mathematicaと答えが違うと質問に書いてしまいましたが、kの定義がMathematicaとその他の本やプログラムで違うことに気づき、僕の勘違いでした。
両方ちゃんと信用できる値が返ってきます。
ありがとうございました。

お礼日時:2005/04/21 13:58

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q[C言語]コンソールからのデータ入力時の誤動作の回避方法

趣味でプログラミングをしております。
環境は、以下です。
Windows10
Mingw-w64
gcc version 5.2.0 (Rev4, Built by MSYS2 project)

https://oshiete.goo.ne.jp/qa/9287118.htmlの回答2にて、
3つの数字を入力し、数字でない場合は再入力を促すプログラムを提示しました。
これについて、他の回答者様より「fflush(stdin); は一般にはやっていけない操作」との回答をいただきました。

私の環境では、fflush(stdin)を使用しないと以下の様に1回目に誤ったデータを入力すると、再入力時のメッセージが2回繰り返し表示されます。
(推測ですが、windowsで改行コードが2Byteであることから発生しているのではと考えています)

fflush(stdin)を使用しないで、この問題を回避する適切な方法がありましたらご教示ください。

よろしくお願いします。


----------実行結果(fflush(stdin)を使用しない場合)
$ ./a.exe
重複しない3つの数字:abc
重複しない3つの数字:重複しない3つの数字:abc
重複しない3つの数字:重複しない3つの数字:
----------


----------ソース
#include <ctype.h>

#define BUF_SIZE 3 // 3文字

int main(void){
char buf[BUF_SIZE + 1];
int user;

while(1){
fflush(stdin);
printf("重複しない3つの数字:");
fflush(stdout);

fgets(buf, BUF_SIZE + 1, stdin);
if(!isdigit(buf[0])) continue; // 1文字目が数字かチェック
if(!isdigit(buf[1])) continue; // 2文字目が数字かチェック
if(!isdigit(buf[2])) continue; // 3文字目が数字かチェック
break;
}
user = atoi(buf);
printf("number : %d", user);

return 0;
}
----------

趣味でプログラミングをしております。
環境は、以下です。
Windows10
Mingw-w64
gcc version 5.2.0 (Rev4, Built by MSYS2 project)

https://oshiete.goo.ne.jp/qa/9287118.htmlの回答2にて、
3つの数字を入力し、数字でない場合は再入力を促すプログラムを提示しました。
これについて、他の回答者様より「fflush(stdin); は一般にはやっていけない操作」との回答をいただきました。

私の環境では、fflush(stdin)を使用しないと以下の様に1回目に誤ったデータを入力すると、再入力時のメッセージが2...続きを読む

Aベストアンサー

>他の回答者様より「fflush(stdin); は一般にはやっていけない操作」との回答をいただきました。

規格にstdinに対して実施した場合の動作が明記されていないから。
だったかと。
実装依存する。ということです。


>推測ですが、windowsで改行コードが2Byteであることから発生しているのではと考えています

ライブラリー依存でしょうかね。
¥rと¥nの両方をfgets()が改行として処理したのかも知れません。
gccだし。

>fflush(stdin)を使用しないで、この問題を回避する適切な方法がありましたらご教示ください。

読み込み用のバッファをもう少し大きく用意する。でしょうか。

1回目、"abc"を読み込みます。
第2引数で指定した3バイトに達したため。
stdinのバッファには¥rと¥nが残ってます。

2回目、¥rを読み込みます。
fgets()の仕様により改行コードに到達したため。

1回目の読み込みで残るのに注意です。
# 2回目で¥rだけなのか¥r¥nなのか、はたまた¥r¥nが¥nに変換されるのか…はfgets()の後で内容確認してください。

>他の回答者様より「fflush(stdin); は一般にはやっていけない操作」との回答をいただきました。

規格にstdinに対して実施した場合の動作が明記されていないから。
だったかと。
実装依存する。ということです。


>推測ですが、windowsで改行コードが2Byteであることから発生しているのではと考えています

ライブラリー依存でしょうかね。
¥rと¥nの両方をfgets()が改行として処理したのかも知れません。
gccだし。

>fflush(stdin)を使用しないで、この問題を回避する適切な方法がありましたらご教示ください。...続きを読む

QFortran90/Fortran95→Fortran77

大学の授業でFortranを使ったプログラミングを勉強しています。

以下の文が大学のPCに入っているコンパイラでは問題なくコンパイルでき実行できるのですが、家のPCだとコンパイルすることが出来ません(以下の文でエラーが出ます)
大学のPCの開発環境はFujitsu-FORTRANだと思います(^ ^;
家のPCはSalford FTN77 Personal Edition CompilerとCPad for Salford FTN77を組み合わせて使用しています

なぜエラーがでるのか自分なりに考えた結果、Fortran90/Fortran95のプログラムをFortran77のコンパイラでコンパイルしているからだと思います(全くの勘違いだったら指摘して下さい)

Fortran90/Fortran95の開発環境がフリーで整えばいいのですが、見つからないのでプログラムを修正したいと思います そこで、力を貸していただきたいのです

前置きが長くなりましたが、エラーが出る文は以下のところです
open(8,file='freq_ex13.dat',action='write',status='replace')
ここを、Fortran77のコンパイラでコンパイルできるようにアドバイスを下さい よろしくお願いします

大学の授業でFortranを使ったプログラミングを勉強しています。

以下の文が大学のPCに入っているコンパイラでは問題なくコンパイルでき実行できるのですが、家のPCだとコンパイルすることが出来ません(以下の文でエラーが出ます)
大学のPCの開発環境はFujitsu-FORTRANだと思います(^ ^;
家のPCはSalford FTN77 Personal Edition CompilerとCPad for Salford FTN77を組み合わせて使用しています

なぜエラーがでるのか自分なりに考えた結果、Fortran90/Fortran95のプログラムをFortran77のコンパイラでコン...続きを読む

Aベストアンサー

action='write'を削除してみては?
8番にREADを使わなければいいだけの話です。
http://docs.hp.com/ja/B3908-90007/ch10s65.html#id21163286

Fortranはコンパイラ毎に独自の拡張が相当されてますから、移植する際にはどの拡張が使えるのか把握する必要があります。
使えない場合はコンパイルエラーが返ってくるのですぐにわかりますけど。
http://www.cc.nao.ac.jp/vppman/HTML/japan/langFort/fvp11/fvp00079.htm

参考URL:http://docs.hp.com/ja/B3908-90007/ch10s65.html#id21163286

QC言語Char型配列に小数値を入れる方法

C言語Char型配列に小数値を入れる方法について質問なんですが、
分からなく質問させていただきました。

(例)23.8を

float f = 23.8
char c[100];

cの配列の中に23.8を入れる

c[0] = '2'
c[1] = '3'
c[2] = '.'
c[4] = '8'
c[5] = '\0'


上記みたいに入ってほしいんですが、そういうC言語の関数ありますか?
itoaやsprintfを使わないでお願いします。

Aベストアンサー

> いえ、HEWで作成していて itoaとsprintfが使用できなくて質問しました

マイコンが何か、またツールチェインが何か知りませんが、いずれにせよsprintfが使えるはずです。
メモリが足りないということでしょうか?

必要な情報は小出しにせず、すべて明らかにしてください。

QFortranの変数の配列の設定値を計算中に設定するには?

FortranでプログラムをつくるときAという変数にBの値の範囲で配列を設定する。A(B)
このとき、プログラム作成時にはAには具体的な数値を設定しておかなくても良いですが、Bには具体的に配列の数を設定しておく必要があるように思います。
 質問は、
 プログラムが動く初めにはBに具体的な値を入れず、プログラム作動状況に応じてプログラム作動中にBの配列の範囲を設定できないものでしょうか?

Aベストアンサー

プログラム A がサブルーチンなら可能です。

メインプログラム
 C=10
 if( C .GT. 0 ) call A(C)
 STOP
 END
 
サブルーチン A
 sub A(B)
  dim(B)
 returne

QC言語 配列で座標

C言語で二次元の配列a[11][11]を考えたとき、a[1][0]はxy座標の(1,0)を、a[0][5]はxy座標の(0, 5)を表しているという風な考えはあっているのでしょうか?
また、C言語で、xy座標で(0.5, 3.1)などの小数を表そうとしたらどうしたら良いのでしょうか?

Aベストアンサー

もう少し数の小さい例で説明します。
以下のように配列を宣言したとします。

***************
//配列宣言
int a[3][4];
***************

この場合 int型の値を格納できる変数が3×4=12個
作られたと考えることができます。

配列の使い方は以下のようになります。

*********************
//配列の扱い方の例
a[0][0]=1;
a[0][1]=234;
a[0][2]=-123;
a[0][3]=5;

a[1][0]=a[0][2];



*******************
つまり普通のint型の変数とそれぞれが同じ扱い方ができます。
どの様に使うかは様々です。

イメージとしては

  [0][1][2][3]
[0] □ □ □ □
[1] □ □ □ □
[2] □ □ □ □

このようなint型の値が格納できる箱が用意されるような感じです。

ここからは主観ですが
配列で座標を扱うといった概念はあまりないように思います。
たくさんの座標を扱うのであれば便利かもしれません。


少数の座標を表現する方法ですが

****************
//double型で座標を表現
double x = 0.5;
double y = 3.1;
****************

のように扱うといいかもしれません。
構造体を知っているのであれば
それで記述するとまとまって見やすいかもしれません。

もう少し数の小さい例で説明します。
以下のように配列を宣言したとします。

***************
//配列宣言
int a[3][4];
***************

この場合 int型の値を格納できる変数が3×4=12個
作られたと考えることができます。

配列の使い方は以下のようになります。

*********************
//配列の扱い方の例
a[0][0]=1;
a[0][1]=234;
a[0][2]=-123;
a[0][3]=5;

a[1][0]=a[0][2];



*******************
つまり普通のint型の変数とそれぞれが同じ扱い方ができます。
どの...続きを読む

QMathematicaで関数の最大値を求める

Mathematicaで複素数の関数S(t)があったとします。
このS(t)の絶対値の最大値が知りたい時、どのように入力すればよいでしょうか?

Aベストアンサー

 S[t]は複素数関数ということですが、絶対値を取ってAbs[S[t]]とすれば結局は実数関数となるので、あとはこの実数関数を最大化すれば良いわけですね。

 ところが、Mathematicaには関数の最大化を行う関数はありません。まあこの点については最小化を行うFindMinimum関数があるため、正負を反転させた関数-Abs[S[t]]の最小化を行えば目的を達成することはできます。

 しかし、問題はFindMinimumで求められるのは局所的最小解であって、大域的最小解ではないということです(そもそも任意の関数の最小値を求める手法は未だ発見されていない)。これについては、幸い目的関数-Abs[S[t]]が1変数関数であるため、Plot関数で最小解がありそうな範囲の見当をつけてからFindMinimumで適切な初期値を与えてやれば、S[t]の絶対値の最大値を求めることができると思います。

Plot[-Abs[S[t]],{t,0,10}]←範囲は適当に変えて下さい
FindMinimum[-Abs[S[t]],{t,t0}]←t0(局所的最適解を求めるための初期点)は適切なものを与えて下さい

 S[t]は複素数関数ということですが、絶対値を取ってAbs[S[t]]とすれば結局は実数関数となるので、あとはこの実数関数を最大化すれば良いわけですね。

 ところが、Mathematicaには関数の最大化を行う関数はありません。まあこの点については最小化を行うFindMinimum関数があるため、正負を反転させた関数-Abs[S[t]]の最小化を行えば目的を達成することはできます。

 しかし、問題はFindMinimumで求められるのは局所的最小解であって、大域的最小解ではないということです(そもそも任意の関数の最小値を...続きを読む

QC言語 ポインタと配列

C言語で配列をあつかう場合、ポインタをつかうか、配列の添え字を使って処理するか迷うのですが、どちらが良いのでしょうか?
処理速度ではどちらが上でしょうか?

Aベストアンサー

いきなり
a[x]
と書いた場合は、他の回答のように
*(a+x)
と同じ処理速度です。

しかし
for(i=0;i<1000;) {
ホゲホゲ=a[i++];
}

型 *p = a;
for(i=0;i<1000;) {
ホゲホゲ=*p++;
}
では、処理速度に差が出ます。

前者では「毎回、aとiを加算して実効アドレス値を求め、値の取り出し後、iをインクリメントする」と言う処理が行われます。

しかし、後者では「毎回のアドレスの計算はせず、pから直接に実効アドレスをロードして使い、値の取り出し後、pに一定値を加算する」と言う処理が行われます。

「どちらが早いか?」は、コンパイラごと、実行するCPUごとに違うので、どちらと明言する事は出来ませんが、明らかに言えるのは「前者と後者では、異なる機械語コードが生成される筈だから、速度に差が出る筈」と言う事。

ま、どう考えても「毎回、加算を行ってアドレス値を作る」のと「アドレス値を持って来るだけ」なら、後者の方が早いでしょう(断言はしませんが)

そう言った訳で「連続したアドレスから順番に中身を取り出す」とか「連続したアドレスに順番に中身を詰め込む」なら、ポインタを用いるべきでしょう。

いきなり
a[x]
と書いた場合は、他の回答のように
*(a+x)
と同じ処理速度です。

しかし
for(i=0;i<1000;) {
ホゲホゲ=a[i++];
}

型 *p = a;
for(i=0;i<1000;) {
ホゲホゲ=*p++;
}
では、処理速度に差が出ます。

前者では「毎回、aとiを加算して実効アドレス値を求め、値の取り出し後、iをインクリメントする」と言う処理が行われます。

しかし、後者では「毎回のアドレスの計算はせず、pから直接に実効アドレスをロードして使い、値の取り出し後、pに一定値を加算する」と言う処理が行わ...続きを読む

QMS-FortranとFortran90

私は研究でFortran90を使っているのですが、研究に使うプログラムはMS-Fortranを用いて書かれているものでした。

そこで質問なんですが、MS-FortranとFortran90の違いについて知っている方がいれば教えてください。
また、MS-FortranでかかれたソースコードをFortranにコピーした時に何か弊害はあるのでしょうか?(人づてに弊害が起こると聞いたことがあるのですが・・・)。

プログラミングを本格的に始めて、まだ3ヶ月ほどで用語の使い方がわかりにくいところがあるかもしれませんがよろしくお願いします。

Aベストアンサー

MicrosoftがFortranを出していた時期を考えると、多分ですが、Fortran77だと思いますね。
Fortran90自体、製品が揃ったのは90年からかなり立っています。そのころには、Microsoftの言語製品はCとBASICだけになっていたんじゃないかな。

なお、MS-Fortranに限らず、intel系のFortranでは、86系のアーキテクチャの影響でホストに比べ、一部の機能が制限されている場合があります、これらについてはマニュアルを参照してください。

QC言語 配列の長さの上限

C言語で配列Array[N]の長さNの上限っていくらなんでしょうか?
もし可能なのであれば上限を2147483647にしたいのですが、方法を教えてください。

Aベストアンサー

そもそもWindowsの32bit版はアプリが仮想メモリ空間を2GBしか使えません。2GBを超えるには64bit版が必要です。
たとえ64bit版OSだとしても添え字が2147483647って、単純なintの配列だとしても4x2147483647=8GB必要ですね。実メモリ16GBとかのPCを用意しますか?
そもそも配列で2147483647個必要なアルゴリズムに問題ありだと思います。

QFortran77 (intel fortran)

Fortran77のプログラムをIntel Fortran (ifort v14.0.1)でコンパイルした時、以下のワーニングがでます。

remark #8291: Recommended relationship between field width 'W' and the number of fractional digits 'D' in this edit descriptor is 'W>=D+7'.
100 FORMAT(12E9.3)
--------------------------^

100の書式はREAL*8で宣言された変数を書き出す時に使っています。

これは具体的にはどういう問題について警告しているのでしょうか?

環境はCentOS6.5 32bitにて実行しています。

よろしくお願いいたします。

Aベストアンサー

E9.3って、全体を9文字で、小数点以下を3文字でと言う意味ですが、全体幅は小数点以下幅の+7以上であるべきと言うのがウォーニングメッセージ内容です。

+0.123E+00

のように、小数点以下の数字以外に、符号1桁、小数点以上1桁以上、小数点自体に1桁、Eが1桁、指数部符号1桁、指数部2桁で、合計7桁以上必要です。


人気Q&Aランキング

おすすめ情報