studentt.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. var cephes = require('cephes');
  2. function StudenttDistribution(df) {
  3. if (!(this instanceof StudenttDistribution)) {
  4. return new StudenttDistribution(df);
  5. }
  6. if (typeof df !== 'number') {
  7. throw TypeError('mean must be a number');
  8. }
  9. if (df <= 0) {
  10. throw RangeError('df must be a positive number');
  11. }
  12. this._df = df;
  13. this._pdf_const = Math.exp(cephes.lgam((df + 1) / 2) - cephes.lgam(df / 2)) / Math.sqrt(this._df * Math.PI);
  14. }
  15. module.exports = StudenttDistribution;
  16. StudenttDistribution.prototype.pdf = function (x) {
  17. return this._pdf_const / Math.pow(1 + ((x*x) / this._df), (this._df + 1) / 2);
  18. };
  19. // Uses the idendenity specified in Abramowitz and Stegun 26.7.1 and
  20. // Abramowitz and Stegun 26.5.27.
  21. // F(x|df) = 1 - 0.5 * I_z (df/2, 1/2)
  22. // z = df / (df + x^2)
  23. // for x > 0
  24. // Since the Student-t distribution is symetric:
  25. // F(x|df) = 0.5 * I_z (df/2, 1/2)
  26. // for x < 0
  27. StudenttDistribution.prototype.cdf = function (x) {
  28. const z = this._df / (this._df + x * x);
  29. const p = 0.5 * cephes.incbet(0.5 * this._df, 0.5, z);
  30. return (x <= 0) ? p : 1 - p;
  31. };
  32. StudenttDistribution.prototype.inv = function (p) {
  33. if (p <= 0) return -Infinity;
  34. if (p >= 1) return Infinity;
  35. if (p === 0.5) return 0;
  36. if (p > 0.25 && p < 0.75) {
  37. const phat = 1 - 2 * p;
  38. const z = cephes.incbi(0.5, 0.5 * this._df, Math.abs(phat));
  39. const t = Math.sqrt(this._df * z / (1 - z));
  40. return (p < 0.5) ? -t : t;
  41. } else {
  42. const phat = (p >= 0.5) ? 1 - p : p;
  43. const z = cephes.incbi(0.5 * this._df, 0.5, 2 * phat);
  44. const t = Math.sqrt(this._df / z - this._df);
  45. return (p < 0.5) ? -t : t;
  46. }
  47. };
  48. StudenttDistribution.prototype.median = function () {
  49. return 0;
  50. };
  51. StudenttDistribution.prototype.mean = function () {
  52. return (this._df > 1) ? 0 : undefined;
  53. };
  54. StudenttDistribution.prototype.variance = function () {
  55. if (this._df > 2) return this._df / (this._df - 2);
  56. else if (this._df > 1) return Infinity;
  57. else return undefined;
  58. };