Algorithm-LibLinear

 view release on metacpan or  search on metacpan

lib/Algorithm/LibLinear/FeatureScaling.pm  view on Meta::CPAN

package Algorithm::LibLinear::FeatureScaling;

use 5.014;
use Algorithm::LibLinear::Types qw/Feature FeatureWithLabel/;
use Carp qw//;
use List::MoreUtils qw/minmax none/;
use List::Util qw/max/;
use Smart::Args::TypeTiny;
use Types::Standard qw/ArrayRef ClassName FileHandle InstanceOf Num Str/;

my $InstanceOfPackage = InstanceOf[__PACKAGE__];

sub new {
    args
        my $class => ClassName,
        my $data_set => +{
            isa => InstanceOf['Algorithm::LibLinear::DataSet'],
            optional => 1,
        },
        my $lower_bound => +{ isa => Num, default => 0, },
        my $min_max_values => +{
            isa => ArrayRef[ArrayRef[Num]],
            optional => 1,
        },
        my $upper_bound => +{ isa => Num, default => 1.0, };

    unless ($data_set or $min_max_values) {
        Carp::croak('Neither "data_set" nor "min_max_values" is specified.');
    }

    my $self = bless +{
        lower_bound => $lower_bound,
        upper_bound => $upper_bound,
    } => $class;

    $self->{min_max_values} = $min_max_values
        // $self->compute_min_max_values(data_set => $data_set);

    return $self;
}

sub load {
    args
        my $class => ClassName,
        my $fh => +{ isa => FileHandle, optional => 1, },
        my $filename => +{ isa => Str, optional => 1, },
        my $string => +{ isa => Str, optional => 1, };

    if (none { defined } ($filename, $fh, $string)) {
        Carp::croak('No source specified.');
    }
    my $source = $fh;
    $source //= do {
        open $fh, '<', +($filename // \$string) or Carp::croak($!);
        $fh;
    };

    chomp(my $header = <$source>);
    Carp::croak('At present, y-scaling is not supported.') if $header eq 'y';
    Carp::croak('Invalid format.') if $header ne 'x';

    chomp(my $bounds = <$source>);
    my ($lower_bound, $upper_bound) = split /\s+/, $bounds;

    my @min_max_values;
    while (defined(my $min_max_values = <$source>)) {
        chomp $min_max_values;
        my (undef, $min, $max) = split /\s+/, $min_max_values;
        push @min_max_values, [ $min, $max ];
    }

    $class->new(
        lower_bound => $lower_bound,
        min_max_values => \@min_max_values,
        upper_bound => $upper_bound,
    );
}

sub as_string {
    args
        my $self => $InstanceOfPackage;

    my $acc =
        sprintf "x\n%.17g %.17g\n", $self->lower_bound, $self->upper_bound;
    my $index = 0;
    for my $min_max_value (@{ $self->min_max_values }) {
        $acc .= sprintf "\%d %.17g %.17g\n", ++$index, @$min_max_value;
    }
    return $acc;
}



( run in 1.509 second using v1.01-cache-2.11-cpan-524268b4103 )