ニュートン法を使って解を求めるC言語プログラム

このQ&Aのポイント
  • C言語を使ってy=x^2-4xのyの解をニュートン法を使って求めるプログラムを作成しました。しかし、ニュートン法がよくわからず、微分についても理解がないため、プログラムの動作が正しくありません。
  • このプログラムはコンパイルはできますが、ニュートン法の原理や微分の概念について理解がないため、正しい結果を返しません。
  • ニュートン法についてできるだけ分かりやすく解説してほしいです。工業系の学校で数学の授業がなく、微分について知識がないため、具体的な説明が必要です。
回答を見る
  • ベストアンサー

ニュートン法を使って解を求めるC言語プログラム

C言語を使って y=x^2-4x のyの解をニュートン法を使って求める プログラムを作る課題を出されたんですが、ニュートン法が良く分かっていないので、いろいろ調べたり、人に聞いたりしたところ #include<stdio.h> #include<math.h> void main() { int counter=0; double an,g,f,sh=0.0001; printf("初期値を入力して下さい==>"); scanf("%ld",&an); do{ g=(an*an)/(2*an-4); f=2*an-4; counter++; }while(fabs(f)>sh); printf("反復回数 %d 回 y=%lf \n",counter,g); } でプログラムがこんな感じになったんですが、結局ニュートン法がどうなのかがわかりません。 なんか微分とかやるとか言われたんですが、工業系の学校で数学の授業が無いので微分についてがわかりません。 このプログラムは、コンパイルはできるんですが、動きません。 ニュートン法についてよくわからないのでどこが間違ってるかわかりません。 ニュートン法についてできるだけ分かりやすく解説してほしいです。

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

  • ベストアンサー
  • fatbowler
  • ベストアンサー率48% (26/54)
回答No.1

ニュートン法を理解するには、せめて微分の初歩の初歩は理解して下さい。 とりあえず、必要なところだけ。 y=x^2-4x の解をもとめるには、次のようにします。 計算途中の近似解をa(n)とすると、それを元に得られる、より精度の良い近似解a(n+1)は、 a(n+1)=(a(n)*a(n))/(2*a(n)-4) として求められます。(ニュートン法の理論から) これを繰り返していって、 |a(n+1)-a(n)| < 0.0001 となったときに、十分精度の良い解が得られたと判断し、計算を終了します。 (計算終了の閾値0.0001は提示されたプログラムから取りました。) プログラムの間違いは、下記の2点。 誤:scanf("%ld",&an); 正:scanf("%lf",&an); 誤:f=2*an-4; 正:f=g-an; an=g; 上記を修正し、初期値が2より大きい場合は4.000000が、初期値が2未満のときは 0.000000が求められることを確かめて下さい。

fon4203
質問者

お礼

できました。 ありがとうございます。

その他の回答 (1)

回答No.2

下記URL参照。

参考URL:
http://blogs.wankuma.com/episteme/archive/2007/06/29/82963.aspx

関連するQ&A

  • ニュートン法をC言語でプログラム

    方程式 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; } }

  • C言語のプログラム

    C言語で2つの微分方程式をEuler法、Heun法、Runge-Kutta法により求めるプログラムを作りたい。ただし、初期条件はx=0,y=1とする。また、間隔Δxを変えたときの解の変化を調べたい。 Euler法のプログラムはどうにか分かったのですが、Heun法、Runge-Kutta法のプログラムがわかりません。 Euler法のプログラム #include_<stdio.h> #include_<math.h> int_main(){ __double__a=0; __double__b; __int_____m=10; __int_____n; __double__h; __double__x,y; __double__dydx; __int_____k; __double__e; __double__f; __printf("オイラー法計算例:y=e^x,_y=1/e^4x\n\n"); __//_y_=_e^x __b_=_1; __for(n=100;n<=10000;n*=100){ ____h_=_(b-a)/n; ____printf("y'_=_y:_h(=dx)_=_%.1e_(y=e^x)\n",h); ____x_=_a;_y_=_1; ____for(k=0;k<=n;k++)_{ ______x_=_k*h; ______if(k%(n/m)==0)_{ ________f_=_exp(x); ________e_=_fabs(y-f); ________printf("x=%.2f,_y=%f,_e^x=%f_er=%.0e\n", ________x,y,f,e); ______} ______dydx_=_y; ______y_=_y_+_dydx*h; ____} __} __printf("\n"); __//_y_=_1/e^4x __b_=_4; __for(n=100;n<=10000;n*=100){ ____h_=_(b-a)/n; ____printf("y'_=_-4y:_h(=dx)_=_%.1e_(y=1/e^4x)\n",h); ____x_=_a;_y_=_1; ____for(k=0;k<=n;k++)_{ ______x_=_k*h; ______if(k%(n/m)==0)_{ ________f_=_exp(-4*x); ________e_=_fabs(y-f); ________printf("x=%.2f,_y=%f,_1/e^4x=%f_er=%.0e\n", ________x,y,f,e); ______} ______dydx_=_-4*y; ______y_=_y_+_dydx*h; ____} __} __return_0; } 分かる方がいましたら、回答よろしくお願いします。

  • C言語 ニュートン法

    何をすればいいかよくわからなくて躓きました わかる方どうかお願いします 問 以下に示すプログラムで、x1 = x0 - f (x0) / f '(x0)を用いて、方程式の左辺関数 f (x) (= x 2 - a ) およびその導関数 f '(x) を独立させろ。 入力変数 a はグローバル変数としてよい。 導関数 f '(x)はプログラム内ではdfと表記することとする。 また、適切なコメントも追加すること。 /* newton.c: ニュートン法 */ #include <stdio.h> // printf, fprintf, fgets, sscanf #include <math.h> // fabs double newton(double x, double (*f)(double), double (*df)(double), double eps) {   int n;   double a = 0, x, x0, err, eps = 1.0e-10;   printf("# n, x, err\n");   printf("%4d, % .15e\n", n, x);   do {     n++;     x0 = x;     x = (x0 + a/x0) / 2;     err = fabs(x-x0);     printf("%4d, % .8e, % .8e\n", n, x, err);   } while (err > eps);     return x; } int main(void) {    double a = 0, x, x0, err, eps = 1.0e-10;    char s[128];   fprintf(stderr, " a = "); fgets(s, 128, stdin); sscanf(s, "%lf", &a);   while (a <= 0.0) {    fprintf(stderr, "'a' には正の数を入れてください。\n");   fprintf(stderr, " a = "); fgets(s, 128, stdin); sscanf(s, "%lf", &a);   }   x = (a + 1.0) / 2.0;   printf("\n# sqrt(%e) = % .15e\n", a, x);    return 0; }

  • ニュートン法で解が収束しない

    こんにちは。 差分式で表した非線形方程式をニュートン法で解いています。が収束しな解あります。ニュートン法は初期値に依存しているため、初期値を可変的にしてみましたがダメでした。何かいい方法はないでしょうか? 参考になるか分かりませんが、使っているプログラムのニュートン法の計算の一部は以下のようです。 call g(x,f,df) h=f/df x=x-h if(dabs(h/x)<1.d-14) then  return endif

  • C言語のプログラムを作るのに困っています。

    C言語で、4次のルンゲクッタ法を用いて微分方程式を解くプログラムを作成したいのですが、始めたばかりの初心者で分からないところだらけなので教えてください。 わからないなりに、下のプログラムを作ってみましたがエラーになります。どうすればうまくいくのでしょうか。本当に始めたばかりなので、文?の組立もよくわかりません。できればわかりやすくお願いします。 このプログラムでは微分方程式dy/dx=x^3+4xy+y+2の解を求めようとしています(自分で適当に作った方程式なので、あるのかどうかわかりません)。 そのほかにもy'=2x^2+3xy-1や、y'=sinxcosy, y'=e^xなどいろいろな微分方程式でできるようにしたいのですが、どうやるのでしょうか。 #include <stdio.h> double f(double x,double y); int main() { double x,y,dx,xmax; double k1,k2,k3,k4; FILE *fp; if ((fp=fopen("result.txt","w"))==NULL) { printf("Cannot open result.txt \n"); return 0; } dx=0.1; //刻み幅 xmax=100.0; //繰り返し最大 x=1.0; //xの初期値 y=1.0; //yの初期値 f(x,y)=x^3+4xy+y+2;; //関数f(x,y)の定義 for(x=1.0;x<xmax;x+=0.1) { k1=dx*f(x,y); k2=dx*f(x+dx/2.0,y+k1/2.0); k3=dx*f(x+dx/2.0,y+k2/2.0); k4=dx*f(x+dx,y+k3); y=y+(k1+2.0*k2+2.0*k3+k4)/6.0; printf(" %f %lf \n",x,y); fprintf(fp," %f %lf \n",x ,y); } return 0; }

  • ニュートン法

    ニュートン法の問題です。 全平面で正則な複素関数f(z)=u(x,y)+i*v(x,y)(z=x+iy) の零点を求めるニュートン法は z(k+1)=z(k)-f(z(k))/f'(z(k)) ですが、 これは2元連立方程式 u(x,y)=0 v(x,y)=0 を解くニュートン法と等価であることを示せ という問題です。 とっかかりからわからないのですが、複素関数の微分の表現の仕方がわからないのと、u(x,y)=0のように2変数でしかも、抽象的に書かれるとニュートン法がわかりにくくなっているという点で困っています。 分かる方、解説よろしくお願いします。

  • ニュートン法

    ケプラー方程式x-e*sin(x)-c=0の解をステップ数とともに出力するプログラムで、e,cはそれぞれ0.5と1です。 xに値を入力して計算させるのですが、どうしてもできません。 下のプログラムリストでおかしいところはどこでしょうか? // ニュートン法 x-e*sin(x)-c=0 #include <stdio.h> #include <math.h> #define e 0.5 #define c 1.0 #define K 10000 double fun(double x); double bibun(int i,double x); float m=1.0,n=1.0; int i=1; main(){ float x1,x2; float z; printf("初期値x0を入力して下さい\n"); scanf("%f",&x1); for(i=0;i<=K;i++){ x2 = x1 - fun(x1)/bibun(i,x1); x1 = x2; z = fun(x1); z = fabs(z); if(fabs(z)<=0.00001){ break; } if(i==K){ printf("収束しません\n"); exit(0); }    } printf("解 = %f\n",x1); printf("ステップ数 = %d",i); return 0; } // 関数f(x) double fun(double x1){ double r; r = x1 - e * sin(x1) - c; return r; } // 微分 double bibun(int i,double x1){ float p; if(i%2==1){ p = pow((-1.0),m)*e*sin(x1); m++; } else { p = pow((-1.0),n)*e*cos(x1); n++; } return p; }

  • C言語の質問です

    ニュートン法のプログラムを組んだのですがPAD図が描けなくて困ってます どなたか回答お願いします /* newton.c: ニュートン法 */ #include <stdio.h> // printf, fprintf, fgets, sscanf #include <math.h> // fabs double a;    //グローバル変数 double f(double x)  //fは関数f(x) { return x * x - a; //f(x)=x~2-a } double df(double x)  //dfはf(x)の導関数f’(x) { return 2 * x; //df(x)/dx = 2x } double newton(double x, double (*f)(double), double (*df)(double), double eps) { int n = 0;     //初期化 double x0, err;    //x0は初期値 printf("# n, x, err\n"); printf("%4d, % .15e\n", n, x); do { n++; x0 = x; x = x0 - f(x0) / df(x0); //切片でy=0、x=x1 err = fabs(x-x0); printf("%4d, % .8e, % .15e\n", n, x, err); } while (err >= eps); return x; } /*メインルーチン*/ int main(void) { double x, eps = 1.0e-10; //収束条件 char s[128]; fprintf(stderr, " a = "); fgets(s, 128, stdin); sscanf(s, "%lf", &a); while (a <= 0.0) { fprintf(stderr, "'a' には正の数を入れてください。\n"); fprintf(stderr, " a = "); fgets(s, 128, stdin); sscanf(s, "%lf", &a); } x = (a + 1.0) / 2.0; x = newton(x, f, df, eps);   //ニュートン法の実装 printf("\n# √(%e) = % .15e\n", a, x); return 0; }

  • (C言語)プログラムが動きません。

    下のC言語のプログラムを書いたのですが、動きません。上手く作動していれば画面に「結果をrunge1.csvに書き込みました」と表示されてテキストファイルが作成されるはずですが、プログラムを実行しても何のメッセージも表示されずファイルも作成されません。ですが、bcpadのエラーメッセージの欄には何も表示されず、どこを直せばいいのか分かりません。アドバイスを下さい。お願いします。 /*ルンゲ・クッタ法による微分方程式y'+y*y=xの解*/ #include<stdio.h> #include<math.h> #define N 100 int main(void) { char *file="runge1.csv"; double x0=0.0,x1=5.0,y0=0.0,x,y,h,k1,k2,k3,k4; int i; FILE *fp; h=(x0-x1)/N; x=x0; y=y0; fp=fopen(file,"w"); fprintf(fp,"x,Runge-y\n"); fprintf(fp,"%3.2f,%3.5f\n",x,y); for(i=1;i<=N;i++){ x+=h; k1=(x-y*y)*h; k2=(x-y*y+k1/2.0)*h; k3=(x-y*y+k2/2.0)*h; k4=(x-y*y+k3)*h; y=(x-y*y)+(k1+2*k2+2*k3+k4)/6.0; fprintf(fp,"%3.2f,%3.5f\n",x,y); } fclose(fp); printf("結果を%sに書き込みました。\n",file); return(0); }

  • 数値計算法の二分法、ニュートン法のc言語プログラムについて

    y=x^2-2x+8について二分法、ニュートン法より範囲[0, 1.5]でy=0となるxの値を求めるプログラムってどうやればいいですか?

専門家に質問してみよう