密度トレイスを計算させるための関数の続き→mickey24が添削してくれたよ!!

昨日の続き。

@tkf経由で知った関数オブジェクトを受け取るアルゴリズム - nursの日記を参照してたら大分きれいになった。operatorに変態な(?)ことをしてやればいいようだ。結果ももちろん昨日のと同じになるよ。

/Users/yasuhisa/cpp% ./a.out     
0	2.72898e-07
1	0.000121768
2	0.00827342
3	0.100135
4	0.290664
5	0.319885
6	0.203549
7	0.064411
8	0.0112637
9	0.00164454
#include <iostream>
#include <vector>
#include <iterator>
#include <cmath>
#include <boost/random.hpp>

using namespace std;
using namespace boost;

class Density
{
public:
  Density( double x ){ X = x; }
  double operator()( double x, double h )
  { 
	const static double PI = 4*atan(1.0);
	return exp( - pow((x-X)/h,2) / 2) / sqrt(2*PI);
  }
private:
  double X;
};

const uint32_t SEED = 123;
double sum_of_kernel_density(vector<Density> densityvec, double x, double h);
int main()
{

  mt19937 gen(SEED);
  normal_distribution<> dst(5.0, 1.0);

  variate_generator<
  mt19937, normal_distribution<>
	> r_norm(gen, dst);
  
  vector<Density> densityvec;
  double h;
  h = 0.7;

  for( int i = 0; i < 100; ++i )
	{
	  Density d(r_norm());
	  densityvec.push_back( d );
	}

  for(int i=0;i<10;++i)
	{
	  cout << i << "\t" << sum_of_kernel_density(densityvec, i, h) << endl;
	}
  return 0;
}

double sum_of_kernel_density(vector<Density> densityvec, double x, double h)
{
  vector<Density>::iterator it;
  it = densityvec.begin();
  double sum;
  sum = 0.0;
  while( it != densityvec.end() )
	{
	  sum = sum + (*it)(x,h);
	  ++it;
	}
  return sum / (densityvec.size() * h);
}