1

C コードを Java に変換しようとしています。これは Newton Raphson アルゴリズムの実装です。すべて順調に進んでいますが、C コードで使用されていたポインタに問題があり、Java でそれらを削除しました。C コード部分は次のとおりです。

 x = newton(x_0, error, max_iters, &iters, &converged); //Call to a function (newton)

   if (converged) {

printf("Newton algorithm converged after %d steps.\n", iters);

    printf("The approximate solution is %19.16e\n", x);
    printf("f(%19.16e) = %19.16e\n", x, f(x));
   } else 
{

printf("Newton algorithm didn't converge after %d steps.\n", 
          iters);

    printf("The final estimate was %19.16e\n", x);
    printf("f(%19.16e) = %19.16e\n", x, f(x));
  }

関数定義は次のようになります。

double newton(double x_0, double error, int max_iters, 
          int* iters_p, int* converged_p)

ここでの問題は、2 つのポインター変数の値が毎回ゼロになることです。また、if(converged) は、互換性のないタイプのエラー メッセージを表示します。ブール値が必要です。int が見つかりました。以下はJavaコードですので、これを克服するのを手伝ってください。

 //Member Functions///////
 public
            double function( double x) 
            { 
                return x*x - 2;
            }

            double F_Deriv( double x ) 
            {
                return 2.0*x; 
            }


            double newton(double x_0, double error, int max_iters,int iters, int converged) 
            {
   double x = x_0;
   double x_prev;
   int    iter = 0;

   do {
      iter++;
      x_prev = x;
      x = x_prev - function(x_prev)/F_Deriv(x_prev);
   } 
   while (Math.abs(x - x_prev) > error && iter < max_iters);

   if (Math.abs(x - x_prev) <= error)
      converged = 1;
   else
      converged = 0;
   iters = iter;

   return x;
} 


/////Main Function///////
    public static void main(String[] args) {

        Newton_Raphson obj=new Newton_Raphson();

        Scanner input=new Scanner(System.in);


        double x_0;       /* Initial guess                */
        double x;         /* Approximate solution         */
        double error;       /* Maximum error                */
        int    max_iters; /* Maximum number of iterations */
        int    iters;     /* Actual number of iterations  */
        int    converged; /* Whether iteration converged  */

        System.out.println( "Enter Initial Solution: " );
        x_0=input.nextDouble();

        System.out.println( "Enter Error: " );
        error=input.nextDouble();


        System.out.println( "Enter Maximum Iterations: " );
        max_iters=input.nextInt();

        x = obj.newton(x_0, error, max_iters, iters, converged);

        if(converged) 
        {
            System.out.println("Newton algorithm converged after "+ iters +" steps.");
            System.out.println("The approximate solution is "+ x);

        } 

        else 
        {
            System.out.println("Newton algorithm didn't converge after " + iters + " steps.");
            System.out.println("The final estimate was " + x);

        }

    }
4

5 に答える 5

3

Java は引数を値で渡すので、

if (Math.abs(x - x_prev) <= error)
    converged = 1;
else
    converged = 0;
iters = iter;

呼び出し元に渡された引数を変更しません。これらの変更は、呼び出された関数から離れることはありません。

出力パラメータを模倣する最も簡単な方法は、それぞれです。C で渡されたポインターは、1 つの長さの配列を渡すことです。

double newton(double x_0, double error, int[] max_iters,int iters, boolean[] converged)

および設定(およびクエリ)iters[0]resp。converged[0].

于 2012-05-02T11:19:50.133 に答える
1

1 つの問題は、次のステートメントです。

if (Math.abs(x - x_prev) <= error)
   converged = 1;
else
   converged = 0;

Javaは値渡しなので何もしていません。convergedしたがって、メソッドの外側の値には影響しません。代わりに、x と converged の 2 つのメンバーを含むメソッドからオブジェクトを返すことができます。

return new NewtonResult (x, iters, converged);

NewtonResult は次のように定義されます。

public class NewtonResult {
    int x;
    int iters;
    boolean converged;
    NewtonResult (int x, int iters, boolean converged) {
        this.x = x;
        this.iters = iters;
        this.converged = converged;
    }
}

コードのもう1つの問題はif、intを渡すときにJavaがブール値を必要とするため、条件を次のように変更する必要があることです。

if (converged != 0) {
    //
}

またはさらに良い収束をブール値にします。

于 2012-05-02T11:18:42.433 に答える
1

問題は、convergeditersが元の C コードから返されることです。これらのパラメーターにポインターを使用するのは、パラメーターがoutセマンティクスを模倣できるようにするためです。Java は値渡しのみをサポートするため、単純なメソッド パラメータを使用して同じ方法でその情報を返すことはできません。

もう 1 つの問題は、古いバージョンの C にはブール型がないため、int代わりに使用されることです。収束を示すフラグbooleanは Java である必要があります。

convergedしたがって、コードは、結果 (浮動小数点値)、 (ブール値)、およびiters(整数)の 3 つの情報を返す必要があります。これらをオブジェクトにラップして、そのように返す必要があります。

必要なクラスは次のようになります。

public class NewtonResult {
     public boolean converged;
     public double value;
     public int iters;
}

newtonメソッドのシグネチャを次のように変更する必要があります。

NewtonResult newton(double x_0, double error, int max_iters) 

最後に、そのパラメーターtoleranceよりもはるかに適切な名前だと思います。error

于 2012-05-02T11:22:52.007 に答える
0

int, -などのプリミティブ型booleanをJavaでメソッドのパラメータとして渡して変更すると、実際には変更されません。
渡されるパラメーターは、実際のパラメーターのコピーです (実際には値によって渡されます)。
変数からオブジェクトを初期化し、次のようにメソッドに渡します。

Integer[] a = new Integer[1];  // For int a
Boolean[] b = new Boolean[1];  // For boolean b
a[0] = 1;
b[0] = true;

このようにして、渡されたオブジェクトの参照のコピーが渡され、[0]上記のようにその要素のいずれかの値を変更すると、実際の変数でも変更されます。

于 2012-05-02T11:30:49.137 に答える
0

クラス宣言がありません (public class Newton_Raphson...)。

上記のように、Java は参照渡しの引数をサポートせず、値渡しのみをサポートするため、それらすべてを「Result」クラスでラップする必要があります。

public class Result {
     public int x;
     public int iters;
     public int converged; // better replace this with a boolean in Java
}

メソッドの戻り値の型をその Result クラスに変更します。

int をブール値としてテストすることはできません。0 とは異なることをテストする必要があります (C では 0 以外はすべて true と見なされるため)。または、ブール値を直接使用することを検討してください。はるかに簡単です。

于 2012-05-02T11:22:16.297 に答える