1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
## Copyright (C) 2006 Peter V. Lanspeary <pvl@mecheng.adelaide.edu.au>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; see the file COPYING. If not, see
## <https://www.gnu.org/licenses/>.
## -*- texinfo -*-
## @deftypefn {Function File} {[@var{psd},@var{f_out}] =} pburg(@var{x}, @var{poles}, @var{freq}, @var{Fs}, @var{range}, @var{method}, @var{plot_type}, @var{criterion})
## Calculate Burg maximum-entropy power spectral density.
##
## The functions "arburg" and "ar_psd" do all the work.
## See "help arburg" and "help ar_psd" for further details.
##
## ARGUMENTS:
##
## All but the first two arguments are optional and may be empty.
##
## @table @asis
## @item x
## [vector] sampled data
## @item poles
## [integer scalar] required number of poles of the AR model
## @item freq
## [real vector] frequencies at which power spectral density is calculated.
##
## [integer scalar] number of uniformly distributed frequency
## values at which spectral density is calculated.
## [default=256]
## @item Fs
## [real scalar] sampling frequency (Hertz) [default=1]
## @end table
##
## CONTROL-STRING ARGUMENTS -- each of these arguments is a character string.
##
## Control-string arguments can be in any order after the other arguments.
##
##
## @table @asis
## @item range
## 'half', 'onesided' : frequency range of the spectrum is
## from zero up to but not including sample_f/2. Power
## from negative frequencies is added to the positive
## side of the spectrum.
##
## 'whole', 'twosided' : frequency range of the spectrum is
## -sample_f/2 to sample_f/2, with negative frequencies
## stored in "wrap around" order after the positive
## frequencies; e.g. frequencies for a 10-point 'twosided'
## spectrum are 0 0.1 0.2 0.3 0.4 0.5 -0.4 -0.3 -0.2 -0.1
##
## 'shift', 'centerdc' : same as 'whole' but with the first half
## of the spectrum swapped with second half to put the
## zero-frequency value in the middle. (See "help
## fftshift". If "freq" is vector, 'shift' is ignored.
## If model coefficients "ar_coeffs" are real, the default
## range is 'half', otherwise default range is 'whole'.
##
## @item method
## 'fft': use FFT to calculate power spectral density.
##
## 'poly': calculate spectral density as a polynomial of 1/z
## N.B. this argument is ignored if the "freq" argument is a
## vector. The default is 'poly' unless the "freq"
## argument is an integer power of 2.
##
## @item plot_type
## 'plot', 'semilogx', 'semilogy', 'loglog', 'squared' or 'db':
## specifies the type of plot. The default is 'plot', which
## means linear-linear axes. 'squared' is the same as 'plot'.
## 'dB' plots "10*log10(psd)". This argument is ignored and a
## spectrum is not plotted if the caller requires a returned
## value.
##
## @item criterion
## [optional string arg] model-selection criterion. Limits
## the number of poles so that spurious poles are not
## added when the whitened data has no more information
## in it (see Kay & Marple, 1981). Recognized values are
##
## 'AKICc' -- approximate corrected Kullback information
## criterion (recommended),
##
## 'KIC' -- Kullback information criterion
##
## 'AICc' -- corrected Akaike information criterion
##
## 'AIC' -- Akaike information criterion
##
## 'FPE' -- final prediction error" criterion
##
## The default is to NOT use a model-selection criterion
## @end table
##
## RETURNED VALUES:
##
## If return values are not required by the caller, the spectrum
## is plotted and nothing is returned.
##
## @table @asis
## @item psd
## [real vector] power-spectral density estimate
## @item f_out
## [real vector] frequency values
## @end table
##
## HINTS
##
## This function is a wrapper for arburg and ar_psd.
##
## See "help arburg", "help ar_psd".
## @end deftypefn
function [psd,f_out]=pburg(x,poles,varargin)
##
if ( nargin<2 )
error( 'pburg: need at least 2 args. Use "help pburg"' );
endif
nvarargin=length(varargin);
criterion=[];
##
## Search for a "criterion" arg. If found, remove it
## from "varargin" list and feed it to arburg instead.
for iarg = 1: nvarargin
arrgh = varargin{iarg};
if ( ischar(arrgh) && ( strcmp(arrgh,'AKICc') ||...
strcmp(arrgh,'KIC') || strcmp(arrgh,'AICc') ||...
strcmp(arrgh,'AIC') || strcmp(arrgh,'FPE') ) )
criterion=arrgh;
if ( nvarargin>1 )
varargin{iarg}= [];
else
varargin={};
endif
endif
endfor
##
[ar_coeffs,residual]=arburg(x,poles,criterion);
if ( nargout==0 )
ar_psd(ar_coeffs,residual,varargin{:});
elseif ( nargout==1 )
psd = ar_psd(ar_coeffs,residual,varargin{:});
elseif ( nargout>=2 )
[psd,f_out] = ar_psd(ar_coeffs,residual,varargin{:});
endif
endfunction
%!demo
%! a = [1.0 -1.6216505 1.1102795 -0.4621741 0.2075552 -0.018756746];
%! Fs = 25;
%! n = 16384;
%! signal = detrend (filter (0.70181, a, rand (1, n)));
%! % frequency shift by modulating with exp(j.omega.t)
%! skewed = signal .* exp (2*pi*i*2/Fs*[1:n]);
%! hold on;
%! pburg (signal, 3, [], Fs);
%! pburg (signal, 4, [], Fs, "whole");
%! pburg (signal, 5, 128, Fs, "shift", "semilogy");
%! pburg (skewed, 7, 128, Fs, "AKICc", "shift", "semilogy");
%! user_freq = [-0.2:0.02:0.2]*Fs;
%! pburg (skewed, 7, user_freq, Fs, "AKICc", "semilogy");
%! hold off;
|