プログラミング演習1 課題3 数値解析法

2. Cによる数値解析のための準備2

2.1 入出力のリダイレクト

出力データをCSV形式で保存すれば、Excelなどのスプレッドシートでただちに読み出すことができる。CSV形式は一組のデータをコンマで区切り、組ごとに改行したフォーマットである。CSVファイルを作成するにはファイルの読み書きに関する関数を使う方法もあるが、ここでは「リダイレクト」機能を使った方法を紹介する。

リダイレクトは標準入出力の対象をファイルや別のプログラムにすることを指す。具体的には、「<」や「>」などの記号を使って以下のように記述する。

Visual Studio上でコマンド引数を指定するには、メニューから「プロジェクト」>「(プロジェクト名)のプロパティ」をクリックし、左枠内の構成プロパティ>デバッグをクリックする。そして、右側の枠内の「コマンド引数」の欄にリダイレクトを指定する。

redirect

練習1 リダイレクト

以下のプログラムを実行してみよう。正しく実行できたら、リダイレクト先を"output.csv"に設定してもう一度実行しよう。

#include <stdio.h>
#include <math.h>

int main(void)
{
    printf("n, err, approx\n"); // 項目名
    int n = 0;
    double pi0, pi1 = 0, err, sign = 1;
    double eps = 1.0e-2;
    const int MAXLOOP = 1000;
    do {
        pi0 = pi1;
        double k = (double)n;
        pi1 += sign * (4.0 / (2 * n + 1));
        err = fabs(pi1 - pi0);
        printf("%d, %g, %g\n", n, err, pi1);
        sign *= -1;
        n += 1;
        if (n > MAXLOOP) {
            fprintf(stderr, "既定のループ回数を超過しました\n");
            break;
        }
    } while (err >= eps);
    
    return 0;
}

2.2 Excelによるグラフの描画

次に、出力されたcsvファイルをExcelを使ってグラフ化する。

  1. エクスプローラーでプロジェクトファイルのある場所を探し、output.csvファイルを開く。
  2. グラフを作成するために、データの範囲を選択する。以下の操作により、データ範囲をすばやく選択できる。
  3. [挿入]→[グラフ]→[散布図(直線)]を選択。
  4. グラフ右上の [+] からグラフ要素の [軸ラベル] を選択し、「横軸ラベル」を、"Iteration" に書き換える。また「縦軸ラベル」を、"approx, err"に書き換える。
  5. グラフのタイトルを削除する、軸の文字色やメモリを変えるなどして、下の図に近づけてみよう。
  6. グラフを(右クリックから)コピーして Word など他のアプリケーションに貼り付けることが可能である。
  7. グラフを作成したらExcelブック(*.xlsx)として「名前を付けて保存」しておこう。

csv csv

練習2 グラフ作成

上記の操作を行い、グラフを描いてみましょう。グラフから何がわかるでしょうか?


レポート課題1 疑似乱数の分布

ここまで、各種の数学関数と、計算結果を出力しグラフに描画する手順を紹介しました。それぞれの説明を復習しつつ、レポート課題1に取り組みましょう。

手順1

以下は、疑似乱数を発生させて、それらの平均値と標準偏差を求めるプログラムです。下記の仕様を満たすように、プログラム中の(1)~(9)の穴を埋めて完成させてください。

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define LEN 4
#define SEED __(1)__

int main(void)
{
    int i, j, random;
    int n[] = {10, 20, 100, 1000};

    double sum, ssqu, mean[LEN], sd[LEN];

    srand( __(2)__ );
    for (i = 0; i < LEN; i++){
        sum = ssqu = 0.0;
        for (j = 0; j < n[i]; j++){
            random = rand()%__(3)__;    /*ヒント:1~100までの表し方*/
            sum  += random;
            ssqu += __(4)__;            /*ヒント:ssquは乱数の二乗和*/ 
        }
        mean[i] = __(5) / __(6)__;      /*平均値*/
        sd[i] = sqrt(fabs(ssqu/n[i] - pow(mean[i], 2)));
    }
    printf("N, Mean, SD\n");
    for (i = 0; i < LEN; i++) {
        printf("%d, %4.2lf, %4.2lf\n", __(7)__, __(8)__, __(9)__);
    }
    return 0;
}

手順2

横軸を疑似乱数の個数(10、20、100、1000)、縦軸を平均値とするグラフ(棒グラフ)をExcelを用いて作成してください。

bar graph

【※Excel作図のポイント】
  1. N, Mean, SDの対応表をリダイレクトを使ってcsvファイルに出力する。
  2. [挿入]→[2-D縦棒]→[集合縦棒]を選択し、グラフを作る。
  3. そのグラフ上で右クリック→[データの選択]→データソースの選択ウィンドウを開く。
  4. 系列の[編集]を選択し、系列名:疑似乱数、系列値:Meanの4個のデータを追加または選択して[OK]する。
  5. 軸ラベル[編集]を選択し、Nの4つの設定値(10,20,100,1000)を選択する。
  6. 図の右上の“+”の[誤差範囲]→[その他の誤差範囲オプション]を選択する。
  7. 図の右上の“+”の軸ラベルを選択し、縦軸、横軸ラベルを記載するなど、図としての完成度をあげる。
  8. 参考: グラフの誤差範囲を追加、変更、または削除する

<補足資料>

なぜ標準偏差が必要なのか?

オプション課題

  1. time関数(ヘッダ<time.h>をインクルード)を用いてseedに“現在の時刻”を設定し、プログラムを実行する度に異なる乱数を発生させるプログラムを作成してください。
  2. グラフから読み取れることについて、平均値と標準偏差の理論値について説明しつつ記述してください。ヒント:一様分布

【目次】 | 【1.】 | 【3.】