File Coverage

blib/lib/DSP/LinPred_XS.pm
Criterion Covered Total %
statement 62 96 64.5
branch 7 16 43.7
condition 8 9 88.8
subroutine 7 10 70.0
pod 5 7 71.4
total 89 138 64.4


line stmt bran cond sub pod time code
1             package DSP::LinPred_XS;
2 2     2   26632 use 5.008005;
  2         7  
  2         76  
3 2     2   1714 use Mouse;
  2         68289  
  2         13  
4             our $VERSION = "0.02";
5 2     2   1147 use XSLoader;
  2         5  
  2         2191  
6             XSLoader::load(__PACKAGE__, $VERSION);
7              
8              
9              
10              
11             has 'mu' => (
12             is => 'rw',
13             isa => 'Num',
14             default => 0.001
15             );
16             has 'mu_mode' => (
17             is => 'rw',
18             isa => 'Int',
19             default => 0
20             );
21             has 'h_length' => (
22             is => 'rw',
23             isa => 'Int',
24             default => 100
25             );
26             has 'h' => (
27             is => 'rw',
28             isa => 'ArrayRef[Num]',
29             default => sub{[(0) x 100]}
30             );
31             has 'x_stack' => (
32             is => 'rw',
33             isa => 'ArrayRef[Num]',
34             default => sub{[(0) x 100]}
35             );
36             has 'x_count' => (
37             is => 'rw',
38             isa => 'Int',
39             default => 0
40             );
41             has 'current_error' => (
42             is => 'rw',
43             isa => 'Num',
44             default => 0
45             );
46             has 'dc' => (
47             is => 'rw',
48             isa => 'Num',
49             default => 0
50             );
51             has 'dc_init' => (
52             is => 'rw',
53             isa => 'Num',
54             default => 0
55             );
56             has 'stddev' => (
57             is => 'rw',
58             isa => 'Num',
59             default => 0
60             );
61             has 'stddev_init' => (
62             is => 'rw',
63             isa => 'Num',
64             default => 1
65             );
66             has 'est_mode' => (
67             is => 'rw',
68             isa => 'Num',
69             default => 1
70             );
71              
72              
73             # filter specification
74             # mu : step size
75             # h_length : filter size
76             sub set_filter{
77 1     1 1 8 my $self = shift;
78 1         2 my $conf = shift;
79 1 50       5 if(defined($conf->{filter_length})){
80 0         0 $self->h_length($conf->{filter_length});
81 0         0 $self->h([(0) x $conf->{filter_length}]);
82 0 0       0 if(defined($conf->{dc_init})){
83 0         0 $self->x_stack([($conf->{dc_init}) x $conf->{filter_length}]);
84             }else{
85 0         0 $self->x_stack([(0) x $conf->{filter_length}]);
86             }
87             }
88 1 50       5 if(defined($conf->{dc_init})){
89 0         0 $self->dc($conf->{dc_init});
90 0         0 $self->dc_init($conf->{dc_init});
91             }
92 1 50       7 if(defined($conf->{est_mode})){
93 0         0 $self->est_mode($conf->{est_mode});
94             }
95 1 50       7 if(defined($conf->{stddev_init})){
96 0         0 $self->stddev($conf->{stddev_init});
97 0         0 $self->stddev_init($conf->{stddev_init});
98             }
99             }
100              
101             # reset filter state
102             sub reset_state{
103 0     0 0 0 my $self = shift;
104 0         0 my $h_length = $self->h_length;
105 0         0 $self->h([(0) x $h_length]);
106 0         0 $self->x_stack([($self->dc_init) x $h_length]);
107 0         0 $self->current_error(0);
108 0         0 $self->dc($self->dc_init);
109 0         0 $self->x_count(0);
110 0         0 $self->stddev($self->stddev_init);
111             }
112              
113             # prediction only
114             # predict_num : number of output predicted values
115             # this method returns list reference of predicted values
116             sub predict{
117 1     1 1 12 my $self = shift;
118 1         3 my $predict_num = shift;
119 1         3 my $h = $self->h;
120 1         4 my $x_stack = $self->x_stack;
121 1         2 my $estimated;
122 1         4 for(1 .. $predict_num){
123 5         6 my $x_est = 0;
124 5   66     8 for( my $k = 0; $k <= $#{$h} and $k <= $self->x_count; $k++){
  505         2731  
125 500         1117 $x_est += $h->[$k] * ($x_stack->[$k] - $self->dc);
126             }
127 5         12 $x_est += $self->dc;
128 5         11 unshift(@$x_stack,$x_est);
129 5         10 push(@$estimated,$x_est);
130 5         15 pop(@$x_stack);
131             }
132 1         7 return($estimated);
133             }
134              
135             # update only
136             # x should be array reference
137              
138             sub update{
139 1     1 1 6 my $self = shift;
140 1         2 my $x = shift;
141 1         5 my $h_length = $self->h_length;
142 1         4 my $h = $self->h;
143 1         3 my $x_stack = $self->x_stack;
144              
145 1         2 for ( my $kx=0; $kx <= $#{$x}; $kx++){
  4001         10075  
146 4000         8105 unshift(@$x_stack,$x->[$kx]);
147 4000         4286 pop(@$x_stack);
148 4000         14735 $self->x_count($self->x_count + 1);
149 4000 50       12305 if($self->est_mode == 1){
150 4000         12680 $self->dc_stddev_update;
151             }
152 4000         4871 my $x_est = 0;
153 4000   100     5139 for( my $k = 0; $k <= $#{$h} and $k <= $self->x_count;$k++){
  399149         1863468  
154 395149         956824 $x_est += $h->[$k] * ($x_stack->[$k] - $self->dc);
155             }
156 4000         9759 my $error = $x->[$kx] - ($x_est + $self->dc);
157 4000         8359 $self->current_error($error);
158 4000         4743 my $h_new = $h;
159 4000         4218 my $tmp_coef = 1;
160 4000 50       10902 if($self->est_mode == 1){
161 4000         11815 $tmp_coef = $self->mu * $error / (1 + $self->stddev);
162             }else{
163 0         0 $tmp_coef = $self->mu * $error;
164             }
165 4000 50       10830 if($self->mu_mode == 1){
166 0         0 $tmp_coef = 10 * $self->mu / (1 + $self->h_length);
167             }
168              
169 4000   100     5490 for(my $k = 0;$k <= $#{$h} and $k <= $self->x_count; $k++){
  399149         1988557  
170 395149         1018290 $h_new->[$k] =
171             $h->[$k]
172             + $tmp_coef * ($x_stack->[$k] - $self->dc);
173             }
174 4000         31310 $self->h($h_new);
175             }
176             }
177              
178             ## DC component calculation and update
179             # using x_stack
180              
181             sub dc_stddev_update{
182 4000     4000 0 5640 my $self = shift;
183 4000         7521 my $x_stack = $self->x_stack;
184 4000         23385 my ($sum,$mean,$variance,$stddev) = &get_stat($x_stack);
185 4000         9554 $self->dc($mean);
186 4000         11289 $self->stddev($stddev);
187             }
188              
189              
190             ## calculation of mean value of filter
191             sub filter_dc{
192 0     0 1   my $self = shift;
193 0           my $h = $self->h;
194 0           my $mean = 0;
195 0           my $num = $#$h + 1;
196 0           for(0 .. $#$h){
197 0           $mean += $h->[$_];
198             }
199 0           return($mean / $num);
200             }
201              
202             ## calculation of stddev of filter
203             sub filter_stddev{
204 0     0 1   my $self = shift;
205 0           my $h = $self->h;
206 0           my $variance = 0;
207 0           my $num = $#$h + 1;
208 0           for(0 .. $#$h){
209 0           $variance += ($h->[$_])**2;
210             }
211 0           return(sqrt($variance / $num));
212             }
213              
214              
215              
216             1;
217             __END__