2 関数の例

2.1 関数をプロットする

ここでは,関数のグラフを描画する方法を学習する.これを身につけるとどんな関数でも グラフにすることができる.かなり便利である.

基礎数学の教科書 [2]p.82の[例題2]の関数

$\displaystyle y=\frac{3x+2}{x+2}$ (1)

をグラフに描く.この関数をグラフにするためには,次の2つの手順を踏む. -4pt 以降,この2つの手順について説明する.

2.1.1 関数のデータの作成

2.1.1.1 ソースプログラム

式(1)の$ x$の値を少しずつ変化させて,$ y$の値を計算する--プロ グラムは先週の学習の範囲である.リスト1hogehoge()関数 をループ文で繰り返し計算すればよい.

計算結果を描画するためには,$ x$$ y$の値をファイルに保存する必要がある.ファイル の取扱いは,教科書 [1]の10章に書かれており,詳細は 後に学習範する.ここでは,データの保存方法を簡単に述べる.

ファイルにデータを書き出すためには,(1)ファイル情報を格納する変数の用意,(2)ファ イルのオープン,(3)データの書き出し,(4)ファイルのクローズ--という一連の動作を 行う.実際には,リスト1のとおりで,ファイル操作に関する部分を 以下に示す.


   1 #include <stdio.h>
   2 
   3 double hogehoge(double x);                        // プロトタイプ宣言
   4 
   5 //============================================================================
   6 // メイン関数
   7 //============================================================================
   8 int main(void){
   9 
  10   FILE *out;                                      // ファイルの情報を格納
  11   int i, np;
  12   double x, dx, xmax, xmin;
  13 
  14   printf("xの最小値\t");                           // キーボード入力
  15   scanf("%lf", &xmin);
  16   printf("xの最大値\t");
  17   scanf("%lf", &xmax);
  18   printf("プロット点の数\t");
  19   scanf("%d", &np);
  20 
  21   dx = (xmax - xmin)/np;                          //データ間隔計算
  22 
  23   out=fopen("data.txt","w");                      //ファイルをオープン
  24 
  25   for(i=0; i<=np; i++){
  26     x = xmin + i*dx;
  27     fprintf(out, "%f\t%f\n", x, hogehoge(x));     //データの書き込み
  28   }
  29 
  30   fclose(out);                                    //ファイルをクローズ
  31 
  32   return 0;
  33 }
  34 
  35 //============================================================================
  36 //  プロットする数学関数
  37 //============================================================================
  38 double hogehoge(double x){
  39   double y;
  40 
  41   y=(3*x+2)/(x+2);
  42 
  43   return y;
  44 }

2.1.1.2 実行と結果

このプログラムをコンパイルして,次のように実行する.



\fbox{実行結果}

xの最小値       -20
xの最大値       20
プロット点の数  10000

このように実行すると,ファイル「data.txt」ができる.「emacs data.txt」とタ イプして,ファイルの中身を見ると次にようになっている.第一列目が$ x$,第二列目が $ y$の値である.10001個の$ (x,y)$の組ができている.このデータの組を線で結べば,グ ラフができあがる.グラフ描画方法については,次節でのべる.


\fbox{出来上がったファイル(data.txt)の中身}

-20.000000      3.222222
-19.996000      3.222272
-19.992000      3.222321
-19.988000      3.222370
-19.984000      3.222420
-19.980000      3.222469
-19.976000      3.222519
-19.972000      3.222568
-19.968000      3.222618
-19.964000      3.222668
-19.960000      3.222717
-19.956000      3.222767
-19.952000      3.222816
-19.948000      3.222866
-19.944000      3.222916

この辺は長いので,途中省略

19.980000       2.818016
19.984000       2.818049
19.988000       2.818083
19.992000       2.818116
19.996000       2.818149
20.000000       2.818182

2.1.2 データのプロット

データの組$ (x,y)$がファイルに保存されている場合,それをプロットしてグラフ化する ことは容易である.様々なアプリケーションプログラムがある.表計算ソフトウェアー Excel でも可能であるが,私は美しいグラフが書ける gnuplot4 を使うことが多い.

gnuplotを使って,先ほど作成したファイルの$ (x,y)$データを図2のように グラフ化してみよう.手順は,以下のとおりである.ただし,コマンドプロンプトである $gnuplot>はタイプしない.



\fbox{gnuplotによるデータのプロット}

$ gnuplot
gnuplot> plot [-20:20] [-50:50] "data.txt" with line
最初に,gnuplotを立ち上げている.すると,コマンドプロンプトがgnuplot>に変わ る.これは,gnuplotのコマンド入力待ちであることを示している.そこで, コマンド「plot」でグラフを描画する.plot以降は,次のような意味が ある. -4pt

これで,ファイルに保存されたデータをグラフ化できる.gnuplot を終わりたいときには, コマンド「exit」をタイプする.

図 2: ユーザー定義関数を含んだソースプログラムの書き方
\includegraphics[keepaspectratio, scale=1.0]{figure/plot.eps}

2.2 関数から関数を呼び出す

C言語のプログラムでは,関数はいくつでも作ることができる.そして,どこからでも呼 び出すことができる.複数の関数を使い,関数から関数を呼び出す例をつぎに示す.

少しばかり複雑な関数

$\displaystyle y$ $\displaystyle =(x^2+\sqrt{x}+x+\sin x+\cos x)(x^2-\sqrt{x\sin x}-2x-\sin x+4\cos x)$    
  $\displaystyle \qquad\qquad +\frac{x^2+\sqrt{x}+x+\sin x+\cos x+\tan x} {x^2-\sqrt{x\sin x}-2x-\sin x+4\cos x+\tan x}$ (2)

を計算することを考える.よくみると

  $\displaystyle y=f(x)g(x)+\frac{f(x)+\tan x}{g(x)+\tan x}$ (3)
  $\displaystyle f(x)=x^2+\sqrt{x}+x+\sin x+\cos x$ (4)
  $\displaystyle g(x)=x^2-\sqrt{x\sin x}-2x-\sin x+4\cos x$ (5)

と書き直すことができる.この方が,すっきりしてわかりやすい.このような3つの数学 関数は,次のようにプログラム中で記述することができる.関数function()の中か ら,関数f()g()を呼び出している.

//============================================================================
//  数学関数
//============================================================================
double function(double x){
  double y;

  y=f(x)*g(x)+(f(x)+tan(x))/(g(x)+tan(x));

  return y;
}

//============================================================================
//  f(x)
//============================================================================
double f(double x){
  double y;

  y = x*x + sqrt(x) + x  + sin(x) + cos(x);

  return y;
}

//============================================================================
//  g(x)
//============================================================================
double g(double x){
  double y;

  y = x*x - sqrt(x*sin(x)) - 2*x  - sin(x) + 4*cos(x);

  return y;
}

2.3 void型の関数

引数あるいは戻り値が無いときは,void型を指定する.英語の void には,「からの, 空虚な,」という意 味がある.引数や戻り値は無いが関数は手続きなので,実行すると効果はある.例えばリ スト2の場合である.このプログラムの関数 write_file() は,(1)ファイルを開き,(2)データを書き込み,(3)ファイルを閉じる--という動作を行 う.
   1 #include <stdio.h>
   2 
   3 void write_file(void);                       // プロトタイプ宣言
   4 
   5 //============================================================================
   6 // メイン関数
   7 //============================================================================
   8 int main(void){
   9 
  10   write_file();                              // 関数の呼出
  11 
  12   return 0;
  13 }
  14 
  15 //============================================================================
  16 // void型の関数
  17 //============================================================================
  18 void write_file(void){
  19   FILE *fuga;
  20 
  21   fuga = fopen("hello.txt", "w");            // ファイルのオープン
  22   
  23   fprintf(fuga, "Hello World !!!\n");        // ファイルへの書き出し
  24 
  25   fclose(fuga);                              // ファイルのクローズ
  26 }

ホームページ: Yamamoto's laboratory
著者: 山本昌志
Yamamoto Masashi
平成18年11月10日


no counter