読者です 読者をやめる 読者になる 読者になる

ファイルを整理していたら昔書いたコードが出て来た

タイムスタンプは2007/10/28になってるけど、その日にどこからかコピーしてきたんだろうと思われる。多分、一年半くらい前に書かれたものと思われる。いやもっと前かも。「反復構造と選択構造を使え」ってな講義の課題だと思われる。でもC++で書いてるしテンプレートも使ってるから、テンプレートを習得した時期から考えて、大学院時代なんだよな。こんな宿題が出る大学院って…。

//反復構造: for(;;)を多用
//選択構造: if, switchを使用(main()内)
//how to compile:
//%g++ checkRandomness.cpp
//
//そこそこ新しいg++なら通るはず
//乱数の分布を確かめるテストプログラム
//0から1の間の乱数の出現だけを記録してグラフに表示
//doubleで0-1を返す関数なら何でも可

#include <stdlib.h>
#include <time.h>
#include <math.h>

#include <iostream>
#include <vector>

#define RAND_TMP_MAX 0xABCDEF
#define PI 3.14159268
#define N 0x1000  //試行繰返し回数
#define DIVIDE 10 //区間分割数
#define LENGTH 50 //グラフ縦軸の長さ

using namespace std;

double generaterandom(){
  return (rand()%RAND_TMP_MAX)*1.0/RAND_TMP_MAX;
}//0〜1の一様分布乱数を返す関数


//平均mean, 分散varianceの正規分布乱数を返す関数
double NormalRandomNum(double mean, double variance){
  double t=sqrt(-2.0 * log(1.0-(rand()%RAND_TMP_MAX)*1.0/RAND_TMP_MAX));
	//                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//                                  →0-1.0の均等乱数
  double u=2*PI*(rand()%RAND_TMP_MAX)*1.0/RAND_TMP_MAX;
  return variance*t*cos(u)+mean;
}

int main(){
  double tmp;
  vector<double> stats;

  //乱数取得数を格納する区間を示すvectorを準備
  for(int i=0;i<DIVIDE;i++)
    stats.push_back(0);
  srand((unsigned int)time(NULL)%RAND_TMP_MAX);

  for(int i=0;i<N;i++){    //乱数を取る試行:乱数を与える関数なら何でもよし

    tmp=NormalRandomNum(0.5, 0.2); //正規分布
    //tmp=generaterandom();       //一様分布

   //該当する区間で乱数を処理
    for(int j=0;j<DIVIDE;j++){
      if(((double)(j))/DIVIDE <tmp && tmp < ((double)(j+1))/DIVIDE)
        stats[j] += 1.0/N;
    }
  }

  //以下、データ表示
  cout << "0";
  for(int i=0;i<LENGTH;i++){
    switch (i){
      case LENGTH/2 :
      case LENGTH/4:
      case LENGTH*3/4:
        cout << "+";
        break;
      default:
        cout << "-";
        break;
    }
  }
  cout << "100%" << endl;

  for(int i=0;i<DIVIDE;i++){
    cout << "|" ;//<< stats[i] ;

    for(int j=0; (double)j< stats[i]*LENGTH;j++)
      cout << "*";

    cout << endl;
  }
}