### ----------------------------------------------------
### -- Math::Libgsl::RandomDistribution
### -- Licenses: Artistic-2.0
### -- Authors: Fernando Santagata
### -- File: lib/Math/Libgsl/RandomDistribution.rakumod
### ----------------------------------------------------
### -- Chunk 3 of 3
�) for the multinomial distribution with parameters p[K].

=head3 negative-binomial(Math::Libgsl::Random $r, Num() $p, Num() $n --> UInt)

This function returns a random integer from the negative binomial distribution.

=head3 negative-binomial-pdf(UInt $k, Num() $p, Num() $n --> Num)

This function computes the probability p(k) of obtaining $k from a negative binomial distribution with parameters $p and $n.

=head3 negative-binomial-P(UInt $k, Num() $p, Num() $n --> Num)
=head3 negative-binomial-Q(UInt $k, Num() $p, Num() $n --> Num)

These functions compute the cumulative distribution functions P(k), Q(k) for the negative binomial distribution with parameters $p and $n.

=head3 pascal(Math::Libgsl::Random $r, Num() $p, UInt $n --> UInt)

This function returns a random integer from the Pascal distribution.

=head3 pascal-pdf(UInt $k, Num() $p, UInt $n --> Num)

This function computes the probability p(k) of obtaining $k from a Pascal distribution with parameters $p and $n.

=head3 pascal-P(UInt $k, Num() $p, UInt $n --> Num)
=head3 pascal-Q(UInt $k, Num() $p, UInt $n --> Num)

These functions compute the cumulative distribution functions P(k), Q(k) for the Pascal distribution with parameters $p and $n.

=head3 geometric(Math::Libgsl::Random $r, Num() $p --> UInt)

This function returns a random integer from the geometric distribution, the number of independent trials with probability $p until the first success.

=head3 geometric-pdf(UInt $k where * ≥ 1, Num() $p --> Num)

This function computes the probability p(k) of obtaining $k from a geometric distribution with probability parameter $p.

=head3 geometric-P(UInt $k where * ≥ 1, Num() $p --> Num)
=head3 geometric-Q(UInt $k where * ≥ 1, Num() $p --> Num)

These functions compute the cumulative distribution functions P(k), Q(k) for the geometric distribution with parameter $p.

=head3 hypergeometric(Math::Libgsl::Random $r, UInt $n1, UInt $n2, UInt $t --> UInt)

This function returns a random integer from the hypergeometric distribution.

=head3 hypergeometric-pdf(UInt $k, UInt $n1, UInt $n2, UInt $t --> Num)

This function computes the probability p(k) of obtaining $k from a hypergeometric distribution with parameters $n1, $n2, $t.

=head3 hypergeometric-P(UInt $k, UInt $n1, UInt $n2, UInt $t --> Num)
=head3 hypergeometric-Q(UInt $k, UInt $n1, UInt $n2, UInt $t --> Num)

These functions compute the cumulative distribution functions P(k), Q(k) for the hypergeometric distribution with parameters $n1, $n2 and $t.

=head3 logarithmic(Math::Libgsl::Random $r, Num() $p --> UInt)

This function returns a random integer from the logarithmic distribution.

=head3 logarithmic-pdf(UInt $k where * ≥ 1, Num() $p --> Num)

This function computes the probability p(k) of obtaining $k from a logarithmic distribution with probability parameter $p.

=head3 wishart(Math::Libgsl::Random $r, Num() $n, Math::Libgsl::Matrix $L where { $L.matrix.size1 == $L.matrix.size2 && $n ≤ $L.matrix.size1 - 1 } --> Math::Libgsl::Matrix)

This function returns a random symmetric p-by-p matrix from the Wishart distribution as a Math::Libgsl::Matrix object.

=head3 wishart-pdf(Math::Libgsl::Matrix $X where { $X.matrix.size1 == $X.matrix.size2 }, Math::Libgsl::Matrix $L-X where { $L-X.matrix.size1 == $L-X.matrix.size2 }, Num() $n where * > $X.matrix.size1 - 1, Math::Libgsl::Matrix $L where { $L.matrix.size1 == $L.matrix.size2 && $X.matrix.size1 == $L.matrix.size1 && $L-X.matrix.size1 == $L.matrix.size1 } --> Num)
=head3 wishart-log-pdf(Math::Libgsl::Matrix $X where { $X.matrix.size1 == $X.matrix.size2 }, Math::Libgsl::Matrix $L-X where { $L-X.matrix.size1 == $L-X.matrix.size2 }, Num() $n where * > $X.matrix.size1 - 1, Math::Libgsl::Matrix $L where { $L.matrix.size1 == $L.matrix.size2 && $X.matrix.size1 == $L.matrix.size1 && $L-X.matrix.size1 == $L.matrix.size1 } --> Num)

These functions return p(X) or log p(X) for the p-by-p matrix $X, whose Cholesky factor is specified in $L-X.
The degrees of freedom is given by $n, the Cholesky factor of the scale matrix V is specified in $L.

=head3 shuffle(Math::Libgsl::Random $r, @base --> List)

This function randomly shuffles the order of the elements of the array @base and returns them as a List.

=head3 choose(Math::Libgsl::Random $r, Int $k, @src where *.elems ≥ $k --> List)

This function returns the list of $k objects taken randomly from the elements of the array @src.

=head3 sample(Math::Libgsl::Random $r, Int $k, @src --> List)

This function is like choose() but samples $k items from the original array of n items @src with replacement, so the same object can appear more than once in the output.

=head2 Class Math::Libgsl::RandomDistribution::Discrete

This probability distribution needs a lookup table for the discrete random number generator, so it's implemented as a class, which hides the implementation details.

=begin code :lang<raku>

use Math::Libgsl::RandomDistribution;
use Math::Libgsl::Random;

my Int $size = 3;
my @probability = .59, .4, .01;
my Math::Libgsl::Random $r .= new;
my Math::Libgsl::RandomDistribution::Discrete $d .= new: :$size, :@probability;

say "Using probability values: { $d.probability }";
say $d.discrete($r) for ^10;

say $d.discrete-pdf(2);

=end code

=head3 new(Int() :$size, :@probability where *.all > 0)

Creates the lookup table for the discrete random number generator. The array @probability contains the probabilities of the discrete events.

=head3 discrete(Math::Libgsl::Random $r --> Int)

This method returns one discrete random number.

=head3 discrete-pdf(Int $k --> Num)

This method returns the probability P[k] of observing the variable $k.

=head1 C Library Documentation

For more details on libgsl see L<https://www.gnu.org/software/gsl/>.
The excellent C Library manual is available here L<https://www.gnu.org/software/gsl/doc/html/index.html>, or here L<https://www.gnu.org/software/gsl/doc/latex/gsl-ref.pdf> in PDF format.

=head1 Prerequisites

This module requires the libgsl library to be installed. Please follow the instructions below based on your platform:

=head2 Debian Linux and Ubuntu 20.04+

=begin code
sudo apt install libgsl23 libgsl-dev libgslcblas0
=end code

That command will install libgslcblas0 as well, since it's used by the GSL.

=head2 Ubuntu 18.04

libgsl23 and libgslcblas0 have a missing symbol on Ubuntu 18.04.
I solved the issue installing the Debian Buster version of those three libraries:

=item L<http://http.us.debian.org/debian/pool/main/g/gsl/libgslcblas0_2.5+dfsg-6_amd64.deb>
=item L<http://http.us.debian.org/debian/pool/main/g/gsl/libgsl23_2.5+dfsg-6_amd64.deb>
=item L<http://http.us.debian.org/debian/pool/main/g/gsl/libgsl-dev_2.5+dfsg-6_amd64.deb>

=head1 Installation

To install it using zef (a module management tool):

=begin code
$ zef install Math::Libgsl::RandomDistribution
=end code

=head1 AUTHOR

Fernando Santagata <nando.santagata@gmail.com>

=head1 COPYRIGHT AND LICENSE

Copyright 2020 Fernando Santagata

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.

=end pod


