DSP-LinPred_XS
view release on metacpan or search on metacpan
lib/DSP/LinPred_XS.pm view on Meta::CPAN
if(defined($conf->{filter_length})){
$self->h_length($conf->{filter_length});
$self->h([(0) x $conf->{filter_length}]);
if(defined($conf->{dc_init})){
$self->x_stack([($conf->{dc_init}) x $conf->{filter_length}]);
}else{
$self->x_stack([(0) x $conf->{filter_length}]);
}
}
if(defined($conf->{dc_init})){
$self->dc($conf->{dc_init});
$self->dc_init($conf->{dc_init});
}
if(defined($conf->{est_mode})){
$self->est_mode($conf->{est_mode});
}
if(defined($conf->{stddev_init})){
$self->stddev($conf->{stddev_init});
$self->stddev_init($conf->{stddev_init});
}
}
# reset filter state
sub reset_state{
my $self = shift;
my $h_length = $self->h_length;
$self->h([(0) x $h_length]);
$self->x_stack([($self->dc_init) x $h_length]);
$self->current_error(0);
$self->dc($self->dc_init);
$self->x_count(0);
$self->stddev($self->stddev_init);
}
# prediction only
# predict_num : number of output predicted values
# this method returns list reference of predicted values
sub predict{
my $self = shift;
my $predict_num = shift;
my $h = $self->h;
my $x_stack = $self->x_stack;
my $estimated;
for(0 .. $predict_num){
my $x_est = 0;
for( my $k = 0; $k <= $#{$h} and $k <= $self->x_count; $k++){
$x_est += $h->[$k] * ($x_stack->[$k] - $self->dc);
}
$x_est += $self->dc;
unshift(@$x_stack,$x_est);
push(@$estimated,$x_est);
pop(@$x_stack);
}
shift(@$estimated);
return($estimated);
}
# update only
# x should be array reference
sub update{
my $self = shift;
my $x = shift;
my $h_length = $self->h_length;
my $h = $self->h;
my $x_stack = $self->x_stack;
for ( my $kx=0; $kx <= $#{$x}; $kx++){
unshift(@$x_stack,$x->[$kx]);
pop(@$x_stack);
$self->x_count($self->x_count + 1);
if($self->est_mode == 1){
$self->dc_stddev_update;
}
my $x_est = 0;
for( my $k = 0; $k <= $#{$h} and $k <= $self->x_count;$k++){
$x_est += $h->[$k] * ($x_stack->[$k] - $self->dc);
}
my $error = $x->[$kx] - ($x_est + $self->dc);
$self->current_error($error);
my $h_new = $h;
my $tmp_coef = 1;
if($self->est_mode == 1){
$tmp_coef = $self->mu * $error / (1 + $self->stddev);
}else{
$tmp_coef = $self->mu * $error;
}
if($self->mu_mode == 1){
$tmp_coef = 10 * $self->mu / (1 + $self->h_length);
}
for(my $k = 0;$k <= $#{$h} and $k <= $self->x_count; $k++){
$h_new->[$k] =
$h->[$k]
+ $tmp_coef * ($x_stack->[$k] - $self->dc);
}
$self->h($h_new);
}
}
## DC component calculation and update
# using x_stack
sub dc_stddev_update{
my $self = shift;
my $x_stack = $self->x_stack;
my ($sum,$mean,$variance,$stddev) = &get_stat($x_stack);
$self->dc($mean);
$self->stddev($stddev);
}
## calculation of mean value of filter
sub filter_dc{
my $self = shift;
my $h = $self->h;
my $mean = 0;
my $num = $#$h + 1;
for(0 .. $#$h){
$mean += $h->[$_];
( run in 1.766 second using v1.01-cache-2.11-cpan-39bf76dae61 )