# Could the t-Student distribution be included in the math module?

**URL:** <https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999>\
**Category:** Questions & Answers\
**Tags:** math\
**Created:** [July 3, 2024, 6:21pm UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999 "2024-07-03T18:21:56Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![encomer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/encomer/32/280_2.png) [@encomer](https://racket.discourse.group/u/encomer)\
**Post date:** [July 3, 2024, 6:21pm UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/1 "2024-07-03T18:21:56Z")

</div>

Hello _math module friends:_

Could it be possible to include some **functions for the t-Student distribution** in the math module?

_May be for the moment, starting with the centered version_.  
An example (very basic and possible limited) implementation of the `pdf`, `cdf` & ` inv-cdf` functions for the **centered t-Student** distribution is available at [oneg-t-student-en.rkt](https://onecompiler.com/racket/42j3n4wdn) .

Thank you and congratulations for your _great and very useful math package_.  
_Kind regards_,  
ECB  
P.S. The implementation of the **non-central t-Student distribution** , will be very welcome also, because of the many important applications that make use of it, in particular the computation of the power in hypothesis testing when the population variance is unknown. For more information on applications, you can explore the article by F.-W. Scholz entitled [Applications of the Noncentral t-Distribution](https://faculty.washington.edu/fscholz/Reports/nctnewrpt.pdf). _Thank you in advance for your support_.

---

<div class="post-metadata">

**Author:** ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)\
**Post date:** [July 3, 2024, 8:09pm UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/2 "2024-07-03T20:09:11Z")

</div>

A great question; I asked about it a month or two ago in Discord, and it seems like the building blocks are there but need put together. I’ve been meaning to try my hand at it but this is not a domain I have enough expertise to judge well.

---

<div class="post-metadata">

**Author:** ![encomer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/encomer/32/280_2.png) [@encomer](https://racket.discourse.group/u/encomer)\
**Post date:** [July 4, 2024, 9:04pm UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/3 "2024-07-04T21:04:24Z")

</div>

Thank you @benknoble for your comment. As it says in [https://github.com/racket/racket/wiki/Math-Library-Features](https://github.com/racket/racket/wiki/Math-Library-Features), for the case of `chisqr-dist`: "( **easy wrapper around gamma-dist** )". A similar comment (using the `beta` functions) can be made concerning the `F-dist`, and` t-dist`.

For example, my implementation of the `ts-dist` (for the `pdf` and `cdf`, respectively) in the file [oneg-t-student-en.rkt](https://onecompiler.com/racket/42j3n4wdn) just follows the equations (1) and (2) in the article by the **Idaho National Lab** : [Student t-distribution](https://mooseframework.inl.gov/source/distributions/StudentT.html). _The code is short, **thanks to the developers of the `math`** module, because_ it already includes the `beta` and `beta-inc` **special functions**. For the `inv-cdf` function, I just used the _[secant method](https://en.wikipedia.org/wiki/Secant_method)_ for finding the unique root of the required equation.

Concerning the validation of the computed values, we can use tables like the one at the [NIST](https://www.nist.gov/)'s [Engineering Statistics Handbook](https://www.itl.nist.gov/div898/handbook/index.htm) section [1.3.6.7.2. Critical Values of the Student's _t_ Distribution](https://www.itl.nist.gov/div898/handbook/eda/section3/eda3672.htm), or alternatively some other software packages.

_It feels good to do (effectively) this kind of computations in Racket_. I'm sure that including these classical distribution (and others) in the math module, will _increase considerable the academic (and may be, industrial) interest and use_ of the great Racket language.

_Kind regards_,  
ECB

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [July 5, 2024, 6:58am UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/4 "2024-07-05T06:58:16Z")

</div>

Take a look at my `t-test` package in pkgs; if yours is better, let me know and I'll replace it. Also, if there's something I can do to aid in discoverability, I'd be interested in that, too.

> **[t-test](https://pkgs.racket-lang.org/package/t-test)**
>
> Simple implementations of Welch's and Student's t-tests

---

<div class="post-metadata">

**Author:** ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)\
**Post date:** [July 5, 2024, 1:20pm UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/5 "2024-07-05T13:20:05Z")

</div>

> discoverability

@soegaard posted a version on Discord ([https://discord.com/channels/571040468092321801/1258477662813294763](https://discord.com/channels/571040468092321801/1258477662813294763)) that integrates directly with the math library, which is probably the ideal version of discoverable.

Short that, providing an extension of the math library (same name conventions, types, etc.,) would probably go a long way.

It now seems I'll have 3 implementations to try + Welch, so I'm at least grateful for all the effort folks have put into this.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [July 5, 2024, 2:08pm UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/6 "2024-07-05T14:08:43Z")

</div>

I have implemented `student-t-dist` for inclusion in `math/distributions`.

The calls `(student-t-dist μ)` and `(student-t-dist μ σ ν)` return  
an `ordered-distribution` representing a Student's t-distribution.

The parameters are as follows:

```scheme
    μ - location parameter
    σ - scale parameter
    ν - degrees of freedom

```

As with all distributions in the math library, you can use `pdf, cdf, inv-cdf` and `sample` on the distribution.

I would appreciate that someone besides me gave the implementation a test run.  
Before the inclusion in `math/distribution` the tests need to move.  
Until then, open one of the files in your editor, uncomment the test suite and run.

Clone the `student-t` branch from `soegaard/math` below.

The lowe-level functions are here:

> **[math/math-lib/math/private/distributions/impl at student-t · soegaard/math](https://github.com/soegaard/math/tree/student-t/math-lib/math/private/distributions/impl)**
>
> Contribute to soegaard/math development by creating an account on GitHub.

They are packed in a student-t-dist struct here:

> <https://github.com/soegaard/math/blob/student-t/math-lib/math/private/distributions/student-t-dist.rkt>

For now the flags `log?` and `1-p?` are ignored.  
Besides those everything is expected to work.

UPDATE

Now the flags `log?` and `1-p?` are implemented.

The idea behind `log?` is to work in log-space. That is, instead of returning `p` one computes `log(p)`. For small probabilities like `(pdf X 40) ~0.0` where X is normal distributed with mean 0 and sigma 1, the log-probability gives a little extra precision.

However, I do not know how to compute `log(p)` without computing `p` first.  
So for now, I simply compute p first and return `log(p)`.

UPDATE

I figured out to compute log(pdf(x)) directly without computing pdf(x) first.

Does anyone know how to compute log(cdf(x)) directly without computing cdf(x) first?

---

<div class="post-metadata">

**Author:** ![encomer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/encomer/32/280_2.png) [@encomer](https://racket.discourse.group/u/encomer)\
**Post date:** [July 5, 2024, 7:52pm UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/7 "2024-07-05T19:52:46Z")

</div>

Thank you @jbclements for your `t-test` package, and especially for the _illuminating comments at the start of its documentation_.

Also thank you @benknoble, for pointing to the work of @soegaard concerning the t-Student distribution. There is much to learn from his implementation.

I will try to follow @soegaard's proposal to test his functions, particularly: `pdf`, `cdf`, & `inv-cdf`, even though I don't have any previous experience cloning branches of code. BTW, it's amazing how much work is required to be able to enjoy all the functionality in the `math` module: _it is greatly appreciated_.

Best regards.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [July 5, 2024, 8:15pm UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/8 "2024-07-05T20:15:07Z")

</div>

Clone the whole repo. Then use `git checkout student-t` to switch to the student-t branch.

---

<div class="post-metadata">

**Author:** ![encomer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/encomer/32/280_2.png) [@encomer](https://racket.discourse.group/u/encomer)\
**Post date:** [July 7, 2024, 6:22am UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/9 "2024-07-07T06:22:48Z")

</div>

Thank you @soegaard for your advice concerning cloning your _t-student distribution_ implementation.

For the **computation** of **log(cdf(x))**, may be equation (9) in the following PDF document: [Some Inferential Problems from Log Student’s T-distribution and its Multivariate Extension](https://pdfs.semanticscholar.org/b869/2af2609ed3ab2cc4b417ded6be6417c8a0c8.pdf), can be helpful, as a reference.

Also, the paper: [Rethinking Generalized Beta Family of Distributions](https://arxiv.org/pdf/2209.05225), may be useful, because in the above document it says that: the _"log t distribution is a special case of the generalized beta distribution"_ (see paragraph just before equation (8)).

Concerning the testing of your implementation:

1. I verified that your testing functions in the files: `student-t-dist.rkt` and `impl/student-t.rkt` **all worked fine**. This for the case of the [**centered**] t-Student distribution.

2. For the case of **non-centered** t-Student distribution, that is _implied_ when using location parameter μ\<\>0, further testing may be needed. For example, we can compare the _Wolfram alpha_ command result of: PDF[NoncentralStudentTDistrib`ution[4,2],3.5] => 0.138586`, with the result of `((make-student-t-pdf 4 1 2) 3.5) => 0.2962962962962963`. Thank you @soegaard, for _verifying if I'm interpreting correctly the used parameters_.

If we concentrate in the [**centered**] _t-Student distribution_, in your code, **all indicates that it is ready**. _Thank you for all your work in this and also in other great packages_.

Kind regards.

P. S. As a reference, the file [oneg-noncentral-ts-dist-en.rkt](https://onecompiler.com/racket/42jef97uw), contains an experimental untyped Racket basic implementation of `pdf`, `cdf`, and` inv-cdf` for the non-central t-Student distribution.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [July 7, 2024, 9:16am UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/10 "2024-07-07T09:16:06Z")

</div>

> For the **computation** of **log(cdf(x))** , may be equation (9) in the following PDF document: [Some Inferential Problems from Log Student’s T-distribution and its Multivariate Extension](https://pdfs.semanticscholar.org/b869/2af2609ed3ab2cc4b417ded6be6417c8a0c8.pdf), can be helpful, as a reference.

Equation (9) is about the "Log Student’s T-distribution", so it is not applicable to computing the logarithm of the cdf for a standard T-distribution.

But I think, I have found the piece of the puzzle, I was missing.  
The formula for cdf(x) in Wikipedia and elsewhere are most often stated for x\>0.  
The expectation is that one can use `P(X≤x) = P(X≥-x) = 1 - P(X≤-x)` for negative x. However, since we are after `log(P(X≤x))` we get stuck with `log(1 - P(X≤-x))`.

Other sources such as "Sampling Student’s T distribution – use of the inverse cumulative distribution function" by William T. Shaw features this formula:

 ![image](https://global.discourse-cdn.com/free1/uploads/racket/original/2X/b/b0c1e4d6151f8f2378b035402178506d77a88d2c.png)

which shows how to get a formula for x\<0.

Asking `wolframscript` about the CDF for a StudentTDistribution, we get the same result as Shaw:

```scheme
In[339]:= CDF[StudentTDistribution[v], x]                          

                                        v v 1
                      BetaRegularized[------, -, -]
                                           2 2 2
                                      v + x
Out[339]= Piecewise[{{-----------------------------, x <= 0}}, 
                                    2
 
                            2
                           x 1 v
     1 + BetaRegularized[------, -, -]
                              2 2 2
                         v + x
> ---------------------------------]
                     2

```

So my plan is to use this formula - and the math library already contains a specialized function for computing logarithms to the beta function(s).

> Concerning the testing of your implementation:

> 1. I verified that your testing functions in the files: `student-t-dist.rkt` and `impl/student-t.rkt` **all worked fine**. This for the case of the [**centered**] t-Student distribution.

Thanks for testing the implementation.

> 1. For the case of **non-centered** t-Student distribution, that is _implied_ when using location parameter μ\<\>0, further testing may be needed. For example, we can compare the _Wolfram alpha_ command result of: PDF[NoncentralStudentTDistribution[4,2],3.5] =\> 0.138586`, with the result of `((make-student-t-pdf 4 1 2) 3.5) =\> 0.2962962962962963`. Thank you @soegaard, for _verifying if I'm interpreting correctly the used parameters_.

While implementing this I have been amazed of just how many different distributions are in use in statistics. The three argument version of `make-student-pdf` does not compute the noncentral Student T-distribution, but the so-called location-scale T-distribution. This matches how Mathematica interprets  
`StudentTDistribution[ν]` and `StudentTDistribution[μ,σ,ν]`.

```scheme
In[340]:= PDF[StudentTDistribution[4,1,2],3.5]                     

Out[340]= 0.296296

In[343]:= N[PDF[StudentTDistribution[4,1,2],35/10],30]             

Out[343]= 0.296296296296296296296296296296

```

Note the need to use 35/10 instead of 3.5 to get full precision.

> If we concentrate in the [**centered**] _t-Student distribution_ , in your code, **all indicates that it is ready**. _Thank you for all your work in this and also in other great packages_ .

Great news, I'll ping you when the logcdf functionality works.

> P. S. As a reference, the file [oneg-noncentral-ts-dist-en.rkt](https://onecompiler.com/racket/42jef97uw), contains an experimental untyped Racket basic implementation of `pdf` , `cdf` , and` inv-cdf` for the non-central t-Student distribution.

This is a very good start. You will need implementations of `logpdf` and `logcdf` too for this to work with `math/distributions`.

When everything works, I'll write up the process of implementing `student-t-dist` in Typed Racket for `math/distributions`. I'll likely implement a `chi-squared-dist` but I don't think I have energy to implement a `noncentral-student-t-dist` as well.

---

<div class="post-metadata">

**Author:** ![encomer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/encomer/32/280_2.png) [@encomer](https://racket.discourse.group/u/encomer)\
**Post date:** [July 8, 2024, 6:18pm UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/11 "2024-07-08T18:18:19Z")

</div>

Thank you @soegaard for clarifying the context of the equation (9) in the reference above. My apologies for the misinterpretation.

> [@soegaard](#):
>
> The expectation is that one can use `P(X≤x) = P(X≥-x) = 1 - P(X≤-x)` for negative x. However, since we are after `log(P(X≤x))` we get stuck with `log(1 - P(X≤-x))`.

Concerning expressions of the form `log(1-x)` it seems that the function `log1p(x)` (_already available in Racket_) where `log1p(x)=log(1+x)` can be use it in this context. That is:  
`log(1 - P(X≤-x))`=`log(1 + (-P(X≤-x)))`  
=`log1p(-P(X≤-x))`,  
where `-P(X≤-x)>-1`.  
(_Update_) I understand that the above function, is mainly used when we need to evaluate with high precision log(1-x), for very small values of x.

Thank you for calling our attention to the work of _William T. Shaw_ in this context. There is much to learn from: [Sampling Student's T distribution](https://www.homepages.ucl.ac.uk/~ucahwts/lgsnotes/JCF_Student.pdf) (e.g. 1st paragraph after eq'n (24), related to `inv-cdf`).

> [@soegaard](#):
>
> This is a very good start. You will need implementations of `logpdf` and `logcdf` too for this to work with `math/distributions`.

I appreciate very much your guidance and example to keep working in the implementation of `logpdf` and `logcdf` function, for the _noncentral t-Student_ case.

---

<div class="post-metadata">

**Author:** ![encomer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/encomer/32/280_2.png) [@encomer](https://racket.discourse.group/u/encomer)\
**Post date:** [July 9, 2024, 7:59pm UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/12 "2024-07-09T19:59:44Z")

</div>

Thank you @soegaard, for the previous technical information.  
About the logcdf() function for the **centered** _t-Student_, please (if possible) you can check the following code, in order to see if it is what is required:

```scheme
;; auxiliary function.
;; notice the selection of Re(x)
(define (log1p x)
  (fllog1p (real->double-flonum
            (real-part x))))

;; log(cdf(x)) for t-student
;; with ν degrees of freedom
(define (make-logcdf-ts ν)
  (λ(x)
    (define (Δlogsβ x) ; invariant with sgn(x)
      (- (log (beta-inc
               (/ ν 2)
               1/2
               (/ ν
                  (+ ν (sqr x)))))
         (log (beta
               (/ ν 2)
               1/2))))
    (cond
      ((< x 0)
       (+ (log 1/2)
          (Δlogsβ (- x))))
      ((= x 0.5)
       (log 0.5))
      (else
       (log1p
        (exp
         (+ (log -1/2) ;; complex
            (Δlogsβ x))))))))

```

I already tested with respect to `log(cdf(x))` and it (seems to) works fine.  
For example:

```scheme
((make-logcdf-ts 4) -10) ; => -8.177149442537441
(log (cdf-ts 4 -10)) ; => -8.177149442537285

```

The basic idea is that, for (x\>0), {B\_x=Beta(\frac{\nu}{2},\frac{1}{2},\frac{\nu}{\nu+x^2})} and {B=Beta(\frac{\nu}{2},\frac{1}{2})}, we have:  
{\mathsf{log} F(x;\nu)=\mathsf{log}(1+(-\frac{1}{2}\frac{B\_x}{B}))}  
{\mathsf{log} F(x;\nu)=\mathsf{log1p}(\mathsf{exp}(\mathsf{log}(-\frac{1}{2})+\mathsf{log} B\_{x} - \mathsf{log}B))}.  
For the case of (x\<0) we have simply:  
\mathsf{log} F(x;\nu)=\mathsf{log}(\frac{1}{2})+\mathsf{log} B\_{-x}-\log B.  
For (x=0) we have \mathsf{log} F(0;\nu)=\mathsf{log}(\frac{1}{2}).

_Notice that_ for the` log1p(x)` function to work properly in this case, _it was necessary_ **to take only the real part** of x.

_Kind regards_.

---

<div class="post-metadata">

**Author:** ![bdeket](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/bdeket/32/1835_2.png) [@bdeket](https://racket.discourse.group/u/bdeket)\
**Post date:** [July 11, 2024, 8:06am UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/13 "2024-07-11T08:06:28Z")

</div>

I checked out the current implementation of @soegaard's pdf for one parameter. I converted the `fl` implementation to a `bf` implementation to check fhe `flulp-error`:

 ![org1](https://global.discourse-cdn.com/free1/uploads/racket/original/2X/8/8f9cf8dd0924faf7cacb0d43583887549b48ab4d.png)  
Red: `flulp-error` \> 200; white: `flulp-error`\> 200 & result=0  
grey lines are at nu=1 & x=1

also near nu=1; x=1 (1e-3 - 1e3):

 ![org3](https://global.discourse-cdn.com/free1/uploads/racket/original/2X/1/100f5d26696ae5679addc5a197c26172c9da3031.png)

I managed to improve some things, mainly rearanging and using `flexpt+`:

 ![new1](https://global.discourse-cdn.com/free1/uploads/racket/original/2X/6/6c3e1e46dfe822ea0d2dbd8df9f13077cca1362d.png)  
 ![new3b](https://global.discourse-cdn.com/free1/uploads/racket/original/2X/6/69781646b276eeee83d362ef8c7429021aa1a88c.png)

The graphs need to be taken with a grain of salt, since I'm not 100% confident in my `bf` implementation, especially for large nu / x.

I also noticed that for `(beta 1/2 (/ nu 2))` the errors can become quite big when nu is an integer (observed 1000 ulp for nu \< 5000). Since this is probably the main use case (integer nu), maybe it is better to use the fct below, but probably using a table somewhere to speed things up:

```scheme
(: beta1/2 (-> Flonum Flonum))
(define (beta1/2 a)
  (if (and (< 1 a 10000) (integer? a))
      (if (fleven? a)
          (let ([a (- (exact-round a) 1)])
            (fl (* 2
                   (let lp : Real ([a : Integer a][c : Real 1])
                     (cond
                       [(< a 2) c]
                       [else (lp (- a 2) (* c (/ (- a 1) a)))])))))
          (let ([a (- (exact-round a) 1)])
            (fl (* pi
                   (let lp : Real ([a : Integer a][c : Real 1])
                     (cond
                       [(< a 2) c]
                       [else (lp (- a 2) (* c (/ (- a 1) a)))]))))))
      (beta 0.5 (/ a 2.))))

```

I don't know what is seen as acceptable accuracy for the distributions, so maybe this all is moot.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [July 11, 2024, 12:19pm UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/14 "2024-07-11T12:19:57Z")

</div>

Thanks for the tip wrt. `log1p` and for pointing out the section in Shaw about inverse CDF.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [July 11, 2024, 12:27pm UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/15 "2024-07-11T12:27:52Z")

</div>

@encomer Thanks for the code for `logcdf`.

We can use `fllog-beta-inc` and `fllog-beta` to compute `(log (beta-inc ...))`  
and `(log (beta ...))` respectively.

I wish there were a way to compute the case `x>0` without using `log1p` combined with `(exp ...)`. It just looks odd for me to see `(log1p (exp ...))`.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [July 11, 2024, 12:39pm UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/16 "2024-07-11T12:39:58Z")

</div>

@bdeket Great idea to compare with a big float implementation.

For small, integer nu there are exact formulas for the probability density [1].  
Should we try these?

> I don't know what is seen as acceptable accuracy for the distributions, so maybe this all is moot.

I think, we should use your version. Reducing the error as much as possible must be  
the right thing to do.

Will you make a PR to [GitHub - soegaard/math at student-t](https://github.com/soegaard/math/tree/student-t) ?

Do you have the big float version on your Github?

[1] From [Student's t-distribution - Wikipedia](https://en.wikipedia.org/wiki/Student%27s_t-distribution#Table_of_selected_values)

 ![image](https://global.discourse-cdn.com/free1/uploads/racket/original/2X/f/f3f327261c862d675100e149041021dcd4fb1a66.png)

UPDATE

I got ChatGPT to rewrite the formulas in the table to Racket-expressions.

```scheme
(define pdf-list
  (list
    ; ν = 1
    (/ 1 (* pi (+ 1 (expt t 2))))
    
    ; ν = 2
    (/ 1 (* 2 (sqrt 2) (expt (+ 1 (/ (expt t 2) 2)) (/ 3 2))))
    
    ; ν = 3
    (/ 2 (* pi (sqrt 3) (expt (+ 1 (/ (expt t 2) 3)) 2)))
    
    ; ν = 4
    (/ 3 (* 8 (expt (+ 1 (/ (expt t 2) 4)) (/ 5 2))))
    
    ; ν = 5
    (/ 8 (* 3 pi (sqrt 5) (expt (+ 1 (/ (expt t 2) 5)) 3)))
    
    ; ν = ∞
    (* (/ 1 (sqrt (* 2 pi))) (exp (/ (expt t 2) -2)))
  ))

```

and

```scheme
(define cdf-list
  (list
    ; ν = 1
    (+ (/ 1 2) (/ 1 pi) (atan t))
    
    ; ν = 2
    (+ (/ 1 2) (/ t (* 2 (sqrt 2) (sqrt (+ 1 (/ (expt t 2) 2))))))
    
    ; ν = 3
    (+ (/ 1 2) (/ 1 pi) (+ (/ (/ t (sqrt 3)) (+ 1 (/ (expt t 2) 3))) (atan (/ t (sqrt 3)))))
    
    ; ν = 4
    (+ (/ 1 2) (/ 3 8) (* (/ t (sqrt (+ 1 (/ (expt t 2) 4)))) (- 1 (/ (expt t 2) (* 12 (+ 1 (/ (expt t 2) 4)))))))
    
    ; ν = 5
    (+ (/ 1 2) (/ 1 pi) (+ (/ (/ t (sqrt 5)) (* (+ 1 (/ (expt t 2) 5)) (+ 1 (/ 2 (* 3 (+ 1 (/ (expt t 2) 5))))))) (atan (/ t (sqrt 5)))))
    
    ; ν = ∞
    (* (/ 1 2) (+ 1 (erf (/ t (sqrt 2)))))
  ))

```

---

<div class="post-metadata">

**Author:** ![bdeket](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/bdeket/32/1835_2.png) [@bdeket](https://racket.discourse.group/u/bdeket)\
**Post date:** [July 11, 2024, 5:02pm UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/17 "2024-07-11T17:02:30Z")

</div>

Hi @soegaard, I created a gist of the `bf` implementation: [bf-student-t · GitHub](https://gist.github.com/bdeket/d56c9c5aa886e0d16b900d8919e20efc)

for now I only seriously used the `make-pdf` so I don't know how well the other functions work.  
To be valid in the complete range of flonums `bf-precision` will be need set to at least 1024. This is especially true if nu \> 1e30

---

<div class="post-metadata">

**Author:** ![bdeket](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/bdeket/32/1835_2.png) [@bdeket](https://racket.discourse.group/u/bdeket)\
**Post date:** [July 26, 2024, 2:05pm UTC](https://racket.discourse.group/t/could-the-t-student-distribution-be-included-in-the-math-module/2999/18 "2024-07-26T14:05:53Z")

</div>

The gist above now includes more testing code. I was trying to also improve the cdf, and although my current version is a lot better (no early 0 in a lot of the flonum space) it still has a significant region near x=0.1~100 and nu=1~1e16 were improvements would be welcome:

 ![a99](https://global.discourse-cdn.com/free1/uploads/racket/original/2X/2/2392dc635cdbda009f11165b0be69c2fe43242bb.png)
