дискретная непрерывная функция кумулятивной плотности - PullRequest
0 голосов
/ 11 июня 2018

Мой вопрос заключается в том, возможно ли преобразовать вектор, в котором хранятся сэмплы исходного CDF (накопительная функция плотности) ...

примерно так:

class normal
{
 public:

   float mean;
   float sigma;
   float variance = sigma * sigma;
   float left_margin = mean - 4 * sigma;
   float right_margin = mean + 4 * sigma;
   normal():mean(0), sigma(1){}
   normal(float m, float s):mean(m), sigma(s){}

   float cdf(float x); 
   float pdf(float x); 
};

float normal::pdf(float x)
{
   if (x < left_margin || x > right_margin)     return 0;

   float coefficient = 1 / (float)sqrt(2 * PI * variance);

   float x_mean = x - mean;
   float result = coefficient * exp(-(x_mean * x_mean) / 2 * variance);
   return result;
}

float normal::cdf(float x) 
{
   if (x <= left_margin)      return 0;
   if (x >= right_margin)     return 1;

   float x_mean = x - mean;
   float result = (float)(0.5 * (1 + erf((x_mean) / sqrt(2 * variance))));
   if (result > 1) return 1;
   else return result;
}

std::vector<float> discrete_normal_cdf(normal& X)
{
   std::vector<float> vec;

   float L = (float)(X.left_margin);
   float R = (float)(1.2 * X.right_margin);

   while (L <= R)
   {
      vec.push_back(X.cdf(L));
      L = (float)(L + 0.1);
   }   

   std::vector<float> tmp;
   // take three samples
   tmp.push_back(vec.at(1));    // first non_zero element
   tmp.push_back(vec.at(40));   // add element with value of 0.5
   tmp.push_back(vec.at(80));   // element with value of 0.99


   std::vector<float> cdf_v(5, 0);

   for (auto i = 0; i < tmp.size(); i++)
      cdf_v.push_back(tmp.at(i));

   int l = 0;
   while (l < 5)
   {
      cdf_v.push_back(1);
      l++;
   }
   return cdf_v;
}

На самом деле, чтоМне нужно вот что: если у нас есть нормальный

 normal n1(5, 1);

, берут сэмплы его CDF, чтобы разрезать линейный CDF:

 vector<float> foo = discrete_normal_cdf(n1); 

, затем восстанавливаем кусочно-линейный CDF в нормальный

 normal function(foo)
 {
    return normal(5, 1);
 }

Является ли эта функция действительной? Я написал функцию, которая принимает вектор в качестве входных данных и ищет во всех элементах вектора значение 0,5 и возвращает индекс этого элемента каксреднее нормальное, но не всегда истинное.

normal vec2normal(vector<float>& vec)
{
     int mean;
     mean = std::find(vec.begin(), vec.end(), 0.5) - vec.begin();
     return normal(mean, 1);
}

Я понятия не имею, как это сделать, поэтому любые предложения будут оценены, спасибо.

...