• 締切済み

数値解析の矩形法について

区間分割数nを10から100まで10ずつ増やして計算値を求め、面積の計算誤差が区間分割数によってどのように変化するかを求める矩形法プログラムを下記に作成したのですが、 計算誤差を求める式で ・計算誤差=(計算値ー真値)/真値×100 (%) (真値は0.68269) と計算するのですが、プログラムでは分母の真値×100 (%)を()を付ける場合の計算の答えと()を付けない計算の答えとが全然違います。どうしてこのようなことが起こるのですか? また、この計算誤差の求め方は()を付ける場合とつけない場合のどちらが正しいのですか? public class Kukei { static double f(double x) { // ここに任意の被積分関数を記述 double y = Math.exp(- x * x / 2) / Math.sqrt(2.0 * Math.PI); return y; } public static void main(String[] args) { double a = - 1.0, b = 1.0; // 積分範囲 int n = 10; // 区間分割数 double suti= ((n+10)-0.68269)/0.68269*100; //真値 for(int k=1; k <= 10; k++){ double h = (b - a) / (double)n; // 分割幅 double s = 0.0; n=k*10; for (int i=0; i < n; i++) { s += f(a + i * h); } s *= h; suti= (s-0.68269)/0.68269*100; System.out.println("区間分割数 =" + n); System.out.println("矩形法による計算値 =" + s); System.out.println("矩形法による計算誤差 =" +suti+"\n"); } } }

  • aw345
  • お礼率2% (1/48)
  • Java
  • 回答数1
  • ありがとう数3

みんなの回答

  • askaaska
  • ベストアンサー率35% (1455/4149)
回答No.1

質問の内容とコードとのつながりがいまいちわからないけど (計算値ー真値)/真値×100 と (計算値ー真値)/(真値×100) で結果が違うってこと? そりゃ当たり前よね。 (計算値ー真値)/真値×100 =(計算値ー真値)×100/真値 になるのだから。 (計算値ー真値)/(真値×100) と比べたらとんでもない違いになるわよ。

関連するQ&A

  • 矩形法プログラムの計算値と計算誤差の求め方

    下記の矩形法の計算値を求めるプログラムで、区間分割数nを10から100まで10ずつ増やして計算値を求めるプログラムを作成したいのですが、どのようにしたらいいのか分かりません。Java初心者なのでJavaプログラムが詳しい人は至急ご連絡をお願いします。 *ちなみにこの矩形法プログラムのの計算誤差も分かる人はお願いしたいのですが・・・・・・  計算誤差の求め方は    計算誤差=(計算値ー真値)/真値×100(%) (真値=0.68269とする) public class Kukei { static double f(double x) { // ここに任意の被積分関数を記述 double y = Math.exp(- x * x / 2) / Math.sqrt(2.0 * Math.PI); return y; } public static void main(String[] args) { double a = - 1.0, b = 1.0; // 積分範囲 int n = 100; // 区間分割数 double h = (b - a) / (double)n; // 分割幅 double s = 0.0; for (int i=0; i < n; i++) { s += f(a + i * h); } s *= h; System.out.println("区間分割数 =" + n); System.out.println("矩形法による計算値 =" + s); } }

    • ベストアンサー
    • Java
  • 数値積分について

    私が作成した下記のJavaの数値解析の矩形法のプログラムで、区間分割数nを10から100まで10ずつ増やして計算値を求め、面積の計算誤差を(計算値-真値(0.68269))/真値(0.68269)*100 (%)として計算するプログラムがまったくわかりません。Javaで数値解析をするのは初めてなのでどこが足りないのか、どこを直したら動くのか教えてください public class Kukei { static double f(double x) { // ここに任意の被積分関数を記述 double y = Math.exp(- x * x / 2) / Math.sqrt(2.0 * Math.PI); return y; } public static void main(String[] args) { double a = - 1.0, b = 1.0; // 積分範囲 int n = 10; // 区間分割数 double suti= (n-0.68269)/(0.68269*100); for(int j=0; j<n; j++){ double h = (b - a) / (double)n; // 分割幅 double s = 0.0; n=n; for (int i=0; i < n; i++) { s += f(a + i * h); } s *= h; System.out.println("区間分割数 =" + n); System.out.println("矩形法による計算値 =" + s); System.out.println("矩形法による計算誤差 =" +suti+"\n"); } } }

  • シンプソン法の出力結果について

    シンプソン法の区間分割数nを10~100まで10ずつ増やして計算値と計算誤差を求めるプログラムを書きに作成したのですが、出力結果に-7.341865999405491E-5などとあります。この「E-数字」とはJavaではどういうこと示しているのですか? また、計算誤差の求め方は下記のプログラムでいいのですか? public class Simpson { static double f(double x) { // ここに任意の被積分関数を記述 double y = Math.exp(- x * x / 2) / Math.sqrt(2.0 * Math.PI); return y; } public static void main(String[] args) { double a = - 1.0, b = 1.0; // 積分範囲 int n = 100; // 区間分割数 for(n=10; n <=100; n+=10){ double h = (b - a) / (double)n; // 分割幅 double s, s1 = 0.0, s2 = 0.0; for (int i = 1; i <= n / 2; i++) { s1 += f(a + (2 * i - 1) * h); } for (int i = 1; i <= n / 2 - 1; i++) { s2 += f(a + 2 * i * h); } s = h / 3.0 * (f(a) + 4.0 * s1 + 2.0 * s2 + f(b)); double suti = (s-0.68269)/0.68269*100;  //計算誤差=(計算値ー真値)/真                                         値×100 System.out.println("区間分割数 =" + n); System.out.println("シンプソン法による計算値 =" + s); System.out.println("シンプソン法による計算誤差 ="+suti+"\n"); } } }

  • 数値解析法

    このHeun法のプログラムをRunge-Kutta法にするにはどうしたらいいですか? #include <stdio.h> #include <math.h> double f1(double y) { return y; } double f2(double y) { return -4*y; } int main(){ double a=0; double b; int m=10; int n; double h; double x,y; int k; double e; double f; double k1,k2; printf("Heun法計算例: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); } // Heun's method k1 = h*f1(y); k2 = h*f1(y+k1); y += (k1+k2)/2; } }

  • javaのプログラムについて

    質問させていただきます // 数値積分 class Integral1 { public static void main(String[] args) { final int n = 100; // 区間数 final double a = 0; // 始点 final double b = 1; // 終点 final double h = (b-a) / n; // 区間の幅 double x, y; double S = 0; // Sを0で初期化 int i; // 区間 for(i = 1; i <= n ; i++) { // 区間1からnまで x = a + h * i; // 区分積分 y = Math.sqrt(1-x*x); // yを計算 S += y * h; } System.out.println("S = " + S + " 4S = " + 4*S); } } これは区分積分法で計算する数値積分のプログラムなのですが、 これをシンプソン法に改造したプログラムに直していただきたいのですが・・・ どなたかお願いします

  • 数値計算法を勉強しているんのですが…

    Shimpson公式を用いて計算したときに何故mが大きいところで誤差が大きくなりました。プログラムは下に示しました。なぜこのような結果になったか分かりません。 #include <stdio.h> #include <math.h> #define PI 3.141592653589793 double sum(long m) { double n,sum,h,x; h=(PI/2)/m; sum=0; n=0;x=0; while( n<m ){ sum+=2*sin(x);/*項の加算*/ sum+=4*sin(x+h/2); n++; x+=h; } sum+=-sin(0)+sin(PI/2); sum*=h/6; return sum; } int main(void) { double s; long m; int i; m=1; for(i=0;i<8;i++){ s=sum(m); printf("%2d m=%10ld sum= %22.16e err= %22.16e \n",i,m,s,s-1.0); m*=10;/*次のmは10倍*/ } return 0; }

  • LU分解を利用した逆行列のプログラム(Java)

    LU分解を利用した逆行列のプログラムが作れません… というか、作ったのですが実行するとエラーが出てしまいます(´Д`;) どこをどう直せばいいか、もしくはこのようにプログラムした方が効率がよい などのアドバイスどなたか下さい double a[][]={{2,5,4}, {2,3,-1}, {6,9,28}}; int N=a.length; double[][] s=new double[N][N]; for(int k=0; k<a[0].length-1; k++){ for(int i=k+1; i<N; i++){ s[i][k]=a[i][k]/a[k][k]; a[i][k]=s[i][k]; for(int j=k+1; j<N; j++){ a[i][j] -= s[i][k] * a[k][j]; } } } double[][] y=new double[N][N]; double[][] X=new double[N][N]; double[][] e=new double[N][N]; for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ if(i==j){ e[i][j]=1; }else{ e[i][j]=0; } } } for(int i=0;i<N;i++){ y[1][i]=e[1][i]; for(int k=2;k<=N;k++){ for(int j=1;j<=N;j++){ y[k][i]=e[k][i]-s[k][j]*y[j][i]; } } X[N][i]=y[N][i]/a[N][N]; for(int k=N-1;k>=1;k--){ for(int j=k+1;j<=N;j++){ X[k][j]=(y[k][j]-s[k][j]*X[j][i])/a[k][k]; } } } for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ System.out.printf(" %6.5f ", X[i][j] ); } System.out.println(""); }

  • 配列の乱数と平均値、個数表示

    0から9までの整数乱数を100個発生させ、100個の乱数の平均値も合わせて出力し、0から9それぞれの個数を数えるための変数に必ず配列を用いるプログラムを下記に作成したんですけども、出現個数カウント用の変数を10個用意していけないという条件で出現個数カウント用の配列を用意し、 結果が、 7 7 1 7 3 9 1 2 5 0 0 3 6 8 4 9 1 4 2 4 8 2 4 2 6 0 9 3 5 8 6 6 6 2 0 9 5 2 6 9 5 0 5 3 9 2 6 7 0 6 1 4 1 1 1 9 7 0 5 0 6 9 7 4 9 9 7 5 3 6 1 9 6 6 6 7 1 2 6 1 4 9 1 3 1 3 7 0 0 8 1 9 3 2 9 4 4 5 4 0 0 *********** 11 1 ************* 13 2 ********* 9 3 ******** 8 4 ********** 10 5 ******** 8 6 ************** 14 7 ********* 9 8 **** 4 9 ************** 14 平均 4.4 に表示されるプログラムがわかりません、Java初心者なので作ったプログラムのどこを直せばいいのか教えてください。 class Kadai06_5 { public static void main(String args[]) { int n=10; int a[] = new int[n]; int i; int sum=0; double avg=0; for(i=0; i<100; i++){ System.out.print((int)(Math.random()*10)); sum +=(int)(Math.random()*10); } for(i=0; i<n; i++){ System.out.println(); } avg=(double)sum/100; System.out.println("平均"+avg); } }

    • ベストアンサー
    • Java
  • 連立方程式を解くプログラムの後退代入の所

    連立方程式を解くプログラムで前進消去の部分はできたのですが、後退代入の所がうまくいきません。教えて!gooを通して皆さまの力をお借りできればと思います。よろしくお願いいたします。 import java.io.*; import java.util.*; import java.math.*; //連立方程式を解くプログラム class krm3{ public static void main(String args[]){ System.out.println("連立方程式を求めます。"); //declaring and allocating2> double[][] A = null; try{ BufferedReader br = new BufferedReader (new FileReader("renritu.txt")); String s; String[] vals; int rows = 0,cols = 0; while((s = br.readLine()) !=null){ vals = s.split(" ");//split the line with space cols = Math.max(cols,vals.length); rows++; } System.out.println(rows+"×"+cols+" array found"); A = new double[rows][cols]; br.close(); br = new BufferedReader(new FileReader("renritu.txt")); rows = cols = 0; while((s = br.readLine()) !=null){ vals =s.split(" ");//split the line with space cols = vals.length; for(int i=0; i<cols;i++) A[rows][i]=Double.parseDouble(vals[i]); rows++; } }catch (IOException e){ System.out.println(e); } for(int i = 0;i<A.length;i++){ for(int j=0;j<A[i].length;j++){ System.out.print(A[i][j]+" "); } System.out.println(); } System.out.println(); //掃き出し法 //前進消去 //行i=0~n-2に対してi+1行目以降のi列目を消去する(ただしnは行の数) // //i行目をピポッド(i,i)で正規化(割る) // 1行目に(j,i)要素をかけてj行目から引く for(int i = 0;i<A.length-1;i++){ double P = A[i][i];//pivot for(int j=0;j<A[i].length;j++) A[i][j]/= P; for(int k=i+1;k<A.length;k++){ double v = A[k][i]; for(int j=0;j<A[i].length;j++){ A[k][j]-= A[i][j]*v; } } } for(int i = 0;i<A.length;i++){ for(int j=0;j<A[i].length;j++){ System.out.print(A[i][j]+" "); } System.out.println(); } System.out.println(); // eqs= // 1 2 3 4 // 0 1 7 8 // 0 0 1 2 //後退代入 //行i=n-1~1に対してi-1行目以前のi列目を消去する for(int i = A.length;2<i;i--){ double P2 = A[i-1][i-1] ;//pivot for(int j=A[i-1].length;j>2;j--) A[i-1][j-1]/= P2; for( int k=i-1;k>2;k--){ double v2 = A[k-1][i-1]; for(int j=A[i].length;j>2;j--){ A[k][j]-= A[i][j]*v2; } } } for(int i = 0;i<A.length;i++){ for(int j=0;j<A[i].length;j++){ System.out.print(A[i][j]+" "); } System.out.println(); } System.out.println(); } }

  • 数値解析に関する質問です。

    /*kadai8 Euler’s Method for Ordinary Differential Equation */ #include <stdio.h> void euler(double *, double *); main () { int i; double v,t,tt,dt[5]; dt[0] = 2; dt[1] = 1; dt[2] = 0.1; dt[3] = 0.01; dt[4] = 0.001; printf("Program of Euler`s Method 1\n"); printf("-----------------------------------------\n"); tt = 50.0/9.80665; printf("Theoretical Solution : %lfs\n",tt); for(i=0;i<=4;i++){ printf("--------------------------------\n"); printf("Step Size : %lf s\n",dt[i]); v=50.0; t=0.0; while(v>0) { euler(&v,&dt[i]); t=t+dt[i]; } printf("Numerical Solution : %lf s\n",t); printf("Error : %lf s\n",t-tt); } return(0); } /*--------------*/ void euler(double *v,double *dt) { *v=*v + (*dt )*(-9.80665); } 以上のプログラムで関数eulerの引数にポインタがついているのはなぜか,またポインタを使用しない方法はないか?また、オイラー法より精度の高い解法はありますか? よろしくお願いします。

専門家に質問してみよう