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 )