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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Q&A

解決済

2回答

448閲覧

ニュートン法について

EUROPEAN

総合スコア17

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

0グッド

0クリップ

投稿2018/10/04 05:20

ニュートン法を用いた問題で
方程式 f(x) = x^2 − 2 として,方程式 f(x) = 0 を
実行時に与えた初期値のもとで
Newton 法によって解くプログラムを作成したいのですが思い通りの結果になりません。
Newton 反復を 1 回行う関数の戻り値がよくわかっていないためだと思います。
変更すべき点を教えていただければ幸いです。

#include <stdio.h> #include <math.h> #define K_MAX 100 #define DX 1.0e-10 #define EPS 1.0e-10 void input(double *x); double f(double x); double df(double x); double g(double x); int newton(double *x); int main(void) { double x; int k; input(&x); k = newton(&x); printf("\n<%d> f(%.16f) = %.16f\n",k,x,f(x)); return 0; } void input(double *x) { printf("input x: "); scanf("%lf",x); } double f(double x) { return (x * x - 2); } double df(double x) { /* return (2 * x); */ return ( (f(x + DX) - f(x)) / DX ); } double g(double x) { return (x * x - 2);  } int dgtof(int m) { int ans = 1; while (m >= 10) { ans++; m = m / 10; } return ans; } int newton(double *x) { double newx, oldx = *x; int dgt = dgtof(K_MAX); int k; for (k = 1; k <= K_MAX; k++) { newx = g(oldx); printf("<%*d> g(%.16f) = %.16f\n",dgt,k,oldx,newx); if (fabs(newx - oldx) < EPS) break; oldx = newx; } *x = newx; return ((k < K_MAX) ? k : -1); }

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

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

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

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

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

mather

2018/10/04 05:26

「思い通りの結果になりません」期待値とどういう結果になったか書いてください。
fana

2018/10/04 06:03

結果がどうの以前に,まずNewton法の実装自体が存在しないように見えるのですが…
guest

回答2

0

ベストアンサー

ニュートン法の更新式がおかしいです。

newx = g(oldx);

newx = oldx - f(oldx) / df(oldx);

サンプルコードを以下に記載します。

サンプルコード

python

1#include <math.h> 2#include <stdio.h> 3 4#define K_MAX 100 5#define DX 1.0e-10 6#define EPS 1.0e-10 7 8void input(double *init_x); 9double f(double x); 10double df(double x); 11bool newton(double init_x, double *x, int *num_iters); 12 13int main() 14{ 15 double init_x; // 初期値 16 double x; //17 int num_iters; // 反復回数 18 19 printf("input x: "); 20 scanf("%lf", &init_x); 21 22 if (newton(init_x, &x, &num_iters)) 23 printf("number of iteration: %d, x=%.15f\n", num_iters, x); 24 else 25 printf("newton method failed."); 26} 27 28/** 29 @brief x^2 の値を計算する。 30 */ 31double f(double x) 32{ 33 return (x * x - 2); 34} 35 36/** 37 @brief x^2 の導関数の値を計算する。 38 */ 39double df(double x) 40{ 41 return (f(x + DX) - f(x)) / DX; 42} 43 44/** 45 @brief newton ニュートン法を実行する。 46 @param init_x 初期値 47 @param x 解 48 @param num_iters 反復回数 49 */ 50bool newton(double init_x, double *x, int *num_iters) 51{ 52 double x1 = init_x, x2; 53 int i; 54 55 for (i = 1; i <= K_MAX; i++) { 56 if (fabs(df(x1)) < EPS) 57 return false; // ニュートン法が失敗する場合 58 59 x2 = x1 - f(x1) / df(x1); 60 printf("%d: x=%.15f\n", i, x2); 61 62 if (fabs(x2 - x1) < EPS) { 63 *x = x2; 64 *num_iters = i; 65 return true; 66 } 67 68 x1 = x2; 69 } 70 71 return false; // 収束しなかった場合 72}
input x: 3 1: x=1.833333429863758 2: x=1.462121242835444 3: x=1.414998368736482 4: x=1.414213779259034 5: x=1.414213562373021 6: x=1.414213562373095 number of iteration: 6, x=1.414213562373095

投稿2018/10/04 06:27

編集2018/10/05 05:30
tiitoi

総合スコア21956

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

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

fana

2018/10/04 09:11

重箱の隅的な話ですが,df(x1)の値にチェックかけた方が良いです
tiitoi

2018/10/04 09:35

コメントありがとうございます。チェックを入れてみました。
fana

2018/10/04 11:09

dx(x1)の値次第でx2が遥か彼方の値に吹っ飛ぶかもしれないことを危惧するなら,もうちょっと厳し目な「dx(x1)の絶対値がとても小さいなら諦める」みたいな形でチェックするのかもしれませんね.(妥当な閾値の決め方が謎ですが…用途次第?)
tiitoi

2018/10/04 16:37

たしかにご指摘のとおり、0近辺で値が発散するかもしれないので、<EPS としました。
fana

2018/10/05 01:34

fabs( dx(x1) ) としないとまずいです
fana

2018/10/05 01:36

× dx() ○ df() ですね… 私のコメントもおかしい.
EUROPEAN

2018/10/05 02:29

ありがとうございました!無事に求めていた結果がでました^^
guest

0

更新式ですが、x_(n+1) = x_n - (f(x_n))/(f'(x_n)) を手計算で求め、算出する関数を実装すればよいです。このf(x)ですが、質問者さんが記載されているものとおなじです。

詳しくは、次のサイトを参考にしてください。

  1. ニュートン法とは何か??ニュートン法で解く方程式の近似解
  2. 【微分法】接線の方程式の求め方

投稿2018/10/04 05:38

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問