• 締切済み

台形公式について

台形公式を使って、2*sqrt(1-x*x)の-1から1の積分の近似値を求めようと思うのですが、結果が違う気がします。おかしなところがありますか?また、皆さんの結果ではどういった結果が出てきますか? 台形公式のプログラムリスト double daikei(double N){ int k; double y,S,sum; sum = 0.0; for(k=0; k<=N; k++){ y = 4.0 * sqrt((k/N)*(1.0+(k/N))); if(k==0 , k==N){ S = (1.0/N) * y; } else { S = (2.0/N) * y; } sum = sum + S; } return sum; }

みんなの回答

  • venzou
  • ベストアンサー率71% (311/435)
回答No.3

>計算のしすぎですか。たしかにそれでミスが出るのは >意味がないですね。 ミスが出る事より、汎用性が無いのが気になりました。 例えば、積分区間を変更した時や、f(x)を変更した時に、プログラムの修正がどれだけ必要になるか?って事です。 #2の様にしておけば、積分区間は引数で与えていますし、f(x)も関数で定義していますので、変更が楽です。

keikei07
質問者

お礼

なるほど。この問題上でしか考えていませんでした。 ありがとうございました。

  • venzou
  • ベストアンサー率71% (311/435)
回答No.2

2箇所間違っているかな。 >y = 4.0 * sqrt((k/N)*(1.0+(k/N))); y = 4.0 * sqrt((k/N)*(1.0-(k/N))); 計算みすかな? >if(k==0 , k==N){ if(k==0 || k==N){ 論理和(or)は , ではなく || です。 プログラムを見た感想を述べると、数式を展開しすぎだと思う。 素直にこんな感じで書いた方が良いのでは? #include <stdio.h> #include <math.h> double y(double x){  return 2*sqrt(1-x*x); } double daikei(double a, double b, int n){  int i;  double sum;  double h;  sum = 0.0;  h = (b - a) / n;  for(i = 0; i < n; i++){   sum += ( y(a+i*h) + y(a+(i+1)*h) ) * h / 2;  }  return sum; } void main(void){  printf("%lf \n", daikei(-1.0, 1.0, 10));  printf("%lf \n", daikei(-1.0, 1.0, 100));  printf("%lf \n", daikei(-1.0, 1.0, 1000));  printf("%lf \n", daikei(-1.0, 1.0, 10000)); }

keikei07
質問者

お礼

ありがとうございました。 論理和のことについては完全に忘れていました。 計算のしすぎですか。たしかにそれでミスが出るのは 意味がないですね。参考になりました。

noname#26650
noname#26650
回答No.1

いくつかお聞きします。 ・daikei関数の引数Nの意味合いは何でしょうか? ・y = 4.0 * sqrt((k/N)*(1.0+(k/N))); の式の意味合いは何でしょうか? ・if(k==0 , k==N) のカッコ内のカンマの意味合いは何でしょうか?

keikei07
質問者

補足

・分割数です。 ・積分区間、分割数を公式に基づいてf(x)に  代入した結果です。(間違っているようです) ・論理和にしたかったのですが、間違っていたようです。

関連するQ&A

  • 台形則による結果の数値の相違

    こんにちは<_ _> 台形則による定積分の問題についての質問です 台形則という言葉を今日始めて目にし、なんとかプログラム を作ってみましたが 「a~b間の分割数=n=50で求める  実行結果:  積分区間 A,B?:0 2 /2.000000 | sqrt(4-x*x)=3.138269 /0.000000 」 としなければなりませんが以下のプログラムでは sqrt(4-x*x)=3.956836と出てしまいます・・・ 色々いじってみましたが期待通りの結果が出ません・・・ どこを変えれば良いのでしょうか? 教えてください。お願いします<_ _> #include<stdio.h> #include<math.h> #define f(x) (sqrt(4-(x)*(x))) /*被積分関数*/ int main(void) { int k; double a,b,n,h,x,s,sum; printf("積分区間 A,B?:"); scanf("%lf %lf",&a,&b); n=50; x=a; s=f(x); h=(b-a)/n; for(k=1;k<n;k++){ x=a+f(x)*h; sum=sum+2*f(x); } x=a+f(x)*h; sum=sum+f(x); sum=h*sum/2.0; printf(" /%f\n",b); printf(" | sqrt(4-x*x)=%f\n",sum); printf(" /%f\n",a); }

  • 台形公式によるf(x)の近似値

    区間[a,b]における連続関数f(x)の低積分S=∫[a→b]f(x)dxの値を求めたい。 [a,b]を幅(b-a)/nの小区間にn当分し、その分点をa=a0<a1<a2<・・・<an-1<an=bとする。 各小区間上に作られる台形の面積の和   Sn=nΣk=1 {f(a(k-1)+f(ak)}/2・(b-a)/n をSの近似値とする。この近似法を台形公式という。 区間[0,π/2]を3等分して、台形公式による∫[0→π/2]sinxdxの近似値S3を求めなさい。 nΣk=1 {f(a(k-1)+f(ak)}/2の部分の計算の仕方がわかりません。 Sn=nΣk=1 {sin(k-1)+sin(k)}/2・(b-a)/n このような形で計算してよいのでしょうか?? 初歩的な質問ですがよろしくお願いします。 

  • 台形公式について

    定積分I=∫(0→2) x(x-1)^2dxを数値積分の台形公式で解いてみましたが とき方がいまいちあってる気がしないので、審議お願いします。 条件は分割数は4で等区間の間隔0.5です 答え h=0.5 yo=0(0-1)^2=1, y1=1/2*(1/2)^2=1/8, y2=1*(1-1)^2=0, y3=3/2*(1/2)^2=3/8, y4=2*1^2=2 I=1/4(1+2*1/8+2*0+2*3/8+2)=1 です。 よろしくお願いします

  • 台形公式

    こんにちは。 学校の先生に台形公式を使って次の式を解けといわれました。 x'[n]=cos(θ[n]) 例えば今n=5とします。θ[1]~θ[5]とx[0]は既知です。 僕的には、θが既知であるため台形公式を使わなくても長方形の計算で解けてしまう気がするのですが、間違いでしょうか? また、この場合どのように台形公式を適用すれば良いのでしょうか? どうぞよろしくお願いします。

  • 台形公式とシンプソン公式

    次の積分を台形公式、シンプソン公式を用いて計算せよ。 ただし、刻みをh=2^-nとし、nと積分値の関係も求めよ。 ∫2~1 1/xdx 刻みの書き方がよくわかりません。それ以外は何とかできそうです。 どなたか教えていただければ幸いです。 因みに、n=1~6だそうです。

  • 台形公式

    幅hの小区間上[xi+(h/2),xi-(h/2)]のf(x)の積分に対する台形公式を求めよ。すなわち h{af(xi-(h/2)+bf(xi+(h/2)))} の形の数値積分公式でもっとも次数が高くなるようにa,bを定めよ。 という問題の答えがわかりません。 どなたか教えて下さい。

  • 台形公式・シンプソン公式についての質問

    以前質問させていただき実際にプログラミングを作ったのですが、なぜか間違った答えが出てしまいます。 区分求積法・台形公式・シンプソンの公式を用いて、1/1+x*xを求めたいのですが、 1)台形公式の答えが区分求積法の答えより精度がが悪くなってしまう。 2)シンプソン公式が答えに収束しない。 となってしまいます。 以下がそのプログラム↓ #include <stdio.h> #define FROM 0.0 #define TO 1.0 double func(double x) { double out; out = 1.0 / ( 1.0 + x * x ); return (out); } double kubun(double start, double end, int num) { int i; double h, s; h = ( end - start ) / num; s = 0.0; for(i=0; i<num; i++) s += func( start + i * h + h / 2.0 ); return ( s * h ); } double daikei(double start,double end,int num) { int i; double h,s; h = ( end - start ) / num; s = 0.0; for(i=1; i<num-1; i++) s += func( start + i * h ); return ((func(start) / 2.0 + s + func(end) / 2.0) * h ); } double simpson(double start,double end,int num) { int i; double h,s; h = ( end - start ) / num; s = 0.0; for(i=1;i<num;i+=2) s += 4.0 * func(start + h * i); for(i=2;i<num;i+=2) s += 2.0 * func(start + h * i); return ( (func(start) + s + func(end))/ 3 ); } int main() { double func(double); double kubun(double, double, int); double daikei(double, double, int); double simpson(double, double, int); printf("\n"); printf("### Square Integration\n"); printf(" ++ Partition = 10\t Answer = %10.6f\n", kubun(FROM, TO, 10)); printf(" ++ Partition = 50\t Answer = %10.6f\n", kubun(FROM, TO, 50)); printf("\n"); printf("### daikei Integration\n"); printf(" ++ Partition = 10\t Answer = %10.6f\n", daikei(FROM, TO, 10)); printf(" ++ Partition = 50\t Answer = %10.6f\n", daikei(FROM, TO, 50)); printf("\n"); printf("### simpson Integration\n"); printf(" ++ Partition = 10\t Answer = %10.6f\n", simpson(FROM, TO, 10)); printf(" ++ Partition = 50\t Answer = %10.6f\n", simpson(FROM, TO, 50)); return (0); } 画面に表示する際に、それぞれ分割数を10と50にした際の値を表示するように作りました。 細かい点までご指摘いただけると幸いです。 よろしくお願いします。

  • 台形公式を使って解析解を、。

     2 ∫ X^5dx の定積分の解析解を求めるのに台形公式法を使って  0    求めよ。 なんですが、 全然回りの答えと合いません・・ 10.~ に出来るだけ近い数値が解です。 どの様にして求めればいいのでしょうか。 プログラムではなく手計算での求め方お願いします。

  • 1/sqrt(x^2+y^2) の x^j y^k

    二次元波動関数の運動を近似計算するために 1/r ≡ 1/sqrt(x^2+y^2) を x^j y^k 整数 べき乗の和として近似しようとしています。より具体的には、下のような近似を成り立 たせる係数 c[j,k] を旨く決めたいと思っています。ただし j,k ∈[-N,N] の整数で す。 N は 2 か 3 か 4 です。             N   N 1/sqrt(x^2+y^2) ≒ Σ  Σ   c[j,k] x^j y^k             j=-N k=-N 皆様でしたら、この c[j,k] をどのように定めますでしょうか。

  • P値(統計学)を求めるプログラム

    統計学でP値を求めるプログラムで、通常ならば、台形公式やシンプソン公式などを用いて、微小ずつ積分していくと考え作ってみたのですが、先生から毎回積分するのではなく近似値を出しておいて利用するようにと言われ、積分をしないプログラムを組めと言われています。 おそらく、積分はしたという前提で計算するという事でしょうか? フリーの統計ソフトR のコードを参考にと見ていたんですが理解し難く、どなたかにご教授願いたいと考えました。 よろしくお願い致します。 今回は、カイ二乗の値からP値を求めようと考えています。 その際の、カイ二乗分布に従う式は f(x) = x^(n-2/2) * e^(-x/2) / 2^(n/2)gamma(n/2) は分かりました。 ガンマ関数に関しては、 double gamma(double x, int *ier) /* ガンマ関数の計算 */ { double err, g, s, t, v, w, y; long k; *ier = 0; if (x > 5.0) { v = 1.0 / x; s = ((((((-0.000592166437354 * v + 0.0000697281375837) * v + 0.00078403922172) * v - 0.000229472093621) * v - 0.00268132716049) * v + 0.00347222222222) * v + 0.0833333333333) * v + 1.0; g = 2.506628274631001 * exp(-x) * pow(x,x-0.5) * s; } else { err = 1.0e-20; w = x; t = 1.0; if (x < 1.5) { if (x < err) { k = (long)x; y = (double)k - x; if (fabs(y) < err || fabs(1.0-y) < err) *ier = -1; } if (*ier == 0) { while (w < 1.5) { t /= w; w += 1.0; } } } else { if (w > 2.5) { while (w > 2.5) { w -= 1.0; t *= w; } } } w -= 2.0; g = (((((((0.0021385778 * w - 0.0034961289) * w + 0.0122995771) * w - 0.00012513767) * w + 0.0740648982) * w + 0.0815652323) * w + 0.411849671) * w + 0.422784604) * w + 0.999999926; g *= t; } return g; }

専門家に質問してみよう