Отрицательное биномиальное распределение

В данном разделе представлены функции для работы с отрицательным биномиальным распределением. Они позволяют производить расчет плотности, вероятности, квантилей и генерировать псевдослучайные числа, распределенные по отрицательному биномиальному закону. Отрицательное биномиальное распределение описывается следующей формулой:

pdf_negative_binomial_distribution

где:

  • x — значение случайной величины
  • r — количество успешных испытаний
  • p — вероятность успеха

DemoNegativeBinomial

Помимо расчета отдельных случайных величин, реализована возможность работы с их массивами.  

Функция

Описание

MathProbabilityDensityNegativeBinomial

Рассчитывает плотность вероятности отрицательного биномиального распределения

MathCumulativeDistributionNegativeBinomial

Рассчитывает значение функции отрицательного биномиального распределения вероятностей

MathQuantileNegativeBinomial

Рассчитывает значение обратной функции отрицательного биномиального распределения для заданной вероятности

MathRandomNegativeBinomial

Генерирует псевдослучайную величину/массив псевдослучайных величин, распределенных по отрицательному биномиальному закону

MathMomentsNegativeBinomial

Рассчитывает теоретические численные значения первых 4 моментов отрицательного биномиального распределения

Пример:

#include <Graphics\Graphic.mqh>
#include <Math\Stat\NegativeBinomial.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double n_par=40;        // количество испытаний
input double p_par=0.75;      // вероятность успеха для каждого испытания
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- отключим показ ценового графика
   ChartSetInteger(0,CHART_SHOW,false);
//--- инициализируем генератор случайных чисел  
   MathSrand(GetTickCount());
//--- сгенерируем выборку случайной величины
   long chart=0;
   string name="GraphicNormal";
   int n=1000000;       // количество значений в выборке
   int ncells=19;       // количество интервалов в гистограмме
   double x[];          // центры интервалов гистограммы
   double y[];          // количество значений из выборки, попавших в интервал
   double data[];       // выборка случайных значений 
   double max,min;      // максимальное и минимальное значения в выборке
//--- получим выборку из отрицательного биномиального распределения 
   MathRandomNegativeBinomial(n_par,p_par,n,data);
//--- рассчитаем данные для построения гистограммы
   CalculateHistogramArray(data,x,y,max,min,ncells);
//--- получим теоретически рассчитанные данные на интервале [min,max]
   double x2[];
   double y2[];
   MathSequence(0,n_par,1,x2);
   MathProbabilityDensityNegativeBinomial(x2,n_par,p_par,false,y2);
//--- масштабируем
   double theor_max=y2[ArrayMaximum(y2)];
   double sample_max=y[ArrayMaximum(y)];
   double k=sample_max/theor_max;
   for(int i=0; i<ncells; i++)
      y[i]/=k;
//--- выводим графики
   CGraphic graphic;
   if(ObjectFind(chart,name)<0)
      graphic.Create(chart,name,0,0,0,780,380);
   else
      graphic.Attach(chart,name);
   graphic.BackgroundMain(StringFormat("Negative Binomial distributionn n=%G p=%G",n_par,p_par));
   graphic.BackgroundMainSize(16);
//--- plot all curves
   graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
//--- а теперь построим теоретическую кривую плотности распределения 
   graphic.CurveAdd(x2,y2,CURVE_LINES,"Theory").LinesSmooth(true);
   graphic.CurvePlotAll();
//--- plot all curves
   graphic.Update();
  }
//+------------------------------------------------------------------+
//|  Calculate frequencies for data set                              |
//+------------------------------------------------------------------+
bool CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[],
                             double &maxv,double &minv,const int cells=10)
  {
   if(cells<=1) return (false);
   int size=ArraySize(data);
   if(size<cells*10) return (false);
   minv=data[ArrayMinimum(data)];
   maxv=data[ArrayMaximum(data)];
   double range=maxv-minv;
   double width=range/cells;
   if(width==0) return false;
   ArrayResize(intervals,cells);
   ArrayResize(frequency,cells);
//--- зададим центры интервалов
   for(int i=0; i<cells; i++)
     {
      intervals[i]=minv+(i+0.5)*width;
      frequency[i]=0;
     }
//--- заполним частоты попадания в интервал
   for(int i=0; i<size; i++)
     {
      int ind=int((data[i]-minv)/width);
      if(ind>=cells) ind=cells-1;
      frequency[ind]++;
     }
   return (true);
  }