
方程式 cos^2x-0.5=0 (0<x<π) の解をニュートン法で求める
という問題をC言語のプログラムを作り計算したいのですが分かりません。
自分で考えてみたプログラムは以下の通りです。
#include <stdio.h>
#include <math.h>
#define f1(x) cos(x)*cos(x)-0.5
#define f2(x) sin(2*x)
/* ニュートン法による方程式の解 */
main()
{
double x0,x1,a,b,c,d,g,n;
a=1;
x0=0.7;
n=0;
while(a>0.0001){
b=x0;
d=f1(b);
g=f2(b);
x1=x0-d/g;
c=x1;
a=f1(c);
n=n+1;
printf(" n= %f x1=%f x0=%f\n",n,x1,x0);
printf(" a= %f → 解 x= %f \n", a,x1);
x0=x1;
}
}
自分としてはこれが精一杯で、何故間違ってるのか、何をどうすればいいのか、さっぱり分かりません。どういったところが間違ってるのか可能性だけでも示して頂ければ幸いです。
参考として、ニュートン法によるプログラム例として書かれていたものを上げさせて頂きます。
例: e^x-3=0 の解をニュートン法により計算する。
#include <stdio.h>
#include <math.h>
#define f1(x) exp(x)-3
#define f2(x) exp(x)
/* ニュートン法による方程式の解 */
main()
{
double x0,x1,e,a,b,c,d,g,n;
a=1;
x0=3;
n=0;
while(a>0.0001){
b=x0;
d=f1(b);
g=f2(b);
x1=x0-d/g;
c=x1;
a=f1(c);
n=n+1;
printf(" n= %f x1=%f x0=%f\n",n,x1,x0);
printf(" a= %f → 解 x= %f \n", a,x1);
x0=x1;
}
}
A 回答 (6件)
- 最新から表示
- 回答順に表示
No.6
- 回答日時:
>正常には作動しているのですが
>範囲がおかしいのか1回しか計算されない
そうですか?
初期値x0に解の近傍の0.7与えているんで1回しか計算されなくてもしょーがない、とか思うんですけどね。
一般に、ニュートン法は収束までのステップ数は短いんで、当然だ、と思いますよ。
それより、問題は収束判定の
a>0.0001
の方だと思います。これがaが負になった場合、対処してない、って思うんですが。
例えば、計算でf1(c)=-2000何とやら、となった場合、そこで計算が止まってしまいます。これは要求仕様じゃないでしょ?
多分、やりたかったのはaの絶対値>0.0001だと踏んでるんですが、それがコードに反映されていません。問題の性質から言うと、初期値はπの付近(例えば3.0とか)からスタートしても解を返さなきゃならない筈、なんですが、元々のコードを微分の部分だけ手直ししたら、おかしな解が出てくるんじゃないのかな、って思います。
その辺、ちょっと見てみてください。
No.4
- 回答日時:
> (sin^2x)'
> =2(sinx)(sinx)'
> =2sinx*cosx
> =sin(2X)
>
> となると思ったのですが…
> よろしければ微分の何が違ってるかご指摘下さい。お願いします。
微分される関数はcos^2x - 0.5ですよね?
なぜsin^2xの微分をしているのでしょうか?
(cos^2x - 0.5)'
= (cosx)(-sinx)
= -(sinx)(cosx)
= -sin2x
となります。
何度もありがとうございます。
焦って違う問題の計算メモを書いてしまいました。
すみません。
マイナスがなかったのも自分の字が汚かっただけのようです。
ご丁寧にありがとうございました。
No.2
- 回答日時:
Cのマナーの部分と、数学の部分と、2つありますね。
Cの部分:
1:書き出しはmain()じゃなくってint main(void)にした方が良い。
これはツマラない部分ですし、計算結果は同じですが、「Cのマナー」としては、引数を取らないmain関数では引数はvoid、とした方が良い、です。
また、main関数の返り値自体も厳密に言うと、「計算結果とは別にして」OSに対して整数が返されます。従って、
2:正常にプログラムが終了した事を伝える為、返り値を返すように必ず最後にreturn 0;を付ける。
これもマナーです。計算結果を別にOSに「正常終了したよ~~。」と教える為、return 0;も必ず記述するようにしましょう。
数学の部分:
#1さんも仰っている通り、(cos(x))^2-0.5の微分はsin(2*x)になりません。計算ミス、ですね。
プログラムは「言われた通りに計算してる」だけですんで、与えた微分係数が間違ってても感知せずに、「言われた通りに計算している」だけです。
特に、コンパイル時にエラーが出ないで正常実行出来るCによるプログラムの場合、プログラムの記法自体にはさほど問題が見られません。つまり、こう言うケースでは「プログラムを記述した人間が」何かミスをした、って事ですね。
このソースも微分係数をキチンと書き換えれば、そのままキチンとした計算結果を返してくれました。つまり、全体としてのロジックは全然間違ってなく、単に「与えた微分係数が間違ってた」ってだけですね。
回答ありがとうございます。
Cのマナーについてですが、今このように授業で習っているのでその先生に対して違う書き方でプログラムを書いて出すことは出来ないのでどうかそこは見逃して下さい。一応、cametan_42がおっしゃられている書き方が基本だと理解してはいるのですが…。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
10の-9乗ってどういう意味ですか?
-
座標ズレ質問
-
写真のような分配ばねの等価ば...
-
確率の問題で、「5人の中から3...
-
高低差のある支持点で,電線の...
-
二点の座標から直線の方程式を...
-
線形代数の質問です。
-
再度、4点を通る曲線の方程式
-
log-logの補間式
-
単調増加関数とは何か?
-
連立二階微分方程式
-
辞書式配列の求め方に確信が持...
-
対数方程式ってこうやって最終...
-
外点ペナルティ関数法
-
プラスとマイナスが入った比率...
-
シグマなど文字を含んだままで...
-
真割引とは?
-
3000円が3割なら10割はいくらで...
-
滴定の実験で、結果をExcelで一...
-
「日常生活における数列」とは...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
おすすめ情報