DSP-LinPred
view release on metacpan or search on metacpan
lib/DSP/LinPred.pm view on Meta::CPAN
}
if(defined($conf->{iir_a})){
$self->iir_a($conf->{iir_a});
}else{
$self->iir_a(1 / $conf->{filter_length})
}
}
if(defined($conf->{dc_mode})){
$self->dc_mode($conf->{dc_mode});
}
if(defined($conf->{dc_init})){
$self->dc($conf->{dc_init});
$self->dc_init($conf->{dc_init});
}
if(defined($conf->{stddev_mode})){
$self->stddev_mode($conf->{stddev_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(1 .. $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);
}
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->dc_mode == 1){
if($self->iir_mode == 1){
$self->dc_update_iir($x->[$kx]);
}else{
$self->dc_update;
}
}
if($self->stddev_mode == 1){
if($self->iir_mode == 1){
$self->stddev_update_iir($x->[$kx]);
}else{
$self->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->stddev_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_update{
my $self = shift;
my $x_stack = $self->x_stack;
my $mean = 0;
my $num = $#$x_stack + 1;
for(0 .. $#$x_stack){
$mean += $x_stack->[$_];
( run in 3.192 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )