Statistics-Sampler-Multinomial

 view release on metacpan or  search on metacpan

lib/Statistics/Sampler/Multinomial.pm  view on Meta::CPAN

package Statistics::Sampler::Multinomial;

use 5.014;
use warnings;
use strict;

our $VERSION = '1.02';

use Carp;
use Ref::Util qw /is_arrayref/;
use List::Util qw /min sum/;
use List::MoreUtils qw /first_index/;
use Scalar::Util qw /blessed looks_like_number/;
#use parent qw/Clone/;
use Clone ();

sub new {
    my ($class, %args) = @_;
    
    my $data = $args{data};
    croak 'data argument not passed'
      if !defined $data;
    croak 'data argument is not an array ref'
      if !is_arrayref ($data);
    croak 'data argument is an empty array'
      if !scalar @$data;

    my $first_neg_idx = first_index {($_ // 0) < 0} @$data;
    croak "negative values passed in data array ($data->[$first_neg_idx] at index $first_neg_idx)\n"
      if $first_neg_idx >= 0;
    

    my $self = {
        data => $data,
        data_sum_to_one => $args{data_sum_to_one},
    };

    bless $self, $class;

    my $prng = $args{prng};
    $self->_validate_prng_object ($prng);
    $self->{prng}
      =  $prng
      // "${class}::DefaultPRNG"->new;

    return $self;
}

sub _clone_inner {
    my $self = shift;
    my $clone = bless {}, blessed $self;
    $clone->{data} = [@{$self->{data}}];
    $clone->{sum}  = $self->{sum} if exists $self->{sum};
    $clone->{data_sum_to_one} = $self->{data_sum_to_one}
      if exists $self->{data_sum_to_one};
    return $clone;
}

sub clone {
    my $self = shift;
    my $clone;
    
    if ($self->{prng}->can('clone')) {
        $clone = do {
            delete local $self->{prng};
            $self->_clone_inner;
        };
        $clone->{prng} = $self->{prng}->clone;
    }
    else {



( run in 1.166 second using v1.01-cache-2.11-cpan-39bf76dae61 )