无需安装Math模块的正态分布计算的累积密度函数

时间:2017-03-13 23:13:21

标签: perl module cdf

我想计算Perl中正态分布的累积密度函数。我正在使用 Math::Gauss 来自CPAN的模块,可以毫无问题地计算CDF。

ttt.pl

#!/usr/bin/perl 

use strict;
use warnings;

use Math::Gauss ':all';

my $x    = 0.1;
my $mean = 0;
my $std  = 0.1;

my $output = cdf($x, $mean, $std);

print $output;

但是,当我在不同的服务器中运行代码时,我遇到了模块安装问题,如下所示:

  

无法在@INC中找到Math / Gauss.pm(@INC包含:
  的/ etc / perl的
  /usr/local/lib/perl/5.14.2
  /usr/local/share/perl/5.14.2
  / usr / lib中/的perl5
  的/ usr /共享/的perl5
  /usr/lib/perl/5.14
  /usr/share/perl/5.14
  在/ usr / local / lib目录/ SITE_PERL
  。 )./ttt.pl第5行。
  BEGIN失败 - 编译在./ttt.pl第5行中止。

我没有root权限所以我需要在本地安装它,但我认为CDF计算不是一个很大的计算。 (CDF方程很简单。)

如果我知道在没有任何安装的情况下在Perl中计算CDF的方法会很棒。或者有没有办法在我的代码中包含Math/Gauss.pm,以便我可以在不安装的情况下使用它?

1 个答案:

答案 0 :(得分:2)

以下是基于Math::Gauss的模块。

# Copyright (C) 2011 by Philipp K. Janert
# No rights reserved by Eric L. Brine
#
# March 13th, 2017 - Eric Brine - Trimmed into light version of the module.
# 
# This library is free software; you can redistribute it and/or modify
# it under the same terms as Perl itself, either Perl version 5.10.1 or,
# at your option, any later version of Perl 5 you may have available.

package Math::GaussLite;

use strict;
use warnings;

use Carp;
use Exporter qw( import );

our @EXPORT_OK = qw( cdf );

my $SQRT2PI = 2.506628274631;

sub pdf {
  my ( $x, $m, $s ) = ( 0, 0, 1 );
  $x = shift if @_;
  $m = shift if @_;
  $s = shift if @_;

  if( $s <= 0 ) {
    croak( "Can't evaluate Math::Gauss:pdf for \$s=$s not strictly positive" );
  }

  my $z = ($x-$m)/$s;

  return exp(-0.5*$z*$z)/($SQRT2PI*$s);
}

sub cdf {
  my ( $x, $m, $s ) = ( 0, 0, 1 );
  $x = shift if @_;
  $m = shift if @_;
  $s = shift if @_;

  # Abramowitz & Stegun, 26.2.17
  # absolute error less than 7.5e-8 for all x

  if( $s <= 0 ) {
    croak( "Can't evaluate Math::Gauss:cdf for \$s=$s not strictly positive" );
  }

  my $z = ($x-$m)/$s;

  my $t = 1.0/(1.0 + 0.2316419*abs($z));
  my $y = $t*(0.319381530
          + $t*(-0.356563782
            + $t*(1.781477937
              + $t*(-1.821255978
                + $t*1.330274429 ))));
  if( $z > 0 ) {
    return 1.0 - pdf( $z )*$y;
  } else {
    return pdf( $z )*$y;
  }
}

1;

(老实说,由于这只是一个公式,版权并没有提供太多保护。)