File: GSL_RNG.pm

package info (click to toggle)
libpdl-gsl-perl 2.101-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 600 kB
  • sloc: perl: 1,587; ansic: 202; makefile: 9
file content (112 lines) | stat: -rw-r--r-- 3,340 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package PDL::Demos::GSL_RNG;

sub info {('gsl_rng', 'GSL randomness functions (Req.: PDL::Graphics::Simple)')}

my @demo = (
[act => q|
# This demo illustrates the PDL::GSL::RNG module.
# It shows the power of PDL with a concise way to generate graphs of
# different random number distributions.
use PDL::Graphics::Simple;
use PDL::GSL::RNG;
$x = zeroes(100)->xlinvals(-5,5);
$w = pgswin();
# Exponential Power Distribution
$w->plot(
  with=>'lines', key=>'a=1 b=2.5', $x, ran_exppow_pdf($x, 1, 2.5),
  with=>'lines', key=>'a=1 b=0.5', $x, ran_exppow_pdf($x, 1, 0.5),
  {le=>'tr', yrange=>[0,0.8], title=>'Exponential Power Distribution',
    xlabel=>'x', ylabel=>'p(x)'}
);
|],

[act => q|
# Cauchy Distribution
$w->plot(
  with=>'lines', key=>'a=1', $x, ran_cauchy_pdf($x, 1),
  with=>'lines', key=>'a=2', $x, ran_cauchy_pdf($x, 2),
  {le=>'tr', yrange=>[0,0.4], title=>'Cauchy Distribution',
    xlabel=>'x', ylabel=>'p(x)'}
);
|],

[act => q|
# Rayleigh Tail Distribution
$x = zeroes(100)->xlinvals(0,5);
$w->plot(
  with=>'lines', key=>'a=1 sigma=1', $x, ran_rayleigh_tail_pdf($x, 1, 1),
  with=>'lines', key=>'a=0.5 sigma=2', $x, ran_rayleigh_tail_pdf($x, 0.5, 2),
  {le=>'tr', yrange=>[0,1.1], title=>'Rayleigh Tail Distribution',
    xlabel=>'x', ylabel=>'p(x)'}
);
|],

[act => q|
# Gamma Distribution
$x = zeroes(100)->xlinvals(0,5);
$w->plot(
  with=>'lines', key=>'a=1 b=1', $x, ran_gamma_pdf($x, 1, 1),
  with=>'lines', key=>'a=2 b=1', $x, ran_gamma_pdf($x, 2, 1),
  with=>'lines', key=>'a=3 b=1', $x, ran_gamma_pdf($x, 3, 1),
  {le=>'tr', yrange=>[0,1], title=>'Gamma Distribution',
    xlabel=>'x', ylabel=>'p(x)'}
);
|],

[act => q|
# Bivariate Gaussian Distribution
# inspired by https://www.perlmonks.org/?node_id=11104262
$points = pdl '[219 88 2.7; 38 95 1.7; 45 268 0.8]';
($XSIZE, $YSIZE) = (300, 300);
($xcoord, $ycoord, $weight) = $points       # xyw nweights
  ->slice(",*$XSIZE,*$YSIZE,")              # xyw nx ny nweights
  ->using(0..2);                            # nx ny nweights
$xbase = xvals($XSIZE)->slice(",*$YSIZE");  # nx ny
$ybase = xvals($YSIZE)->slice("*$XSIZE,");  # nx ny
for (1..90) {
  $h = (
    $weight * ran_bivariate_gaussian_pdf(
      $xcoord-$xbase, $ycoord-$ybase, $_, $_, 0
    )                                           # nx ny nweights
  )->mv(-1,0)->sumover;                         # nx ny
  $w->plot(with=>'image', $h, {title=>'Bivariate Gaussian Distribution',j=>1});
}
|],

[act => q|
# Same, but with a colourful heatmap (if you have the right libraries)
sub as_heatmap {
  my ($d) = @_;
  my $max = $d->max;
  die "as_heatmap: can't work if max == 0" if $max == 0;
  $d /= $max; # negative OK
  my $hue   = (1 - $d)*240;
  $d = cat($hue, pdl(1), pdl(1));
  (hsv_to_rgb($d->mv(-1,0)) * 255)->byte->mv(0,-1);
}
if (eval 'use PDL::Graphics::ColorSpace; 1') {
  for (1..90) {
    $h = (
      $weight * ran_bivariate_gaussian_pdf(
        $xcoord-$xbase, $ycoord-$ybase, $_, $_, 0
      )                                           # nx ny nweights
    )->mv(-1,0)->sumover;                         # nx ny
    $w->plot(
      with=>'image', as_heatmap($h),
      {title=>'Bivariate Gaussian Distribution (heatmap)',j=>1}
    );
  }
}
|],

[comment => q|
See https://www.gnu.org/software/gsl/doc/html/randist.html for more.
|],
);

sub demo { @demo }
sub done {'
  undef $w;
'}

1;