File Coverage

blib/lib/Algorithm/LBFGS.pm
Criterion Covered Total %
statement 31 34 91.1
branch 4 6 66.6
condition n/a
subroutine 8 10 80.0
pod 6 6 100.0
total 49 56 87.5


line stmt bran cond sub pod time code
1             package Algorithm::LBFGS;
2              
3 3     3   1272 use strict;
  3         5  
  3         111  
4 3     3   18 use warnings;
  3         6  
  3         91  
5              
6 3     3   12 use XSLoader;
  3         6  
  3         2239  
7              
8             our $VERSION = '0.16';
9             XSLoader::load('Algorithm::LBFGS', $VERSION);
10              
11             # constructor
12             sub new {
13 4     4 1 40 my $class = shift;
14 4         11 my %param = @_;
15 4         63 my $self = bless { param => create_lbfgs_param() }, $class;
16 4         27 $self->set_param(%param);
17 4         12 return $self;
18             }
19              
20             # destructor
21             sub DESTROY {
22 4     4   18 my $self = shift;
23 4         326 destroy_lbfgs_param($self->{param});
24             }
25              
26             # set parameters
27             sub set_param {
28 5     5 1 9 my $self = shift;
29 5         10 my %param = @_;
30 5         30 set_lbfgs_param($self->{param}, $_, $param{$_}) for keys %param;
31             }
32              
33             # get parameters
34             sub get_param {
35 12     12 1 27 my $self = shift;
36 12         16 my $name = shift;
37 12         72 return set_lbfgs_param($self->{param}, $name, undef);
38             }
39              
40             # verbose monitor
41             my $verbose_monitor = sub {
42             my ($x, $g, $fx, $xnorm, $gnorm, $step, $k, $ls, $user_data) = @_;
43             ($fx, $xnorm, $gnorm, $step) =
44             map { sprintf("%g", $_) } ($fx, $xnorm, $gnorm, $step);
45             my $hr = "=" x 79;
46             my $s = ":";
47             print <
48             Iteration $k
49             $hr
50             f(x) $s $fx
51             || x || $s $xnorm
52             || grad f(x) || $s $gnorm
53             line search step $s $step
54             evaluations num $s $ls
55              
56             MSG
57             return 0;
58             };
59              
60             # logging monitor
61             my $logging_monitor = sub {
62             my ($x, $g, $fx, $xnorm, $gnorm, $step, $k, $ls, $user_data) = @_;
63             push @$user_data, {
64             x => $x, g => $g, fx => $fx, xnorm => $xnorm, gnorm => $gnorm,
65             step => $step, k => $k, ls => $ls, user_data => $user_data
66             };
67             return 0;
68             };
69              
70             # do optimization
71             sub fmin {
72 4     4 1 81725 my $self = shift;
73 4         11 my ($lbfgs_eval, $x0, $lbfgs_prgr, $user_data) = @_;
74 4 100       16 if (defined($lbfgs_prgr)) {
75 1 50       5 $lbfgs_prgr = $verbose_monitor if ($lbfgs_prgr eq 'verbose');
76 1 50       10 $lbfgs_prgr = $logging_monitor if ($lbfgs_prgr eq 'logging');
77             }
78 4         18 my $instance =
79             create_lbfgs_instance($lbfgs_eval, $lbfgs_prgr, $user_data);
80 4         28036 $self->{status} = status_2pv(do_lbfgs($self->{param}, $instance, $x0));
81 4         1050969 destroy_lbfgs_instance($instance);
82 4         17 return $x0;
83             }
84              
85             # query status
86             sub get_status {
87 0     0 1   my $self = shift;
88 0           return $self->{status};
89             }
90              
91 0     0 1   sub status_ok { return get_status(@_) == 0; }
92              
93             1;
94              
95             __END__