StochHMM  v0.34
Flexible Hidden Markov Model C++ Library and Application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
distributions.cpp
Go to the documentation of this file.
1 /*
2  * distributions.cpp
3  *
4  * Created by Paul Lott on 4/22/09.
5  * Copyright 2009 University of California, Davis. All rights reserved.
6  *
7  */
8 
9 #include "distributions.h"
10 
11 namespace StochHMM{
12  int maximum=1000000;
13 
14 
15 
16  //////////////////////// DISTRIBUTIONS ///////////////////////////////////
17 
18 
19  ////// DISCRETE & FINITE //////
20 
21 
22  //!Binomial Distribution Survival Function
23  //!\param [out] dist
24  //!\param trials Number of trials in experiment
25  //!\param prob Probability of success
26  void sBinomial (std::vector<double>&dist, int trials, double prob){
27  //http://en.wikipedia.org/wiki/Binomial_distribution
28  double cdf=0;
29  for (int i=1; i<maximum;i++){
30  double pmf=bin_coef(trials,i)*pow(prob,i)*pow(1-prob,trials-i);
31  cdf+=pmf;
32  double val=1-cdf;
33  if (val<=0){
34  break;
35  }
36  else{
37  dist.push_back(val);
38  }
39  }
40  return;
41  }
42 
43 
44  //!Binomial Cumulative Distribution
45  //!\param [out] dist
46  //!\param trials Number of trials in experiment
47  //!\param prob Probability of success
48  void cBinomial (std::vector<double>&dist, int trials, double prob){
49  //http://en.wikipedia.org/wiki/Binomial_distribution
50  double cdf=0;
51  for (int i=1; i<maximum;i++){
52  double pmf=bin_coef(trials,i)*pow(prob,i)*pow(1-prob,trials-i);
53  cdf+=pmf;
54  double val=cdf;
55  if (val>=1.0){
56  dist.push_back(1.0);
57  break;
58  }
59  else{
60  dist.push_back(val);
61  }
62  }
63  return;
64  }
65 
66 
67 
68  //!BetaBinomial Survival Function
69  //!<a href = "http://en.wikipedia.org/wiki/Beta-binomial_model">
70  //!\param [out] dist
71  //!\param trials Number of trials
72  //!\param a alpha
73  //!\param b beta
74  void sBetaBinomial (std::vector<double>& dist, int trials, double a, double b){
75  double cdf = 0;
76  for (int i=1; i<maximum;i++){
77  double newAlpha = (double) i + a;
78  double newBeta = (double)(trials-i) + b;
79  double pmf = bin_coef(trials,i) * (beta(newAlpha,newBeta)/ beta(a,b));
80  cdf+=pmf;
81  double val=1-cdf;
82 
83  if (val<=0){
84  dist.push_back(1.0);
85  break;
86  }
87  else{
88  dist.push_back(val);
89  }
90  }
91  return;
92 
93  }
94 
95  //!BetaBinomial Cumulative Distribution
96  //!<a href = "http://en.wikipedia.org/wiki/Beta-binomial_model">
97  //!\param [out] dist
98  //!\param trials Number of trials
99  //!\param a alpha
100  //!\param b beta
101  void cBetaBinomial (std::vector<double>& dist, int trials, double a, double b){
102  double cdf = 0;
103  for (int i=1; i<maximum;i++){
104  double newAlpha = (double) i + a;
105  double newBeta = (double)(trials-i) + b;
106  double pmf = bin_coef(trials,i) * (beta(newAlpha,newBeta)/ beta(a,b));
107  cdf+=pmf;
108  double val=cdf;
109 
110  if (val>=1.0){
111  dist.push_back(1.0);
112  break;
113  }
114  else{
115  dist.push_back(val);
116  }
117  }
118  return;
119  }
120 
121 
122 
123  //!Degenerate Survival Function
124  //!Support consists of only one value
125  //!\param [out] dist
126  //!\param value
127  void sDegenerate(std::vector<double>&dist, double value){
128  for (int i=0;i<value;i++){
129  dist.push_back(1);
130  }
131  dist.push_back(0);
132  return;
133  }
134 
135 
136  //!Degenerate Cumulative Distribution
137  //!Support consists of only one value
138  //!\param [out] dist
139  //!\param value
140  //!<a href = "http://en.wikipedia.org/wiki/Degenerate_distribution">
141  void cDegenerate(std::vector<double>&dist, double value){
142  for (int i=0;i<value;i++){
143  dist.push_back(0);
144  }
145  dist.push_back(1);
146  return;
147  }
148 
149 
150  //!Discrete Uniform Survival Function
151  //!<a href = "http://en.wikipedia.org/wiki/Uniform_distribution_(discrete)">
152  void sUniform (std::vector<double> &dist,int lower,int upper){
153  for(int k=0;k<=upper;k++){
154  if (k<lower){
155  dist.push_back(1);
156  }
157  else if (k>=lower && k<=upper){
158  double val=(k-lower+1)/(upper-lower+1);
159  dist.push_back(1-val);
160  }
161  }
162  return;
163  }
164 
165  //!Discrete Uniform Cumulative Distribution
166  //!<a href = "http://en.wikipedia.org/wiki/Uniform_distribution_(discrete)">
167  void cUniform (std::vector<double> &dist,int lower,int upper){
168  for(int k=0;k<=upper;k++){
169  if (k<lower){
170  dist.push_back(0);
171  }
172  else if (k>=lower && k<=upper){
173  double val=(k-lower+1)/(upper-lower+1);
174  dist.push_back(val);
175  }
176  }
177  return;
178  }
179 
180 
181 
182 
183  //!Complement CDF Hypergeometric Distribution
184  //!\param [out] dist
185  //!\param N Population Size
186  //!\param m Number of successes
187  //!\param n Number of draws
188  void sHypergeometric (std::vector<double> &dist,int N, int m, int n){
189  //http://en.wikipedia.org/wiki/Hypergeometric_distribution
190  double cdf=0;
191  for( int k=0;k<maximum;k++){ //k = number of successes
192  double pmf=((double)bin_coef(m,k) * (double)bin_coef(N-m,n-k))/(double) bin_coef(N,n);
193  cdf+=pmf;
194  double val=1-cdf;
195  if (val<=0){
196  break;
197  }
198  else{
199  dist.push_back(val);
200  }
201  }
202  return;
203  }
204 
205 
206 
207  //! CDF Hypergeometric Distribution
208  //!\param [out] dist
209  //!\param N Population Size
210  //!\param m Number of successes
211  //!\param n Number of draws
212  void cHypergeometric (std::vector<double> &dist,int N, int m, int n){
213  //http://en.wikipedia.org/wiki/Hypergeometric_distribution
214  double cdf=0;
215  for( int k=0;k<maximum;k++){ //k = number of successes
216  double pmf=((double)bin_coef(m,k) * (double)bin_coef(N-m,n-k))/(double) bin_coef(N,n);
217  cdf+=pmf;
218  double val=cdf;
219  if (val>=1){
220  dist.push_back(1.0);
221  break;
222  }
223  else{
224  dist.push_back(val);
225  }
226  }
227  return;
228  }
229 
230 
231 
232 
233  //Cauchy Distribution
234  void sCauchy(std::vector<double> &dist,double location, double scale){
235  //http://en.wikipedia.org/wiki/Cauchy_distribution
236  for (int i=0; i<maximum;i++){
237  double val=1-((1/M_PI)*atan((i-location)/scale)+0.5);
238  if (val==0){
239  break;
240  }
241  else{
242  dist.push_back(val);
243  }
244  }
245  return;
246  }
247 
248  //! CDF of Chi-Squared Distribution
249  //! \param x Chi-Square Value
250  //! \param df Degrees of freedom
251  //! \return double Value of CDF at x
252  double cChiSquared(double x,double df){
253  double val = 1.0/tgamma(df/2.0);
254  double div = igamma_lower(df/2.0,x/2.0);
255  return val*div;
256  }
257 
258 
259  //! Complement CDF/Survival of Chi-Squared Distribution
260  //! \param [out] dist Vector to store distribution in
261  //! \param df Degrees of freedom
262  //ChiSquared Distribution
263  void sChiSquared(std::vector<double> &dist, double df){
264  //http://en.wikipedia.org/wiki/Chi-square_distribution
265  for (double i=1; i<maximum;i++){
266  //CDF Value
267  double val=1.0/tgamma(df/2.0);
268  double div=igamma_lower(df/2.0, i/2.0);
269  val*=div;
270 
271  //CCDF value
272  val = 1-val;
273  if (fabs(val)<0.00001){
274  break;
275  }
276  else{
277  dist.push_back(val);
278  }
279  }
280  return;
281  }
282 
283 
284 
285 
286 
287 
288  //!Complement CDF Exponential Distribution
289  //!\param [out] dist
290  //!\param lambda Value of lambda to use
291  //!<a href = "http://en.wikipedia.org/wiki/Exponential_distribution">
292  void sExponential (std::vector<double> &dist, double lambda){
293  for (int i=0; i<maximum;i++){
294  double val=exp(-1*lambda*i);
295  if (val==0){
296  break;
297  }
298  else{
299  dist.push_back(val);
300  }
301  }
302  return;
303  }
304 
305  //!CDF Exponential Distribution
306  //!\param [out] dist
307  //!\param lambda Value of lambda to use
308  //!<a href = "http://en.wikipedia.org/wiki/Exponential_distribution">
309  void cExponential (std::vector<double> &dist, double lambda){
310  for (int i=0; i<maximum;i++){
311  double val=1-exp(-1*lambda*i);
312  if (val==0){
313  break;
314  }
315  else{
316  dist.push_back(val);
317  }
318  }
319  return;
320  }
321 
322 
323 
324 
325 
326  //
327  //void sExtremeValue(vector<double> &dist, double location, double shape, double scale){
328  // if (scale<=0){
329  // std::cerr << "Extreme value doesn't support scale <=0" <<std::endl;
330  // return;
331  // }
332  // //http://en.wikipedia.org/wiki/Extreme_value_distribution
333  //}
334  //
335  //void cExtremeValue(vector<double> &dist, double location, double shape, double scale){
336  // if (scale<=0){
337  // std::cerr << "Extreme value doesn't support scale <=0" <<std::endl;
338  // return;
339  // }
340  //
341  // if (shape == 0){
342  //
343  // }
344  // else{
345  // for(int i=0;i<maximum;i++){
346  // double tx = exp((i-location)/shape
347  // double val = 1-exp(-1*tx);
348  // }
349  // }
350  // //http://en.wikipedia.org/wiki/Extreme_value_distribution
351  //}
352 
353 
354 
355  //F-Distribution Distribution
356  void sFDistribution(std::vector<double> &dist, double dOne, double dTwo){
357  //http://en.wikipedia.org/wiki/F_distribution
358  for (int i=0;i<maximum;i++){
359  double val=1-ribeta((dOne*i)/((dOne*i)+dTwo), dOne/2, dTwo/2);
360  if (val==0){
361  break;
362  }
363  else{
364  dist.push_back(val);
365  }
366  }
367  return;
368  }
369 
370 
371  //F-Distribution Distribution
372  void cFDistribution(std::vector<double> &dist, double dOne, double dTwo){
373  //http://en.wikipedia.org/wiki/F_distribution
374  for (int i=0;i<maximum;i++){
375  double val=ribeta((dOne*i)/((dOne*i)+dTwo), dOne/2, dTwo/2);
376  if (val==1){
377  dist.push_back(1.0);
378  break;
379  }
380  else{
381  dist.push_back(val);
382  }
383  }
384  return;
385  }
386 
387 
388 
389 
390 
391  //Gamma distribution
392  void sGamma(std::vector<double> &dist, double shape, double scale){
393  //http://en.wikipedia.org/wiki/Gamma_distribution
394  for (int i=0;i<maximum;i++){
395  double val=1-igamma_lower(shape, i/scale)/tgamma(shape);
396  if (val==0){
397  break;
398  }
399  else{
400  dist.push_back(val);
401  }
402  }
403  return;
404  }
405 
406  //Gamma distribution
407  void cGamma(std::vector<double> &dist, double shape, double scale){
408  //http://en.wikipedia.org/wiki/Gamma_distribution
409  for (int i=0;i<maximum;i++){
410  double val=igamma_lower(shape, i/scale)/tgamma(shape);
411  if (val==1){
412  dist.push_back(1.0);
413  break;
414  }
415  else{
416  dist.push_back(val);
417  }
418  }
419  return;
420  }
421 
422 
423  //Geometric Distribution
424  void sGeometric (std::vector<double> &dist, double p){
425  //http://en.wikipedia.org/wiki/Geometric_distribution
426  for (int i=0;i<maximum;i++){
427  double val=pow((1-p),i+1);
428  if (val==0){
429  break;
430  }
431  else{
432  dist.push_back(val);
433  }
434  }
435  return;
436  }
437 
438  void cGeometric (std::vector<double> &dist, double p){
439  //http://en.wikipedia.org/wiki/Geometric_distribution
440  for (int i=0;i<maximum;i++){
441  double val=1-pow((1-p),i+1);
442  if (val==1){
443  dist.push_back(1.0);
444  break;
445  }
446  else{
447  dist.push_back(val);
448  }
449  }
450  return;
451  }
452 
453 
454 
455 
456  //Laplace Distribution
457  void sLaplace(std::vector<double> &dist , double location, double scale){
458  //http://en.wikipedia.org/wiki/Laplace_distribution
459  for( int i=0;i<maximum;i++){
460  double val=(1/(2*scale))*exp(-1*(fabs(i-location)/scale));
461  if (val==0){
462  break;
463  }
464  else{
465  dist.push_back(val);
466  }
467  }
468  return;
469  }
470 
471  //Log-Normal Distribution
472  void sLogNormal(std::vector<double> &dist,double location, double scale){
473  //http://en.wikipedia.org/wiki/Lognormal_distribution
474  for( int i=0;i<maximum;i++){
475  double val=0.5+0.5*(erf((log(i-location)/sqrt(2*pow(scale,2)))));
476  if (val==0){
477  break;
478  }
479  else{
480  dist.push_back(val);
481  }
482  }
483  return;
484  }
485 
486 
487  //Logarithmic Distribution
488  void sLogarithmic(std::vector<double> &dist, double prob){
489  //http://en.wikipedia.org/wiki/Logarithmic_distribution
490  double cdf=0;
491  for( int i=1;i<maximum;i++){
492  double pmf=(-1/log(1-prob))*((pow(prob,i)/i));
493  cdf+=pmf;
494  double val=1-cdf;
495  if (val==0){
496  break;
497  }
498  else{
499  dist.push_back(val);
500  }
501  }
502  return;
503  }
504 
505  //Logistic Distribution
506  void sLogistic(std::vector<double> &dist, double location, double scale){
507  //http://en.wikipedia.org/wiki/Logistic_distribution
508  for( int i=0;i<maximum;i++){
509  double val=1-(1/(1+exp(-1*(i-location)/scale)));
510  if (val==0){
511  break;
512  }
513  else{
514  dist.push_back(val);
515  }
516  }
517  return;
518  }
519 
520 
521 
522  void sMaxwellBoltzman(std::vector<double> &dist, double scale){
523  //http://en.wikipedia.org/wiki/Maxwell–Boltzmann_distribution
524  for( int i=0;i<maximum;i++){
525  double error=erf(i/(sqrt(2)*scale));
526  double i_squared=-1*pow((double)i,2);
527  double val=sqrt(2*(1/M_PI))*((double)i*exp(i_squared/(2*pow(scale,2)))/scale);
528  double boltz=1-(error-val);
529  if (boltz==0){
530  break;
531  }
532  else{
533  dist.push_back(boltz);
534  }
535  }
536  return;
537  }
538 
539  //Negative Binomial Distribution
540  void sNegativeBinomial(std::vector<double> &dist,int r, double p){
541  //http://en.wikipedia.org/wiki/Negative_binomial_distribution
542  for( int i=0;i<maximum;i++){
543  double val=ribeta(p, i+1, r);
544  if (val==0){
545  break;
546  }
547  else{
548  dist.push_back(val);
549  }
550  }
551  return;
552  }
553 
554 
555 
556  /*
557  void sNonCentralChiSquared(vector<double> &dist, double v, double lmda){
558  //http://en.wikipedia.org/wiki/Noncentral_chi-square_distribution
559  double cdf=0;
560  for( int i=1;i<maximum;i++){
561  double pmf=(-1/log(1-prob))*((pow(prob,i)/i));
562  cdf+=pmf;
563  double val=1-cdf;
564  if (val==0){
565  break;
566  }
567  else{
568  dist.push_back(val);
569  }
570  }
571  return;
572 
573  }
574 
575 
576 
577  //Non-Central F distribution
578  void sNonCentralF(vector<double> &dist,double vone, double vtwo, double lmda){
579  //http://en.wikipedia.org/wiki/Noncentral_F-distribution
580  }
581 
582 
583  //Non-Central T distribution
584  void sNonCentralT(vector<double> &dist, double v, double lambda){
585  //http://en.wikipedia.org/wiki/Noncentral_t-distribution
586  }
587  */
588 
589  //Normal distribution
590  void sNormal(std::vector<double> &dist, double mean, double stdev){
591  //http://en.wikipedia.org/wiki/Normal_distribution
592  for( int i=0;i<maximum;i++){
593  double val=1-(0.5*(1+erf((i-mean)/sqrt(2*pow(stdev,2)))));
594  if (val==0){
595  break;
596  }
597  else{
598  dist.push_back(val);
599  }
600  }
601  return;
602 
603  }
604 
605  //Pareto Distribution
606  void sPareto(std::vector<double> &dist,double shape, double scale){
607  for( int i=0;i<maximum;i++){
608  double val=pow((scale/(double) i),shape);
609  if (val==0){
610  break;
611  }
612  else{
613  dist.push_back(val);
614  }
615  }
616  return;
617  }
618 
619  //Poisson Distribution
620  void sPoisson(std::vector<double> &dist, double lambda){
621  //http://en.wikipedia.org/wiki/Poisson_distribution
622  for( int i=0;i<maximum;i++){
623  double val=igamma_upper(i+1,lambda)/factorial(i);
624  if (val==0){
625  break;
626  }
627  else{
628  dist.push_back(val);
629  }
630  }
631  return;
632  }
633 
634 
635  //Rayleigh Distribution
636  void sRayleigh(std::vector<double> &dist, double sigma){
637  //http://en.wikipedia.org/wiki/Rayleigh_distribution
638  for( int i=0;i<maximum;i++){
639  double val=exp((-1*(pow((double) i, 2)))/(2*pow(sigma,2)));;
640  if (val==0){
641  break;
642  }
643  else{
644  dist.push_back(val);
645  }
646  }
647  return;
648  }
649 
650  //Triangular distribution
651  void sTriangular(std::vector<double> &dist,int a, int b, int c){
652  //http://en.wikipedia.org/wiki/Triangular_distribution
653  double val=0;
654  for(int x=0;x<=b;x++){
655  if (x<a){
656  dist.push_back(1);
657  }
658  else if (x>=a && x<=c){
659  val=pow((double)(x-a),2)/((b-a)*(c-a));
660  dist.push_back(1-val);
661  }
662  else{
663  val=pow((double)(b-x),2)/((b-a)*(b-c));
664  dist.push_back(val);
665  }
666  }
667  return;
668  }
669 
670 
671 
672 
673  //User defined distribution - Converts pdf to survival distrib.
674  void sUser (std::vector<double>&dist, std::vector<double> &prob_dist){
675  double c_df=0;
676  //calculate CDF
677  for(int i=0;i<prob_dist.size();i++){
678  c_df+=prob_dist[i];
679  dist.push_back(c_df);
680  }
681  //Convert CDF to survival function
682  for(int i=0; i<dist.size();i++){
683  dist[i]=1-dist[i];
684  }
685  return;
686  }
687 
688  //Weibull-Survival distribution
689  void sWeibull(std::vector<double> &dist,double shape, double scale){
690  //http://en.wikipedia.org/wiki/Weibull_distribution
691  for (int i=0; i<maximum;i++){
692  double val=exp(-1*pow(i/scale,shape));
693  if (val==0){
694  break;
695  }
696  else{
697  dist.push_back(val);
698  }
699  }
700  return;
701  }
702 };
703 
704 
705