-4

ニュートン法を実行し、方程式 exp(-x)-(x^2)+3 の根を見つけるプログラムを作成しようとしています。ルートを見つける限り機能しますが、反復ごとにルートを出力したいのですが、動作させることができません。誰かが私の間違いを指摘してもらえますか?

どうもありがとう :)

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

//Define Functions:
double evalf(double x)
{
        double answer=exp(-x)-(x*x)+3;
        return(answer);
}
double evalfprime(double x)
{
        double answer=-exp(-x)-2*x;
        return(answer);
}
double *newton(double initialrt,double accuracy,double *data)
{
        double root[102];
        data=root;
        int maxit = 0;
        root[0] = initialrt;
        for (int i=1;i<102;i++)
        {
                *(data+i)=*(data+i-1)-evalf(*(data+i-1))/evalfprime(*(data+i-1));
                if(fabs(*(data+i)-*(data+i-1))<accuracy)
                {
                        maxit=i;
                        break;
                }
                maxit=i;
        }

        if((maxit+1==102)&&(fabs(*(data+maxit)-*(data+maxit-1))>accuracy))
        {
                printf("\nMax iteration reached, method terminated");
        }      
        else
        {
                printf("\nMethod successful");
                printf("\nNumber of iterations: %d\nRoot Estimate: %lf\n",maxit+1,*(data+maxit));
        }

        return(data);
}




int main()
{
    double root,accuracy;
    double *data=(double*)malloc(sizeof(double)*102);

    printf("NEWTONS METHOD PROGRAMME:\nEquation: f(x)=exp(-x)-x^2+3=0\nMax No iterations=100\n\nEnter initial root estimate\n>> ");
    scanf("%lf",&root);
    _flushall();
    printf("\nEnter accuracy required:\n>>");
    scanf("%lf",&accuracy);
    *data= *newton(root,accuracy,data);
    printf("Iteration        Root           Error\n ");
    printf("%d          %lf             \n", 0,*(data));
    for(int i=1;i<102;i++)
    {
        printf("%d             %5.5lf           %5.5lf\n", i,*(data+i),*(data+i)-*(data+i-1));
        if(*(data+i*sizeof(double))-*(data+i*sizeof(double)-1)==0)
        {
            break;
        }
    }
    getchar();
    getchar();
    free(data);
    return(0);
}
4

3 に答える 3

1

違反はありませんが、あなたの質問は反対票を投じるのに非常に魅力的です. 無関係な質問のタイトル、ばかげたコーディング スタイル (集計を意味します)。

また、newton関数内ではすべての中間結果を実際に格納する必要はありません。Newton-Raphson は余分なメモリを使用しないでください (つまり、O(1))。

反復ループの内側に追加するだけprintfです。newtonこれは問題ですか?

于 2012-04-04T10:39:33.170 に答える
1

ではnewton、関数が戻った後に存在しなくなったローカル変数のアドレスを返しています。後でアクセスすると、未定義の動作になります。

あなたmainが持っている

if(*(data+i*sizeof(double))-*(data+i*sizeof(double)-1)==0)

dataは adouble*であるため、最初からdata + ii 番目をアドレス指定しますdouble。オフセットに を掛けるとsizeof(double)、配列 if の末尾を超えてアクセスし、i > number_of_elements/sizeof(double)さらに未定義の動作になります。

そして、それを見つけてくれた JeremyP に感謝しmainます。newton

*data= *newton(root,accuracy,data);

newton(未定義の動作ですが、その時点であなたが望むことをする可能性が高いです)によって返されたポインタを逆参照し、data割り当てられた inの最初のスロットにその値を格納しますmain。そのため、おそらくroot配列 fromの最初の要素が得られますが、 innewtonに割り当てられたメモリ ブロック内の他の要素は変更されません。datamain

于 2012-04-04T10:40:08.803 に答える
0
void newton(double initialrt,double accuracy,double *data)
{
    double root[102];
    data=root;
    // at this moment the values in the original argument data[]
    // are no longer accessible to this function.
    int maxit = 0;
    root[0] = initialrt;
    for (int i=1; i < 102; i++)
        {
                data[i] = data[i-1] 
                 - evalf(data[i-1]) / evalfprime( data[i-1] );
                if ( fabs(data[i] - data[i-1]) < accuracy )
                {
                        maxit=i;
                        break;
                }
                maxit=i;
        }

        if ( maxit+1 == 102 && fabs(data[maxit] - data[maxit-1] ) > accuracy )
        {
                printf("\nMax iteration reached, method terminated");
        }      
        else
        {
                printf("\nMethod successful");
                printf("\nNumber of iterations: %d\nRoot Estimate: %lf\n",maxit+1
                ,data[maxit);
        }
    return;
}

(実際の問​​題はすでに対処されているため、これは単なる文体のコメントです)

  • ポインタの間接参照と配列のインデックス付けは、Cでは同等です*(data+i) = ...data[i] = ...
  • 戻り値は役に立たず、関数は代わりに何か有用なものを返す可能性があります(例:精度)
  • returnは関数ではありません。する必要はありませreturn(something);return something;
  • ローカル配列ルートへのポインタを返します。これは、呼び出し元に表示されたときにスコープ外です。
  • 空白は読書体験に違いをもたらします

更新:考え直してみると、内側のループでは、OPは次のよ​​うなものを意図していると思います。

root[i] = root[i-1] 
        - evalf(data[i-1]) / evalfprime( data[i-1] );
if ( fabs(data[i] - data[i-1]) < accuracy )
     {
     maxit=i;
     break;
     }
maxit=i;
于 2012-04-04T11:20:30.860 に答える