summaryrefslogtreecommitdiff
path: root/macros/lpc.sci
diff options
context:
space:
mode:
Diffstat (limited to 'macros/lpc.sci')
-rw-r--r--macros/lpc.sci96
1 files changed, 57 insertions, 39 deletions
diff --git a/macros/lpc.sci b/macros/lpc.sci
index 02ab1a5..70c64be 100644
--- a/macros/lpc.sci
+++ b/macros/lpc.sci
@@ -9,35 +9,53 @@ function [a,g] = lpc(x,varargin)
//
// Description
// [a,g] = lpc(x,p)
- // Determines the coefficients of a pth order forward linear predictor
- // filter by minimizing the squared error. If p is unspecified, a
+ // Determines the coefficients of a pth order forward linear predictor
+ // filter by minimizing the squared error. If p is unspecified, a
// default value of length(x)-1 is used.
//
// Parameters
// x: double
- // The input signal. If x is a matrix, each column in treated as an
+ // The input signal. If x is a matrix, each column in treated as an
// independent computation
// p: int, natural number, scalar
// The order of the linear prediction filter to be inferred. Value must
- // be a scalar and a positive natural number. p must be less than or
+ // be a scalar and a positive natural number. p must be less than or
// equal to the length of the signal vector
// a: double
- // The coefficients of the forward linear predictor. Coefficient for
+ // The coefficients of the forward linear predictor. Coefficient for
// each signal input is returned as a row vector.
// g: double
// Column vector of averaged square prediction error
//
//
// Examples
- // 1)
- // noise = randn(20000,1);
- // x = filter(1,[1 1/5 1/3 1/4],noise);
- // x = x(15904:20000);
- // [a,g] = lpc(x,3);
+ //noise = rand(50000,1,"normal");
+ //x = filter(1,[1 1/2 1/3 1/4],noise);
+ //x = x(45904:50000);
+ //[a,g]= lpc(x,3)
+ //est_x = filter([0 -a(2:$)],1,x);
+ //e = x-est_x;
+ //[acs,lags] = xcorr(e,'coeff');
+ //plot(1:97,x(4001:4097),1:97,est_x(4001:4097),'--');
+ //a = gca();
+ //a.grid = [1,1];
+ //title 'Original Signal vs. LPC Estimate';
+ //xlabel 'Sample number', ylabel 'Amplitude';
+ //legend('Original signal','LPC estimate');
+
+ //Output :
+ // g =
+ //
+ // 1.0117019
+ // a =
+ //
+ // 1. 0.51533 0.3313039 0.2783268
+ //
+
//
//
// References
- // [1] Hayes, Monson H. Statistical digital signal processing and modeling.
+ // [1] Hayes, Monson H. Statistical digital signal processing and modeling.
// John Wiley & Sons, 2009, pg. 220
//
// See also
@@ -49,7 +67,7 @@ function [a,g] = lpc(x,varargin)
// ** Check on number of arguments **
[numOutArgs,numInArgs] = argn(0);
-
+
if numInArgs<1 | numInArgs>2 then
msg = "lpc: Wrong number of input argument; 1-2 expected";
error(77,msg);
@@ -58,10 +76,10 @@ function [a,g] = lpc(x,varargin)
msg = "lpc: Wrong number of output argument; 2 expected";
error(78,msg);
end
-
+
// ** Parsing input arguments **
// 1) check on x
-
+
// check on dimensions
if size(x,1)==1 | size(x,2)==1 then
// x is a single signal
@@ -71,7 +89,7 @@ function [a,g] = lpc(x,varargin)
msg = "lpc: Wrong size for argument #1 (x): a vector or 2D matrix expected"
error(60,msg);
end
-
+
// check on data type
if type(x)==8 then
// convert int to double
@@ -80,7 +98,7 @@ function [a,g] = lpc(x,varargin)
msg = "lpc: Wrong type for argument #1 (x): Real or complex matrix expected";
error(53,msg);
end
-
+
if length(varargin)==0 then
p = size(x,1)-1;
else
@@ -90,53 +108,53 @@ function [a,g] = lpc(x,varargin)
msg = "lpc: Wrong size for argument #2 (p): Scalar expected";
error(60,msg);
end
-
+
if type(p)~=1 & type(p)~=8 then
msg = "lpc: Wrong type for argument #2 (p): Natural number expected";
error(53,msg);
end
-
+
if p~=round(p) | p<=0 then
- msg = "lpc: Wrong type for argument #2 (p): Natural number expected";
+ msg = "lpc: Wrong type for argument #2 (p): Natural number expected";
error(53,msg);
end
-
+
if p>size(x,1) then
- msg = "lpc: Wrong value for argument #2 (p): Must be less than or equal to the length of the signal vector";
+ msg = "lpc: Wrong value for argument #2 (p): Must be less than or equal to the length of the signal vector";
error(53,msg);
end
-
+
if ~isreal(p) then
msg = "lpc: Wrong type for argument #2 (p): Real scalar expected";
error(53,msg);
end
end
-
+
num_signals = size(x,2);
// ** Processing **
N = size(x,1);
-
+
// zero pad x
x = [x; zeros(2^nextpow2(2*N-1)-N,size(x,2))];
X = fft(x,-1,1);
R = fft(abs(X).^2,1,1);
R = R./N; // Biased autocorrelation estimate
-
+
// change ieee mode to handle division by zero
ieee_prev = ieee();
ieee(2);
[a,g] = ld_recursion(R,p);
ieee(int(ieee_prev));
-
-
+
+
// filter coeffs should be real if input is real
for signal_idx=1:num_signals
if isreal(x(:,signal_idx)) then
- a(signal_idx,:) = real(a(signal_idx,:));
+ a(signal_idx,:) = real(a(signal_idx,:));
end
end
-
+
endfunction
function [a,e] = ld_recursion(R,p)
@@ -144,30 +162,30 @@ function [a,e] = ld_recursion(R,p)
//
// Paramaters
// R: double
- // Autocorrelation matrix where column corresponds to autocorrelation
+ // Autocorrelation matrix where column corresponds to autocorrelation
// to be treated independently
// a: double
- // Matrix where rows denote filter cofficients of the corresponding
+ // Matrix where rows denote filter cofficients of the corresponding
// autocorrelation values
// e: double
// Column vector denoting error variance for each filter computation
-
-
+
+
num_filters = size(R,2);
-
-
+
+
// Initial filter (order 0)
a = zeros(num_filters,p+1);
a(:,1) = 1;
e = R(1,:).';
-
-
+
+
// Solving in a bottom-up fashion (low to high filter coeffs)
for m=1:p
k_m = -sum(a(:,m:-1:1).*R(2:m+1,:).',2)./e;
a(:,2:m+1) = a(:,2:m+1) + k_m(:,ones(1,m)).*conj(a(:,m:-1:1));
-
+
e = (1-abs(k_m).^2).*e;
end
-
+
endfunction