計算数学演習第6回

定積分の近似値

これまでfor文を使うことで、\sum\prodを表現することができることを実感してもらったと思います。
そこで、積分が和の極限だということを使うと,計算機で定積分の近似値を簡単に計算できます。
以下は定積分

    \[f = \int_0^1 (1-x^2)dx\]

の近似値を(区分求積法を使って)求めるプログラムです。
integration-1.cとして打ち込み実行してください。
プログラムの概要は以下の通り。

  1. まず積分区間(0~ a)を、 N 個の、幅 d = a/N の領域に分割。
  2. i 番目の領域の中心(x = (i+0.5)*d)での関数の値(y = f(x)=1 – x*x)を高さとする長方形の面積が y*d と得られるので、それらを全区間に渡って足し合わせる。(紙に絵を描いてみるとすぐ分かります。)

integral-1.c

#include <stdio.h>
 
int main() {
    /* 実数型変数の宣言 */
    double f, x, y, a, d;
    
    /* 整数型変数の宣言 */
    int i, N;
    
    /* 積分範囲 を代入 */
    a = 1.0;
    
    /* 分割数 N を代入 */
    N = 100;
    
    /* 分割の幅 d を計算. 整数型変数 N を,ここでだけ実数型として扱って計算(下の注を参考)*/
    d = a / (double)(N);
    
    /* fの初期化 */
    f = 0.0;
    
    /* 積分を計算する繰り返し文 */
    for (i = 0; i < N; i++) {
       /* 整数型変数 i を, ここでだけ実数型として扱って計算(下の注を参考) */
       x = ((double)(i)+0.5) * d;
       y = 1.0 - x * x;
       f = f + y * d; 
    }
    
    /* 結果を表示 */
    printf(" 答え %f \n", f);
    
    return 0;
}

– – – – – – – – – – – – – – – –
分割数 N を大きくすると(例えば 10 -> 100 -> 1000 としていくと),2/3=0.66666・・・に近づくことを確認してください。
注:プログラムの途中で、一時的に変数の型を変更すると便利な事があります。(上の例での N, i 等)このような場合「(一時的に使用したい変数の型)(変数)」とすることで、一時的にその文でのみ指定した型の変数として扱う事ができます。つまり, 例えばプログラム始めで double a; と宣言されていても、ある文中で (int)(a) 書かれていれば、その文中のみでは a は int 型変数として扱われます(その文以外のところでは、始めに宣言された型で扱われます)。(int)(a), (double)(N) 等, 整数型, 実数型どちらでも使用可です(例えば a = 2.9 等の場合 (int)(a) は 2 となります。実数型変数を整数型にした場合、小数点以下は 0 になります)。

課題1

例えば積分区間を -2 ~ 3 とした場合の定積分の近似値を計算求めよ。
また適当な関数、積分区間でいろいろ計算してみてみよ。

課題2

xy平面上の曲線,

    \[y = \frac{x(x-3)^2}{1+x^2}\]

y=a~(0<a\le 2)の交点をそれぞれ( x_0, a), (x_1, a), (x_2, a)とし、
x0\le x\le x_1で二つの曲線で囲まれた領域の面積をS_1
x_1\le x\le x_2で二つの曲線で囲まれた領域の面積をS_2
二つの面積の合計をSとする。
a=1.1のときのSを求めるプログラムを作成せよ。

ヒント
まずはx_0,x_1,x_2を求める。次に、x_0からx_1の間をN_1分割して積分し、同様にx_1からx_2の間をN_2分割して積分する。

数学関数

数学関数の使い方

C言語では下記プログラムのように、様々な数学関数を用いることができます。
例えば以下のようなプログラムで、三角関数の計算や平方根等の利用ができます。
(math-1.c として打ち込んでみてください。)

math-1.c

#include <stdio.h>
#include <math.h>
 
int main() {
    double pi,a,x,y,z,r;
    
    pi = 3.14159265;
    a = 3.0;
    r = 10.0;
    
    /*三角関数の計算 */
    x = r*cos(pi/a);
    y = r*sin(pi/a);
    
    /*平方根の計算 */
    z = sqrt(x*x + y*y);
    
    printf("10*cos(pi/3.0)=%lf, 10*sin(pi/3.0)=%lf \n", x, y);
    printf("A square root of (x*x+y*y) is %lf \n", z);
    
    return 0;
}

数学関数を用いる場合には、
#include <math.h> をプログラムの先頭付近に書き入れることと、コンパイル時に、
ファイル名を math-1.c とすると、
gcc math-1.c -o math-1 -lm
というふうに、最後に -lm を付け足す必要があります
sin(), cos(), sqrt()の他に, exp(), tan(), log() などいろいろ用意されています。
さらに、円周率\piも変数”M_PI”として宣言されていますので、今後はこちらを使っても良いです。
(次回以降、よく使う事になります.)

課題3

実数x の値の入力を促し、sin(x)、cos(x)、tan(x)の値を出力するプログラムを作成せよ。

課題4

実数x , hの値の入力を促し、(sin(x + h) – sin(x) )/ h、cos(x)の値を出力するプログラムを作成せよ。
また、同じxの値を与えた場合で、h = 0.1, 0.01, 0.001とおいたときの出力を確認せよ。

課題5

二等辺三角形ABCの角Aの大きさをx (rad)、辺ABと辺ACの長さを共にLとする。
xとLの値の入力を促し、辺BCの長さを求めるプログラムを作成せよ。

課題6

整数Nの入力を促し、半径10の円に内接する正N角形の周りの長さ、面積を求めるプログラムを作成せよ。
(正四角形、正六角形の場合について正しい答えになっているか、またNが大きい場合に円に近い値をとるか、各自試してみよ)

課題7

実数L>0の入力を促し、|sin(x)|をxについて区間[0, L]で積分するプログラムを作成せよ。
絶対値は数学関数fabs()をもちいて計算できる。(例:xの絶対値はfabs(x) )
ただし、区間の分割数nは1000であるとする。

課題8(応用問題)

下図の灰色の部分の面積(の近似値)を数値的に求めるプログラムを作成せよ。
(曲線はそれぞれ y=sin(10*x), y=x*x)
ただし,分割後の領域の幅は0.001以下となるように分割数をとること。
(つまり積分する領域が[0,1]であれば1000分割以上すること)

※ ヒント:積分区間を決めるには、どのようなfor/whileループを作れば良いか?
※ 得られる数値:0.519738程度であればOK。

Department of Mathematical and Life Sciences, Graduate School of Integrated Sciences for Life, Hiroshima University