Algorithm-RandomPointGenerator

 view release on metacpan or  search on metacpan

lib/Algorithm/RandomPointGenerator.pm  view on Meta::CPAN

package Algorithm::RandomPointGenerator;

#---------------------------------------------------------------------------
# Copyright (c) 2014 Avinash Kak. All rights reserved.  This program is free
# software.  You may modify and/or distribute it under the same terms as Perl itself.
# This copyright notice must remain attached to the file.
#
# Algorithm::RandomPointGenerator generates a set of random points in a 2D plane
# according to a user-specified probability distribution that is supplied as a
# 2D histogram.
# ---------------------------------------------------------------------------

use 5.10.0;
use strict;
use Carp;
use List::Util qw/reduce/;
use Math::Random;        
use constant PI => 4 * atan2( 1, 1 );
use Math::Big qw/euler/; 
use File::Basename;
use Graphics::GnuplotIF;     

our $VERSION = '1.01';

# from perl docs:
my $_num_regex =  '^[+-]?\ *(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$'; 
# Useful for creating reproducible results:
random_seed_from_phrase('hellojello');

# Constructor:
sub new { 
    my ($class, %args) = @_;
    my @params = keys %args;
    croak "\nYou have used a wrong name for a keyword argument " .
          "--- perhaps a misspelling\n" 
          if check_for_illegal_params(@params) == 0;
    bless {
        _hist_file           =>   $args{input_histogram_file}    || croak("histogram file required"),
        _bbox_file           =>   $args{bounding_box_file}       || croak("bounding box file required"),
        _N                   =>   $args{number_of_points}               || 2000,
        _how_many_to_discard =>   $args{how_many_to_discard}            || 500,
        _debug               =>   $args{debug}                          || 0,
        _proposal_density_width    =>   $args{proposal_density_width}   || 0.1, 
        _y_axis_pos_direction      =>   $args{y_axis_pos_direction}     || "down",
        _output_hist_bins_along_x  =>   $args{output_hist_bins_along_x} || 40,
        _command_line_mode         =>   $args{command_line_mode}        || 0,
        _x_delta             =>   undef,
        _y_delta             =>   undef,
        _input_histogram     =>   undef,
        _output_histogram    =>   undef,
        _bounding_box        =>   undef,
        _generated_points    =>   undef,
        _normalized_input_hist => undef,
        _sigmax_for_proposal_density => undef,
        _sigmay_for_proposal_density => undef,
        _bin_width_for_output_hist   => undef,
        _bin_height_for_output_hist  => undef,
    }, $class;
}

# The file that contains a 2D histogram of the desired probability distribution for
# the random points must either be in the CSV or the white-space-separated
# format. Since we are working with 2D densities, each line of this text file should
# show one row of the histogram.  The subroutine creates an array of arrays from the
# information read from the file, which each inner row holding one row of the
# histogram.
sub read_histogram_file_for_desired_density {
    my $self = shift;
    my $filename = $self->{_hist_file};
    open FILEIN, $filename
        or die "unable to open file: $!";
    my @hist;
    while (<FILEIN>) {
        next if /^#/;
        next if /^\s*$/;
        chomp;
        my @line;
        if ($filename =~ /.csv$/) {
            @line =  map {$_ =~ s/^\s*|\s*$//; $_} split /,/, $_;
        } else {
            @line = split;
        }
        push @hist, \@line;
    }
    close FILEIN;
    if ($self->{_y_axis_pos_direction} eq "up") {
        my @newhist;
        foreach my $i (0..@hist-1) {
            push @newhist, $hist[scalar(@hist)-$i-1];
        }
        $self->{_input_histogram} = \@newhist; 
    } elsif ($self->{_y_axis_pos_direction} eq "down") {
        $self->{_input_histogram} = \@hist; 
    } else {
        die "Something is wrong with your value for the construction option 'y_xis_pos_direction'";
    }
}



( run in 0.563 second using v1.01-cache-2.11-cpan-4991d5b9bd9 )