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 )