C言語関係掲示板

過去ログ

No899 3x^3-6x^2-3x+6の解をニュートンラフソン法で求めたい

[戻る] [ホームページ]
No.584

ニュートンラフソン法で3x^3-6x^2-3x+6の解を求めたい
投稿者---まめの(2003/10/27 23:11:46)


3x^3-6x^2-3x+6の解をニュートンラフソン法で求めたいのですが、

どうすれば良いのでしょうか?さらに、|X(n+1)-X(n)|<10^-6という条件があります。よろしくお願いいたします。

No.589

Re:ニュートンラフソン法で3x^3-6x^2-3x+6の解を求めたい
投稿者---ceybord2(2003/10/28 18:16:50)


>3x^3-6x^2-3x+6の解をニュートンラフソン法で求めたいのですが、

>どうすれば良いのでしょうか?さらに、|X(n+1)-X(n)|<10^-6という条件があります。よろしくお願いいたします。

X(n+1)-X(n)の説明がないので、この辺はコメントのしようがないですが、
多項式の微分ぐらいは手計算でしましょう。(数値微分という手もありますが。)

No.612

Re:ニュートンラフソン法で3x^3-6x^2-3x+6の解を求めたい
投稿者---かずま(2003/11/04 20:02:50)


> 3x^3-6x^2-3x+6の解をニュートンラフソン法で求めたいのですが、
3x^3-6x^2-3x+6 は関数であり、解はありません。
3x^3-6x^2-3x+6 = 0 という 3次方程式の解を求めるのですね。
因数分解すると、3(x+1)(x-1)(x-2) = 0 ですから、解は、-1、1、2 です。

さて、Newton-Raphson法を使うときは、微分が必要です。
f(x) = 3x^3-6x^2-3x+6 のとき、
f'(x) = 9x^2-12x-3 ですから、プログラムは次のようになります。
初期値の与え方で求める結果が変わってきます。

#include <stdio.h>
#include <math.h>

double f(double x) { return 3*x*x*x - 6*x*x - 3*x + 6; }
double f1(double x) { return 9*x*x - 12*x - 3; }

void newton(double x0)
{
    double x1;
    printf("x0 = %5.1f  -->  ", x0);
    for (;;) {
        x1 = x0 - f(x0)/f1(x0);
        if (fabs(x1 - x0) < 1e-6) break;
        x0 = x1;
    }
    printf("x1 = %5.1f\n", x1);
}

int main(void)
{
    double x;
    for (x = -1.1; x < 2.2; x += 0.2)
        newton(x);
    return 0;
}


No.613

Re:ニュートンラフソン法で3x^3-6x^2-3x+6の解を求めたい
投稿者---まめの(2003/11/04 20:28:46)


ありがとうございました。助かりました

No.665

Re:Re:ニュートンラフソン法で3x^3-6x^2-3x+6の解を求めたい
投稿者---ceybord(2003/11/15 15:13:33)


時々こういうタイプのプログラムを見かけるのですが、
多項式の結果を得るだけとか、そういうのはサブルーチンにせずに、
main関数に組み込んだ方が、速い計算ができます。
意味も無く関数を増やさないほうがいいです。
今のプログラムの場合は、#define文を活用したほうがいいです。

No.667

Re:Re:ニュートンラフソン法で3x^3-6x^2-3x+6の解を求めたい
投稿者---たいちう(2003/11/15 16:20:52)


原則としては、関数の呼び出しにはその分の時間が余分にかかりますが、
C言語ではそのための時間は驚くほど短いものです。
プロファイラ等で確認してみてください。

また、最近のコンパイラの殆どが最適化されたコードをはき出すことが
可能ですので、人間が小手先のテクニックで実行時間を短くする必要は
ほとんどないと思います。

実行速度のために関数を使うなというのは、時代遅れに感じますが。
このプログラムの実行時間なんてどうせ体感できないんだし。

No.683

Re:Re:Re:ニュートンラフソン法で3x^3-6x^2-3x+6の解を求めたい
投稿者---ceybord(2003/11/17 07:54:50)


確かに速さにこだわると、アセンブラでプログラムを組めという話になってしまいますね。
ついでに多項式の計算は
((3*x-6)*x-3)*x+6の順番のほうがいいのですが、
これもコンパイラが最適化をやってくれるのですか?

No.684

Re:Re:Re:ニュートンラフソン法で3x^3-6x^2-3x+6の解を求めたい
投稿者---たいちう(2003/11/17 09:58:37)


コンパイラによるとは思いますが、その程度のこともできないのでは最適化とは
いえないと思います。個人的には。よって現在市販されているほとんど全ての
コンパイラで可能だと推測しています。

それを直接確認するには、コンパイラの出したコードを読めばいいのですが、
ちょこちょこっと仕事の合間に読む技量を残念ながら持ち合わせていませんので、
今度時間のあるときに。

間接的な確認としては、数億回繰返して時間を計ることとかな。

No.685

Re:Re:Re:ニュートンラフソン法で3x^3-6x^2-3x+6の解を求めたい
投稿者---かずま(2003/11/17 14:21:35)


> ついでに多項式の計算は
> ((3*x-6)*x-3)*x+6の順番のほうがいいのですが、
> これもコンパイラが最適化をやってくれるのですか?

規格に準拠したコンパイラなら、絶対にやりません。
浮動小数点演算は、精度やオーバーフローの問題があるので、結果が異なる
ようになる演算順序の変更は行わないことになっています。
規格書でなくても、K&R2 の付録A 参照マニュアルの「A7. 式」にも書かれて
います。

No.686

Re:Re:Re:ニュートンラフソン法で3x^3-6x^2-3x+6の解を求めたい
投稿者---たいちう(2003/11/17 15:45:52)


なるほど。考えてみるとそりゃそうですね。
私があさはかでした。

でもこのタイプのテクニックは多用しないことをお勧めします。
ソースが読みにくくなる、修正しにくくなる、といったデメリット
に対して、メリットは実行速度が若干速くなるだけ。

例えば1時間も計算するような場合、少しでも速くしたいという気持ちは
分かりますが、闇雲にこのような定石を使う前に、アルゴリズムを見直し、
次にプロファイラでボトルネックを探しましょう。
その後で必要なだけ最適化のテクニックを駆使すればよいでしょう。
アルゴリズムの見直しに比べると、飛躍的な向上は望みにくいでしょうが。