view scripts/signal/periodogram.m @ 14552:86854d032a37

maint: miscellaneous style fixes for .m files * audio/mu2lin.m, deprecated/cut.m, general/cplxpair.m, general/genvarname.m, geometry/rectint.m, help/gen_doc_cache.m, image/hsv2rgb.m, image/rainbow.m, io/textscan.m, miscellaneous/bzip2.m, miscellaneous/compare_versions.m, miscellaneous/fact.m, miscellaneous/menu.m, optimization/fminbnd.m, optimization/fminunc.m, optimization/fzero.m, optimization/sqp.m, plot/__gnuplot_drawnow__.m, plot/axis.m, plot/findobj.m, plot/legend.m, plot/peaks.m, plot/private/__errplot__.m, plot/private/__fltk_print__.m, plot/private/__go_draw_axes__.m, plot/private/__patch__.m, polynomial/pchip.m, polynomial/residue.m, signal/periodogram.m, sparse/sprandsym.m, statistics/base/moment.m, statistics/distributions/expcdf.m, statistics/distributions/expinv.m, statistics/distributions/exppdf.m, statistics/tests/prop_test_2.m, statistics/tests/sign_test.m, statistics/tests/t_test.m, statistics/tests/t_test_2.m, statistics/tests/t_test_regression.m, strings/regexptranslate.m, time/datetick.m: Style fixes.
author John W. Eaton <jwe@octave.org>
date Wed, 11 Apr 2012 22:07:00 -0400
parents 72c96de7a403
children 5d3a684236b0
line wrap: on
line source

## Copyright (C) 1995-2012 Friedrich Leisch
## Copyright (C) 2010 Alois Schloegl
##
## This file is part of Octave.
##
## Octave 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.
##
## Octave 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 Octave; see the file COPYING.  If not, see
## <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn {Function File} {[Pxx, @var{w}] =} periodogram (@var{x})
## For a data matrix @var{x} from a sample of size @var{n}, return the
## periodogram.  The angular frequency is returned in @var{w}.
##
## [Pxx,w] = periodogram (@var{x}).
##
## [Pxx,w] = periodogram (@var{x},win).
##
## [Pxx,w] = periodogram (@var{x},win,nfft).
##
## [Pxx,f] = periodogram (@var{x},win,nfft,Fs).
##
## [Pxx,f] = periodogram (@var{x},win,nfft,Fs,"range").
##
## @itemize
## @item x: data; if real-valued a one-sided spectrum is estimated,
## if complex-valued or range indicates "@nospell{twosided}", the full
## spectrum is estimated.
##
## @item win: weight data with window, x.*win is used for further computation,
## if window is empty, a rectangular window is used.
##
## @item nfft: number of frequency bins, default max(256, 2.^ceil(log2(length(x)))).
##
## @item Fs: sampling rate, default 1.
##
## @item range: "@nospell{onesided}" computes spectrum from [0..nfft/2+1].
## "@nospell{twosided}" computes spectrum from [0..nfft-1].  These strings
## can appear at any position in the list input arguments after window.
##
## @item Pxx: one-, or two-sided power spectrum.
##
## @item w: angular frequency [0..2*pi) (two-sided) or [0..pi] one-sided.
##
## @item f: frequency [0..Fs) (two-sided) or [0..Fs/2] one-sided.
## @end itemize
## @end deftypefn

## Author: FL <Friedrich.Leisch@ci.tuwien.ac.at>
## Description: Compute the periodogram

function [pxx, f] = periodogram (x, varargin)

  ## check input arguments

  if (nargin < 1 || nargin > 5)
    print_usage ();
  endif

  nfft = []; fs = []; range = []; window = [];
  j = 1;
  for k = 1:length (varargin)
    if (ischar (varargin{k}))
      range = varargin{k};
    else
      switch (j)
      case 1
        window = varargin{k};
      case 2
        nfft   = varargin{k};
      case 3
        fs     = varargin{k};
      case 4
        range  = varargin{k};
      endswitch
      j++;
    endif
  endfor

  [r, c] = size (x);
  if (r == 1)
    r = c;
  endif

  if (ischar (window))
    range = window;
    window = [];
  endif;
  if (ischar (nfft))
    range = nfft;
    nfft = [];
  endif;
  if (ischar (fs))
    range = fs;
    fs = [];
  endif;

  if (!  isempty (window))
    if (all (size (x) == size (window)))
      x .*= window;
    elseif (size (x, 1) == size (window, 1) && size (window, 2) == 1)
      x .*= window (:,ones (1,c));
    endif;
  endif

  if (numel (nfft)>1)
    error ("nfft must be scalar");
  endif
  if (isempty (nfft))
    nfft = max (256, 2.^ceil (log2 (r)));
  endif

  if (strcmp (range, "onesided"))
    range = 1;
  elseif (strcmp (range, "twosided"))
    range = 2;
  else
    range = 2-isreal (x);
  endif

  ## compute periodogram

  if (r>nfft)
    Pxx = 0;
    rr = rem (length (x), nfft);
    if (rr)
      x = [x(:); (zeros (nfft-rr, 1))];
    endif
    x = sum (reshape (x, nfft, []), 2);
  endif

  if (isempty (window))
    n = r;
  else
    n = sumsq (window);
  end;
  Pxx = (abs (fft (x, nfft))) .^ 2 / n ;

  if (nargin<4)
    Pxx /= 2*pi;
  elseif (! isempty (fs))
    Pxx /= fs;
  endif

  ## generate output arguments

  if (range == 1)  # onesided
    Pxx = Pxx(1:nfft/2+1) + [0; Pxx(end:-1:(nfft/2+2)); 0];
  endif

  if (nargout != 1)
    if (range == 1)
      f = (0:nfft/2)'/nfft;
    elseif (range == 2)
      f = (0:nfft-1)'/nfft;
    endif
    if (nargin<4)
      f *= 2*pi; # generate w=2*pi*f
    elseif (! isempty (fs))
      f *= fs;
    endif
  endif

  if (nargout == 0)
    if (nargin<4)
      plot (f/(2*pi), 10*log10 (Pxx));
      xlabel ("normalized frequency [x pi rad]");
      ylabel ("Power density [dB/rad/sample]");
    else
      plot (f, 10*log10 (Pxx));
      xlabel ("frequency [Hz]");
      ylabel ("Power density [dB/Hz]");
    endif
    grid on;
    title ("Periodogram Power Spectral Density Estimate");
  else
    pxx = Pxx;
  endif

endfunction