見出し画像

高校数学をプログラミングで解く(数学II編)「5-7 定積分(2)」


はじめに

今回は、数学IIで学ぶ「定積分」について、定積分で表された関数を台形公式を用いて数値的に計算したものと解析的に計算したものとをグラフを描いて比較するためのプログラムを作成します。

定積分で表された関数

まず、定積分で表された関数の性質について解説しておきます。

定積分で表された関数

$${a}$$は$${x}$$に無関係な定数とする。

$$
\int_a^x f(t) dt, \ \ \int_{g(x)}^{h(x)}f(t)dt
$$

は、$${x}$$の関数である。

$$
\frac{d}{dx} \int_a^x f(t)dt = f(x)
$$

定積分の数値計算と解析計算との比較

今回は、以下の定積分で表された関数について、定積分を記事『高校数学をプログラミングで解く(数学II編)「5-6 定積分(1)」』で解説した台形公式を用いて数値的に計算したものと、定積分を解析的に計算して式に表したものとを同じキャンバス上に描いて比較するためのプログラムを作成してみます。

$$
\int_0^x \left( \frac{3}{5} t^2-4t+5 \right) dt
$$

アルゴリズム設計

上記の定積分で表された関数は、解析的に

$$
\int_0^x \left( \frac{3}{5} t^2-4t+5 \right) dt = \frac{1}{5} x (x-5)^2
$$

と計算することができます。この式の左辺を$${x}$$の値を与えたときに台形公式を用いて積分範囲$${[0,x]}$$で数値計算する関数として準備し、また、右辺をそのまま$${x}$$の関数として準備します。これら左辺と右辺の関数を利用してグラフを同じキャンバス上に描いて比較します。

プログラム

それでは、定積分の数値計算と解析計算とを比較するためのプログラムを作成します。
今回は、記事『高校数学をプログラミングで解く(数学II編)「5-3 関数の値の変化」』で作成したスケッチ「calcandplotExtrema」を再利用して作成していきます。(座標軸を設定するための関数 setAxes を定義した「setAxes.pde」ファイルを再利用することが目的ですので、新規にスケッチを作成して、そのスケッチのフォルダに「setAxes.pde」ファイルをコピーする方法で作成しても問題ないです。)
スケッチ「calcandplotExtrema」をフォルダごとコピーして、スケッチの名前(フォルダ名)を「compare_definite_integral」と変更し、またスケッチ「compare_definite_integral」内の「calcandplotExtrema.pde」ファイルの名前を「compare_definite_integral.pde」に変更します。そして、pdeファイル「compare_definite_integral.pde」をダブルクリックしてスケッチ「compare_definite_integral」の開発環境ウィンドウを立ち上げます。開発環境ウィンドウのタブ欄で「compare_definite_integral」タブを選択し、そのテキストエリアのソースコードを以下で書き換えます。

float x_range = 10.0; // x軸の表示範囲 -x_rangeからx_rangeまで
float y_range = 10.0; // y軸の表示範囲 -y_rangeからy_rangeまで 

void setup(){
  size(500,500);
  noLoop();

  setAxes(x_range, y_range); // 座標軸の準備
  noFill();
  
  // グラフの描画範囲  
  float x_min = -x_range;
  float x_max = x_range;
  
  // 定積分を解析的に計算した結果のグラフを描く
  stroke(0,255,0);  
  strokeWeight(5);
  draw_integral_analytic(x_min, x_max);

  // 定積分を台形公式を用いて数値的に計算した結果のグラフを描く
  stroke(255,0,0);
  strokeWeight(2);
  draw_integral_trapezoidal_rule(x_min, x_max);

  // 被積分関数のグラフを描く
  stroke(0,0,255);
  strokeWeight(1);
  draw_integrand(x_min, x_max);

}

// 被積分関数
float integrand(
  float x
){
  return 3.0/5.0*x*x-4.0*x+5.0;
}

// 定積分を台形公式を用いて計算する関数
float trapezoidal_rule(
  float l, // 積分領域の下限
  float r // 積分領域の上限
){
  float dx = 0.01;
  if( l > r ){
    dx = -dx;
  }
  int division_num = (int)((r-l)/dx);
  float x, y1, y2;
  float dintegral = 0.0;
  for(int i=0; i<division_num; i++){
    x = l + i*dx;
    y1 = integrand(x);
    y2 = integrand(x+dx);
    dintegral = dintegral + (y1+y2)*dx/2.0;
  }
  return dintegral;
}

// integrandの積分範囲[0,x]での定積分を解析的に導出した関数
float f(
  float x 
){
  return x*(x-5.0)*(x-5.0)/5.0;
}

// 関数 f を描く関数
void draw_integral_analytic(
  float x_min, // グラフの定義域の下限
  float x_max  // グラフの定義域の上限
){
  int plot_num = 2000; // グラフを描くための頂点の個数  
  
  // グラフを描画
  float x, y; // 関数の座標
  float X, Y; // キャンバス上の座標 
  beginShape();
  for(int i=1; i<plot_num; i++){
    x = x_min + (x_max - x_min) / plot_num * i; // 曲線上の点のx座標
    y = f(x); // 曲線上の点のyの値
    // キャンバス上の座標位置に換算
    X = width / 2.0 / x_range * x;
    Y = height / 2.0 / y_range * y;
    vertex(X, Y);
  }
  endShape();

}

// 関数 trapezoidal_rule を描く関数
void draw_integral_trapezoidal_rule(
  float x_min, // グラフの定義域の下限
  float x_max  // グラフの定義域の上限
){
  int plot_num = 2000; // グラフを描くための頂点の個数  
  
  // グラフを描画
  float x, y; // 関数の座標
  float X, Y; // キャンバス上の座標 
  beginShape();
  for(int i=1; i<plot_num; i++){
    x = x_min + (x_max - x_min) / plot_num * i; // 曲線上の点のx座標
    y = trapezoidal_rule(0.0,x); // 曲線上の点のyの値
    // キャンバス上の座標位置に換算
    X = width / 2.0 / x_range * x;
    Y = height / 2.0 / y_range * y;
    vertex(X, Y);
  }
  endShape();

}

// 関数 integrand を描く関数
void draw_integrand(
  float x_min, // グラフの定義域の下限
  float x_max  // グラフの定義域の上限
){
  int plot_num = 2000; // グラフを描くための頂点の個数  
  
  // グラフを描画
  float x, y; // 関数の座標
  float X, Y; // キャンバス上の座標 
  beginShape();
  for(int i=1; i<plot_num; i++){
    x = x_min + (x_max - x_min) / plot_num * i; // 曲線上の点のx座標
    y = integrand(x); // 曲線上の点のyの値
    // キャンバス上の座標位置に換算
    X = width / 2.0 / x_range * x;
    Y = height / 2.0 / y_range * y;
    vertex(X, Y);
  }
  endShape();

}

ソースコード1 定積分の数値計算と解析計算とを比較するためのプログラム

ソースコード1で、定積分を台形公式を用いて計算する関数 trapezoidal_rule は、記事『高校数学をプログラミングで解く(数学II編)「5-6 定積分(1)」』で作成したスケッチ「calc_definite_integral」内の、3次関数に対する定積分を計算する関数 trapezoidal_rule_cubic_function を参考に作成しています。ただ、trapezoidal_rule_cubic_function 関数は、積分範囲$${[l,r]}$$が$${l \leq r}$$のときのみ利用できる関数でしたので、今回の trapezoidal_rule 関数では、グラフ描画のことも考慮して、積分範囲$${[0,x]}$$が$${x < 0}$$の場合でも正しい定積分の結果が得られるようにしました。

ソースコード1を、スケッチ「compare_definite_integral」の「compare_definite_integral」タブのテキストエディタ部分に書いて実行すると、図1のように、実行ウィンドウのキャンバス上に定積分を解析的に計算した結果の関数のグラフが緑色の太線で、定積分を台形公式を用いて数値的に計算した結果の関数のグラフが赤色の線で、そして、被積分関数のグラフが青色の線でそれぞれ描かれます。

図1 定積分で表された関数のグラフ

図1を見ると、定積分の数値計算の結果のグラフと解析計算の結果のグラフとが重なっています。つまり、

$$
\int_0^x \left( \frac{3}{5} t^2-4t+5 \right) dt = \frac{1}{5} x (x-5)^2
$$

の左辺と右辺とは一致していることが示唆されます。
また、定積分で表された関数のグラフ(赤色の曲線)と被積分関数のグラフ(青色の曲線)とを比較することも勉強になります。つまり、与えられた$${x}$$の値に対して、定積分で表された関数のグラフ(赤色の曲線)の$${y}$$の値は、被積分関数のグラフ(青色の曲線)の$${[0,x]}$$の部分と$${x}$$軸とに挟まれた領域の面積に一致しているはずです。これをいくつかの$${x}$$の値に対して、グラフを眺めてみると、いろいろな示唆が得られるはずです。ぜひ少し考察してみてください。

まとめ

今回は、数学IIで学ぶ「定積分」について、定積分で表された関数を台形公式を用いて数値的に計算したものと解析的に計算したものとをグラフを描いて比較するためのプログラムを作成しました。
今回のように、定積分で表された関数を数値計算や解析計算でグラフを描いてみたり、被積分関数も一緒に描いてみたりして比較して考察するといろいろと示唆を得ることができます。今回は被積分関数が2次関数でしたが、他の形の被積分関数でも是非グラフを描いてみて、比較、考察をしてみてください。

参考文献

改訂版 教科書傍用 スタンダード 数学II(数研出版、ISBN9784410209369)

この記事が気に入ったらサポートをしてみませんか?