@c ---------------------------------------------------
@node Signals
@section Signals
@cindex Signals
@c Signals buffer
@c -----------------------------------------
@subsection buffer
@cindex buffer
@deftypefn  {Function File} {@var{y} =} buffer (@var{x}, @var{n}, @var{p}, @var{opt})
@deftypefnx {Function File} {[@var{y}, @var{z}, @var{opt}] =} buffer (@dots{})
 Buffer a signal into a data frame. The arguments to @code{buffer} are

@table @asis
@item @var{x}
 The data to be buffered.

@item @var{n}
 The number of rows in the produced data buffer. This is an positive
 integer value and must be supplied.

@item @var{p}
 An integer less than @var{n} that specifies the under- or overlap
 between column in the data frame. The default value of @var{p} is 0.

@item @var{opt}
 In the case of an overlap, @var{opt} can be either a vector of length
@var{p} or the string 'nodelay'. If @var{opt} is a vector, then the
 first @var{p} entries in @var{y} will be filled with these values. If
@var{opt} is the string 'nodelay', then the first value of @var{y}
 corresponds to the first value of @var{x}.

 In the can of an underlap, @var{opt} must be an integer between 0 and
@code{-@var{p}}. The represents the initial underlap of the first
 column of @var{y}.

 The default value for @var{opt} the vector @code{zeros (1, @var{p})}
 in the case of an overlap, or 0 otherwise.
@end table

 In the case of a single output argument, @var{y} will be padded with
 zeros to fill the missing values in the data frame. With two output
 arguments @var{z} is the remaining data that has not been used in the
 current data frame.

 Likewise, the output @var{opt} is the overlap, or underlap that might
 be used for a future call to @code{code} to allow continuous buffering.
@end deftypefn
@c Signals chirp
@c -----------------------------------------
@subsection chirp
@cindex chirp
@deftypefn  {Function File} {} chirp (@var{t})
@deftypefnx {Function File} {} chirp (@var{t}, @var{f0})
@deftypefnx {Function File} {} chirp (@var{t}, @var{f0}, @var{t1})
@deftypefnx {Function File} {} chirp (@var{t}, @var{f0}, @var{t1}, @var{f1})
@deftypefnx {Function File} {} chirp (@var{t}, @var{f0}, @var{t1}, @var{f1}, @var{shape})
@deftypefnx {Function File} {} chirp (@var{t}, @var{f0}, @var{t1}, @var{f1}, @var{shape}, @var{phase})

 Evaluate a chirp signal at time @var{t}.  A chirp signal is a frequency
 swept cosine wave.

@table @var
@item t
 vector of times to evaluate the chirp signal
@item f0
 frequency at time t=0 [ 0 Hz ]
@item t1
 time t1 [ 1 sec ]
@item f1
 frequency at time t=t1 [ 100 Hz ]
@item shape
 shape of frequency sweep
    'linear'      f(t) = (f1-f0)*(t/t1) + f0
    'quadratic'   f(t) = (f1-f0)*(t/t1)^2 + f0
    'logarithmic' f(t) = (f1/f0)^(t/t1) * f0
@item phase
 phase shift at t=0
@end table

 For example:

@example
@group
@c doctest: +SKIP
 specgram (chirp ([0:0.001:5]));  # default linear chirp of 0-100Hz in 1 sec
 specgram (chirp ([-2:0.001:15], 400, 10, 100, "quadratic"));
 soundsc (chirp ([0:1/8000:5], 200, 2, 500, "logarithmic"), 8000);
@end group
@end example

 If you want a different sweep shape f(t), use the following:

@group
@verbatim
 y = cos (2 * pi * integral (f(t)) + phase);
@end verbatim
@end group
@end deftypefn
@c Signals cmorwavf
@c -----------------------------------------
@subsection cmorwavf
@cindex cmorwavf
@deftypefn {Function File} {[@var{psi}, @var{x}] =} cmorwavf (@var{lb}, @var{ub}, @var{n}, @var{fb}, @var{fc})
 Compute the Complex Morlet wavelet.
@end deftypefn
@c Signals diric
@c -----------------------------------------
@subsection diric
@cindex diric
@deftypefn {Function File} {@var{y} =} diric (@var{x},@var{n})
 Compute the dirichlet function.
@xseealso{sinc, gauspuls, sawtooth}
@end deftypefn
@c Signals gauspuls
@c -----------------------------------------
@subsection gauspuls
@cindex gauspuls
@deftypefn  {Function File} {@var{y} =} gauspuls (@var{t})
@deftypefnx {Function File} {@var{y} =} gauspuls (@var{t}, @var{fc})
@deftypefnx {Function File} {@var{y} =} gauspuls (@var{t}, @var{fc}, @var{bw})
 Generate a Gaussian modulated sinusoidal pulse sampled at times @var{t}.
@xseealso{pulstran, rectpuls, tripuls}
@end deftypefn
@c Signals gmonopuls
@c -----------------------------------------
@subsection gmonopuls
@cindex gmonopuls
@deftypefn {Function File} {@var{y} =} gmonopuls (@var{t},@var{fc})
 Return the gaussian monopulse.
@end deftypefn
@c Signals mexihat
@c -----------------------------------------
@subsection mexihat
@cindex mexihat
@deftypefn {Function File} {[@var{psi}, @var{x}] =} mexihat (@var{lb}, @var{ub}, @var{n})
 Compute the Mexican hat wavelet.
@end deftypefn
@c Signals meyeraux
@c -----------------------------------------
@subsection meyeraux
@cindex meyeraux
@deftypefn {Function File} {@var{y} =} meyeraux (@var{x})
 Compute the Meyer wavelet auxiliary function.
@end deftypefn
@c Signals morlet
@c -----------------------------------------
@subsection morlet
@cindex morlet
@deftypefn {Function File} {[@var{psi}, @var{x}] =} morlet (@var{lb}, @var{ub}, @var{n})
 Compute the Morlet wavelet.
@end deftypefn
@c Signals pulstran
@c -----------------------------------------
@subsection pulstran
@cindex pulstran
@deftypefn  {Function File} {@var{y} =} pulstran (@var{t}, @var{d}, @var{func}, @dots{})
@deftypefnx {Function File} {@var{y} =} pulstran (@var{t}, @var{d}, @var{p})
@deftypefnx {Function File} {@var{y} =} pulstran (@var{t}, @var{d}, @var{p}, @var{Fs})
@deftypefnx {Function File} {@var{y} =} pulstran (@var{t}, @var{d}, @var{p}, @var{Fs}, @var{method})

 Generate the signal y=sum(func(t+d,...)) for each d.  If d is a
 matrix of two columns, the first column is the delay d and the second
 column is the amplitude a, and y=sum(a*func(t+d)) for each d,a.
 Clearly, func must be a function which accepts a vector of times.
 Any extra arguments needed for the function must be tagged on the end.

 Example:
@example
 fs = 11025;  # arbitrary sample rate
 f0 = 100;    # pulse train sample rate
 w = 0.001;   # pulse width of 1 millisecond
 auplot (pulstran (0:1/fs:0.1, 0:1/f0:0.1, "rectpuls", w), fs);
@end example

 If instead of a function name you supply a pulse shape sampled at
 frequency Fs (default 1 Hz),  an interpolated version of the pulse
 is added at each delay d.  The interpolation stays within the the
 time range of the delayed pulse.  The interpolation method defaults
 to linear, but it can be any interpolation method accepted by the
 function interp1.

 Example:
@example
 fs = 11025;      # arbitrary sample rate
 f0 = 100;        # pulse train sample rate
 w = boxcar(10);  # pulse width of 1 millisecond at 10 kHz
 auplot (pulstran (0:1/fs:0.1, 0:1/f0:0.1, w, 10000), fs);
@end example
@end deftypefn
@c Signals rectpuls
@c -----------------------------------------
@subsection rectpuls
@cindex rectpuls
@deftypefn  {Function File} {@var{y} =} rectpuls (@var{t})
@deftypefnx {Function File} {@var{y} =} rectpuls (@var{t}, @var{w})
 Generate a rectangular pulse over the interval [-@var{w}/2,@var{w}/2),
 sampled at times @var{t}.  This is useful with the function @code{pulstran}
 for generating a series of pulses.

 Example:
@example
@group
 fs = 11025;  # arbitrary sample rate
 f0 = 100;    # pulse train sample rate
 w = 0.3/f0;  # pulse width 3/10th the distance between pulses
 plot (pulstran (0:1/fs:4/f0, 0:1/f0:4/f0, "rectpuls", w));
@end group
@end example

@xseealso{gauspuls, pulstran, tripuls}
@end deftypefn
@c Signals sawtooth
@c -----------------------------------------
@subsection sawtooth
@cindex sawtooth
@deftypefn  {Function File} {@var{y} =} sawtooth (@var{t})
@deftypefnx {Function File} {@var{y} =} sawtooth (@var{t}, @var{width})
 Generates a sawtooth wave of period @code{2 * pi} with limits @code{+1/-1}
  for the elements of @var{t}.

@var{width} is a real number between @code{0} and @code{1} which specifies
 the point between @code{0} and @code{2 * pi} where the maximum is. The
 function increases linearly from @code{-1} to @code{1} in  @code{[0, 2 *
 pi * @var{width}]} interval, and decreases linearly from @code{1} to
@code{-1} in the interval @code{[2 * pi * @var{width}, 2 * pi]}.

 If @var{width} is 0.5, the function generates a standard triangular wave.

 If @var{width} is not specified, it takes a value of 1, which is a standard
 sawtooth function.
@end deftypefn
@c Signals shanwavf
@c -----------------------------------------
@subsection shanwavf
@cindex shanwavf
@deftypefn {Function File} {[@var{psi}, @var{x}] =} shanwavf (@var{lb}, @var{ub}, @var{n}, @var{fb}, @var{fc})
 Compute the Complex Shannon wavelet.
@end deftypefn
@c Signals shiftdata
@c -----------------------------------------
@subsection shiftdata
@cindex shiftdata
@deftypefn  {Function File} {[@var{out perm shifts}] =} shiftdata (@var{in})
@deftypefnx {Function File} {[@var{out perm shifts}] =} shiftdata (@var{in}, @var{dim})
 Shift data @var{in} to permute the dimension @var{dim} to the first column.
@xseealso{unshiftdata}
@end deftypefn
@c Signals sigmoid_train
@c -----------------------------------------
@subsection sigmoid_train
@cindex sigmoid_train
@deftypefn {Function File} {[@var{y} @var{s}] =} sigmoid_train (@var{t}, @var{ranges}, @var{rc})

 Evaluate a train of sigmoid functions at @var{t}.

 The number and duration of each sigmoid is determined from @var{ranges}.
 Each row of @var{ranges} represents a real interval, e.g. if sigmoid
@code{i} starts at @code{t=0.1} and ends at @code{t=0.5}, then
@code{@var{ranges}(i,:) = [0.1 0.5]}.
 The input @var{rc} is an array that defines the rising and falling time
 constants of each sigmoid.  Its size must equal the size of @var{ranges}.

 The individual sigmoids are returned in @var{s}. The combined sigmoid train
 is returned in the vector @var{y} of length equal to @var{t}, and such that
@code{Y = max (S)}.

 Run @code{demo sigmoid_train} to some examples of the use of this function.

@end deftypefn
@c Signals specgram
@c -----------------------------------------
@subsection specgram
@cindex specgram
@deftypefn  {Function File} {} specgram (@var{x})
@deftypefnx {Function File} {} specgram (@var{x}, @var{n})
@deftypefnx {Function File} {} specgram (@var{x}, @var{n}, @var{Fs})
@deftypefnx {Function File} {} specgram (@var{x}, @var{n}, @var{Fs}, @var{window})
@deftypefnx {Function File} {} specgram (@var{x}, @var{n}, @var{Fs}, @var{window}, @var{overlap})
@deftypefnx {Function File} {[@var{S}, @var{f}, @var{t}] =} specgram (@dots{})

 Generate a spectrogram for the signal @var{x}.  The signal is chopped into
 overlapping segments of length @var{n}, and each segment is windowed and
 transformed into the frequency domain using the FFT.  The default segment
 size is 256.  If @var{fs} is given, it specifies the sampling rate of the
 input signal.  The argument @var{window} specifies an alternate window to
 apply rather than the default of @code{hanning (@var{n})}.  The argument
@var{overlap} specifies the number of samples overlap between successive
 segments of the input signal.  The default overlap is
@code{length (@var{window})/2}.

 If no output arguments are given, the spectrogram is displayed.  Otherwise,
@var{S} is the complex output of the FFT, one row per slice, @var{f} is the
 frequency indices corresponding to the rows of @var{S}, and @var{t} is the
 time indices corresponding to the columns of @var{S}.

 Example:
@example
@group
    x = chirp([0:0.001:2],0,2,500);  # freq. sweep from 0-500 over 2 sec.
    Fs=1000;                  # sampled every 0.001 sec so rate is 1 kHz
    step=ceil(20*Fs/1000);    # one spectral slice every 20 ms
    window=ceil(100*Fs/1000); # 100 ms data window
    specgram(x, 2^nextpow2(window), Fs, window, window-step);

    ## Speech spectrogram
    [x, Fs] = auload(file_in_loadpath("sample.wav")); # audio file
    step = fix(5*Fs/1000);     # one spectral slice every 5 ms
    window = fix(40*Fs/1000);  # 40 ms data window
    fftn = 2^nextpow2(window); # next highest power of 2
    [S, f, t] = specgram(x, fftn, Fs, window, window-step);
    S = abs(S(2:fftn*4000/Fs,:)); # magnitude in range 0<f<=4000 Hz.
    S = S/max(S(:));           # normalize magnitude so that max is 0 dB.
    S = max(S, 10^(-40/10));   # clip below -40 dB.
    S = min(S, 10^(-3/10));    # clip above -3 dB.
    imagesc (t, f, log(S));    # display in log scale
    set (gca, "ydir", "normal"); # put the 'y' direction in the correct direction
@end group
@end example

 The choice of window defines the time-frequency resolution.  In
 speech for example, a wide window shows more harmonic detail while a
 narrow window averages over the harmonic detail and shows more
 formant structure. The shape of the window is not so critical so long
 as it goes gradually to zero on the ends.

 Step size (which is window length minus overlap) controls the
 horizontal scale of the spectrogram. Decrease it to stretch, or
 increase it to compress. Increasing step size will reduce time
 resolution, but decreasing it will not improve it much beyond the
 limits imposed by the window size (you do gain a little bit,
 depending on the shape of your window, as the peak of the window
 slides over peaks in the signal energy).  The range 1-5 msec is good
 for speech.

 FFT length controls the vertical scale.  Selecting an FFT length
 greater than the window length does not add any information to the
 spectrum, but it is a good way to interpolate between frequency
 points which can make for prettier spectrograms.

 After you have generated the spectral slices, there are a number of
 decisions for displaying them.  First the phase information is
 discarded and the energy normalized:

     S = abs(S); S = S/max(S(:));

 Then the dynamic range of the signal is chosen.  Since information in
 speech is well above the noise floor, it makes sense to eliminate any
 dynamic range at the bottom end.  This is done by taking the max of
 the magnitude and some minimum energy such as minE=-40dB. Similarly,
 there is not much information in the very top of the range, so
 clipping to a maximum energy such as maxE=-3dB makes sense:

     S = max(S, 10^(minE/10)); S = min(S, 10^(maxE/10));

 The frequency range of the FFT is from 0 to the Nyquist frequency of
 one half the sampling rate.  If the signal of interest is band
 limited, you do not need to display the entire frequency range. In
 speech for example, most of the signal is below 4 kHz, so there is no
 reason to display up to the Nyquist frequency of 10 kHz for a 20 kHz
 sampling rate.  In this case you will want to keep only the first 40%
 of the rows of the returned S and f.  More generally, to display the
 frequency range [minF, maxF], you could use the following row index:

     idx = (f >= minF & f <= maxF);

 Then there is the choice of colormap.  A brightness varying colormap
 such as copper or bone gives good shape to the ridges and valleys. A
 hue varying colormap such as jet or hsv gives an indication of the
 steepness of the slopes.  The final spectrogram is displayed in log
 energy scale and by convention has low frequencies on the bottom of
 the image:

     imagesc(t, f, flipud(log(S(idx,:))));
@end deftypefn
@c Signals square
@c -----------------------------------------
@subsection square
@cindex square
@deftypefn  {Function File} {@var{s} =} square (@var{t}, @var{duty})
@deftypefnx {Function File} {@var{s} =} square (@var{t})
 Generate a square wave of period 2 pi with limits +1/-1.

 If @var{duty} is specified, it is the percentage of time the square
 wave is "on".  The square wave is +1 for that portion of the time.

@verbatim
                   on time * 100
    duty cycle = ------------------
                 on time + off time
@end verbatim

@xseealso{cos, sawtooth, sin, tripuls}
@end deftypefn
@c Signals tripuls
@c -----------------------------------------
@subsection tripuls
@cindex tripuls
@deftypefn  {Function File} {@var{y} =} tripuls (@var{t})
@deftypefnx {Function File} {@var{y} =} tripuls (@var{t}, @var{w})
@deftypefnx {Function File} {@var{y} =} tripuls (@var{t}, @var{w}, @var{skew})
 Generate a triangular pulse over the interval [-@var{w}/2,@var{w}/2),
 sampled at times @var{t}.  This is useful with the function @code{pulstran}
 for generating a series of pulses.

@var{skew} is a value between -1 and 1, indicating the relative placement
 of the peak within the width.  -1 indicates that the peak should be
 at -@var{w}/2, and 1 indicates that the peak should be at @var{w}/2.  The
 default value is 0.

 Example:
@example
@group
 fs = 11025;  # arbitrary sample rate
 f0 = 100;    # pulse train sample rate
 w = 0.3/f0;  # pulse width 3/10th the distance between pulses
 plot (pulstran (0:1/fs:4/f0, 0:1/f0:4/f0, "tripuls", w));
@end group
@end example

@xseealso{gauspuls, pulstran, rectpuls}
@end deftypefn
@c Signals udecode
@c -----------------------------------------
@subsection udecode
@cindex udecode
@deftypefn  {Function File} {@var{out} =} udecode (@var{in}, @var{n})
@deftypefnx {Function File} {@var{out} =} udecode (@var{in}, @var{n}, @var{v})
@deftypefnx {Function File} {@var{out} =} udecode (@var{in}, @var{n}, @var{v}, @var{overflows})
 Invert the operation of uencode.
@xseealso{uencode}
@end deftypefn
@c Signals uencode
@c -----------------------------------------
@subsection uencode
@cindex uencode
@deftypefn  {Function File} {@var{out} =} uencode (@var{in}, @var{n})
@deftypefnx {Function File} {@var{out} =} uencode (@var{in}, @var{n}, @var{v})
@deftypefnx {Function File} {@var{out} =} uencode (@var{in}, @var{n}, @var{v}, @var{signed})
 Quantize the entries of the array @var{in} using 2^@var{n} quantization levels.
@xseealso{udecode}
@end deftypefn
@c Signals unshiftdata
@c -----------------------------------------
@subsection unshiftdata
@cindex unshiftdata
@deftypefn  {Function File} {[@var{out}] =} unshiftdata (@var{in}, @var{perm}, @var{shifts})
 Reverse what is done by shiftdata.
@xseealso{shiftdata}
@end deftypefn
@c Signals vco
@c -----------------------------------------
@subsection vco
@cindex vco
@deftypefn {} {y =} vco (@var{x}, @var{fc}, @var{fs})
@deftypefnx {} {y =} vco (@var{x}, [@var{fmin}, @var{fmax}], @var{fs})
 Creates a signal that oscillates at a frequency determined by input @var{x} with a sampling frequency @var{fs}.

 Inputs:
@itemize
@item
@var{x} - input data with a range of -1 to 1. A value of -1 means no output, 0 cuoreesponds to @var{fc},
 and 1 corresponds to 2*@var{fc}.

@item
@var{fc} - Carrier frequency

@item
@var{fs} - Sampling rate

@item
@var{fmin}, @var{fmax} - Frequency modulation range limits.
@end itemize

 Outputs:
@itemize
@item
@var{y} - output signal
@end itemize
@end deftypefn
@c ---------------------------------------------------
@node Signal Measurement
@section Signal Measurement
@cindex Signal Measurement
@c Signal Measurement findpeaks
@c -----------------------------------------
@subsection findpeaks
@cindex findpeaks
@deftypefn  {Function File} {[@var{pks}, @var{loc}, @var{extra}] =} findpeaks (@var{data})
@deftypefnx {Function File} {@dots{} =} findpeaks (@dots{}, @var{property}, @var{value})
@deftypefnx {Function File} {@dots{} =} findpeaks (@dots{}, @asis{"DoubleSided"})
 Finds peaks on @var{data}.

 Peaks of a positive array of data are defined as local maxima. For
 double-sided data, they are maxima of the positive part and minima of
 the negative part. @var{data} is expected to be a single column
 vector.

 The function returns the value of @var{data} at the peaks in
@var{pks}. The index indicating their position is returned in
@var{loc}.

 The third output argument is a structure with additional information:

@table @asis
@item "parabol"
 A structure containing the parabola fitted to each returned peak. The
 structure has two fields, @asis{"x"} and @asis{"pp"}. The field
@asis{"pp"} contains the coefficients of the 2nd degree polynomial
 and @asis{"x"} the extrema of the interval where it was fitted.

@item "height"
 The estimated height of the returned peaks (in units of @var{data}).

@item "baseline"
 The height at which the roots of the returned peaks were calculated
 (in units of @var{data}).

@item "roots"
 The abscissa values (in index units) at which the parabola fitted to
 each of the returned peaks realizes its width as defined below.
@end table

 This function accepts property-value pair given in the list below:

@table @asis

@item "MinPeakHeight"
 Minimum peak height (non-negative scalar). Only peaks that exceed this
 value will be returned. For data taking positive and negative values
 use the option "DoubleSided". Default value @code{eps}.

@item "MinPeakDistance"
 Minimum separation between (positive integer). Peaks separated by
 less than this distance are considered a single peak. This distance
 is also used to fit a second order polynomial to the peaks to
 estimate their width, therefore it acts as a smoothing parameter.
 The neighborhood size is equal to the value of @asis{"MinPeakDistance"}.
 Default value 1.

@item "MinPeakWidth"
 Minimum width of peaks (positive integer). The width of the peaks is
 estimated using a parabola fitted to the neighborhood of each peak.
 The width is caulculated with the formula
@group
 a * (width - x0)^2 = 1
@end group
 where a is the the concavity of the parabola and x0 its vertex.
 Default value 1.

@item "MaxPeakWidth"
 Maximum width of peaks (positive integer).
 Default value @code{Inf}.

@item "DoubleSided"
 Tells the function that data takes positive and negative values. The
 base-line for the peaks is taken as the mean value of the function.
 This is equivalent as passing the absolute value of the data after
 removing the mean.
@end table

 Run @command{demo findpeaks} to see some examples.
@end deftypefn
@c Signal Measurement peak2peak
@c -----------------------------------------
@subsection peak2peak
@cindex peak2peak
@deftypefn  {Function File} {@var{y} =} peak2peak (@var{x})
@deftypefnx {Function File} {@var{y} =} peak2peak (@var{x}, @var{dim})
 Compute the difference between the maximum and minimum values in the vector
@var{x}.

 If @var{x} is a matrix, compute the difference for each column and return
 them in a row vector.

 If the optional argument @var{dim} is given, operate along this dimension.
@xseealso{max, min, peak2rms, rms, rssq}
@end deftypefn
@c Signal Measurement peak2rms
@c -----------------------------------------
@subsection peak2rms
@cindex peak2rms
@deftypefn  {Function File} {@var{y} =} peak2rms (@var{x})
@deftypefnx {Function File} {@var{y} =} peak2rms (@var{x}, @var{dim})
 Compute the ratio of the largest absolute value to the root-mean-square
 (RMS) value of the vector @var{x}.

 If @var{x} is a matrix, compute the peak-magnitude-to-RMS ratio for each
 column and return them in a row vector.

 If the optional argument @var{dim} is given, operate along this dimension.
@xseealso{max, min, peak2peak, rms, rssq}
@end deftypefn
@c Signal Measurement rms
@c -----------------------------------------
@subsection rms
@cindex rms
@deftypefn  {Function File} {@var{y} =} rms (@var{x})
@deftypefnx {Function File} {@var{y} =} rms (@var{x}, @var{dim})
 Compute the root-mean-square (RMS) of the vector @var{x}.

 The root-mean-square is defined as

@tex
 $$ {\rm rms}(x) = {\sqrt{\sum_{i=1}^N {x_i}^2 \over N}} $$
@end tex
@ifnottex

@example
 rms (@var{x}) = SQRT (1/N SUM_i @var{x}(i)^2)
@end example

@end ifnottex
 If @var{x} is a matrix, compute the root-mean-square for each column and
 return them in a row vector.

 If the optional argument @var{dim} is given, operate along this dimension.
@xseealso{mean, meansq, peak2rms, rssq, sumsq}
@end deftypefn
@c Signal Measurement rssq
@c -----------------------------------------
@subsection rssq
@cindex rssq
@deftypefn  {Function File} {@var{y} =} rssq (@var{x})
@deftypefnx {Function File} {@var{y} =} rssq (@var{x}, @var{dim})
 Compute the root-sum-of-squares (RSS) of the vector @var{x}.

 The root-sum-of-squares is defined as

@tex
 $$ {\rm rssq}(x) = {\sqrt{\sum_{i=1}^N {x_i}^2}} $$
@end tex
@ifnottex

@example
 rssq (@var{x}) = SQRT (SUM_i @var{x}(i)^2)
@end example

@end ifnottex
 If @var{x} is a matrix, compute the root-sum-of-squares for each column and
 return them in a row vector.

 If the optional argument @var{dim} is given, operate along this dimension.
@xseealso{mean, meansq, sumsq, rms}
@end deftypefn
@c ---------------------------------------------------
@node Correlation and Convolution
@section Correlation and Convolution
@cindex Correlation and Convolution
@c Correlation and Convolution cconv
@c -----------------------------------------
@subsection cconv
@cindex cconv
@deftypefn  {Function File} {@var{c} =} cconv (@var{a}, @var{b}, @var{n})
@deftypefnx {Function File} {@var{c} =} cconv (@var{a}, @var{b})
 Compute the modulo-N circular convolution.

@var{a} and @var{b} are input vectors and @var{c} is the modolo-@var{n}
 convolution of @var{a} and @var{b}. If @var{n} is not provided,
 its assumed default value is @code{length(@var{a}) + length(@var{b}) - 1},
 which provides the same result as a linear convolution.

 Examples:

@example
@group
 cconv (1:2, 1:4)
    @result{}  1   4   7   10   8
@end group
@end example

@example
@group
 cconv (1:2, 1:4, 2)
    @result{}  16   14
@end group
@end example

@example
@group
 cconv (1:2, 1:4, 4)
    @result{}  9   4   7   10
@end group
@end example

@xseealso{conv, circshift}
@end deftypefn
@c Correlation and Convolution convmtx
@c -----------------------------------------
@subsection convmtx
@cindex convmtx
@deftypefn {Function File} {} convmtx (@var{a}, @var{n})
 If @var{a} is a column vector and @var{x} is a column vector
 of length @var{n}, then

@code{convmtx(@var{a}, @var{n}) * @var{x}}

 gives the convolution of of @var{a} and @var{x} and is the
 same as @code{conv(@var{a}, @var{x})}. The difference is if
 many vectors are to be convolved with the same vector, then
 this technique is possibly faster.

 Similarly, if @var{a} is a row vector and @var{x} is a row
 vector of length @var{n}, then

@code{@var{x} * convmtx(@var{a}, @var{n})}

 is the same as @code{conv(@var{x}, @var{a})}.
@end deftypefn
@xseealso{conv}
@c Correlation and Convolution wconv
@c -----------------------------------------
@subsection wconv
@cindex wconv
@deftypefn  {Function File} {@var{y} =} wconv (@var{type}, @var{x}, @var{f})
@deftypefnx {Function File} {@var{y} =} wconv (@var{type}, @var{x}, @var{f}, @var{shape})
 1-D or 2-D convolution.

@strong{Inputs}
@table @var
@item type
 Type of convolution.
@item x
 Signal vector or matrix.
@item f
 Coefficients of @acronym{FIR} filter.
@item shape
 Shape.
@end table

@strong{Outputs}
@table @var
@item y
 Convoluted signal.
@end table
@end deftypefn
@c Correlation and Convolution xcorr
@c -----------------------------------------
@subsection xcorr
@cindex xcorr
@deftypefn  {Function File} {[@var{R}, @var{lag}] =} xcorr ( @var{X} )
@deftypefnx {Function File} {@dots{} =} xcorr ( @var{X}, @var{Y} )
@deftypefnx {Function File} {@dots{} =} xcorr ( @dots{}, @var{maxlag})
@deftypefnx {Function File} {@dots{} =} xcorr ( @dots{}, @var{scale})
 Estimates the cross-correlation.

 Estimate the cross correlation R_xy(k) of vector arguments @var{X} and @var{Y}
 or, if @var{Y} is omitted, estimate autocorrelation R_xx(k) of vector @var{X},
 for a range of lags k specified by  argument "maxlag".  If @var{X} is a
 matrix, each column of @var{X} is correlated with itself and every other
 column.

 The cross-correlation estimate between vectors "x" and "y" (of
 length N) for lag "k" is given by

@tex
 $$   R_{xy}(k) = \sum_{i=1}^{N} x_{i+k} \conj(y_i),
@end tex
@ifnottex
@example
@group
            N
 R_xy(k) = sum x_@{i+k@} conj(y_i),
           i=1
@end group
@end example
@end ifnottex

 where data not provided (for example x(-1), y(N+1)) is zero. Note the
 definition of cross-correlation given above. To compute a
 cross-correlation consistent with the field of statistics, see @command{xcov}.

@strong{ARGUMENTS}
@table @var
@item X
 [non-empty; real or complex; vector or matrix] data

@item Y
 [real or complex vector] data

 If @var{X} is a matrix (not a vector), @var{Y} must be omitted.
@var{Y} may be omitted if @var{X} is a vector; in this case xcorr
 estimates the autocorrelation of @var{X}.

@item maxlag
 [integer scalar] maximum correlation lag
 If omitted, the default value is N-1, where N is the
 greater of the lengths of @var{X} and @var{Y} or, if @var{X} is a matrix,
 the number of rows in @var{X}.

@item scale
 [character string] specifies the type of scaling applied
 to the correlation vector (or matrix). is one of:
@table @samp
@item none
 return the unscaled correlation, R,
@item biased
 return the biased average, R/N,
@item unbiased
 return the unbiased average, R(k)/(N-|k|),
@item coeff or normalized
 return the correlation coefficient, R/(rms(x).rms(y)),
 where "k" is the lag, and "N" is the length of @var{X}.
 If omitted, the default value is "none".
 If @var{Y} is supplied but does not have the same length as @var{X},
 scale must be "none".
@end table
@end table

@strong{RETURNED VARIABLES}
@table @var
@item R
 array of correlation estimates
@item lag
 row vector of correlation lags [-maxlag:maxlag]
@end table

 The array of correlation estimates has one of the following forms:
 (1) Cross-correlation estimate if @var{X} and @var{Y} are vectors.

 (2) Autocorrelation estimate if is a vector and @var{Y} is omitted.

 (3) If @var{X} is a matrix, R is an matrix containing the cross-correlation
 estimate of each column with every other column. Lag varies with the first
 index so that R has 2*maxlag+1 rows and P^2 columns where P is the number of
 columns in @var{X}.

 If Rij(k) is the correlation between columns i and j of @var{X}

@code{R(k+maxlag+1,P*(i-1)+j) == Rij(k)}

 for lag k in [-maxlag:maxlag], or

@code{R(:,P*(i-1)+j) == xcorr(X(:,i),X(:,j))}.

@code{reshape(R(k,:),P,P)} is the cross-correlation matrix for @code{X(k,:)}.

@xseealso{xcov}
@end deftypefn
@c Correlation and Convolution xcorr2
@c -----------------------------------------
@subsection xcorr2
@cindex xcorr2
@deftypefn  {Function File} {} xcorr2 (@var{a})
@deftypefnx {Function File} {} xcorr2 (@var{a}, @var{b})
@deftypefnx {Function File} {} xcorr2 (@dots{}, @var{scale})
 Compute the 2D cross-correlation of matrices @var{a} and @var{b}.

 If @var{b} is not specified, computes autocorrelation of @var{a}, i.e.,
 same as @code{xcorr (@var{a}, @var{a})}.

 The optional argument @var{scale}, defines the type of scaling applied to the
 cross-correlation matrix. Possible values are:

@table @asis
@item "none" (default)
 No scaling.

@item "biased"
 Scales the raw cross-correlation by the maximum number of elements of @var{a}
 and @var{b} involved in the generation of any element of @var{c}.

@item "unbiased"
 Scales the raw correlation by dividing each element in the cross-correlation
 matrix by the number of products @var{a} and @var{b} used to generate that
 element.

@item "coeff"
 Scales the normalized cross-correlation on the range of [0 1] so that a value
 of 1 corresponds to a correlation coefficient of 1.
@end table

@xseealso{conv2, corr2, xcorr}
@end deftypefn
@c Correlation and Convolution xcov
@c -----------------------------------------
@subsection xcov
@cindex xcov
@deftypefn  {Function File} {[@var{R}, @var{lag}] =} xcov ( @var{X} )
@deftypefnx {Function File} {@dots{} =} xcov ( @var{X}, @var{Y} )
@deftypefnx {Function File} {@dots{} =} xcov ( @dots{}, @var{maxlag})
@deftypefnx {Function File} {@dots{} =} xcov ( @dots{}, @var{scale})
 Compute covariance at various lags [=correlation(x-mean(x),y-mean(y))].

@table @var
@item X
 input vector
@item Y
 if specified, compute cross-covariance between X and Y,
 otherwise compute autocovariance of X.
@item maxlag
 is specified, use lag range [-maxlag:maxlag],
 otherwise use range [-n+1:n-1].
@item scale:
@table @samp
@item biased
 for covariance=raw/N,
@item unbiased
 for covariance=raw/(N-|lag|),
@item coeff
 for covariance=raw/(covariance at lag 0),
@item none
 for covariance=raw
@item none
 is the default.
@end table
@end table

 Returns the covariance for each lag in the range, plus an
 optional vector of lags.

@xseealso{xcorr}
@end deftypefn
@c ---------------------------------------------------
@node Filtering
@section Filtering
@cindex Filtering
@c Filtering filtfilt
@c -----------------------------------------
@subsection filtfilt
@cindex filtfilt
@deftypefn {Function File} {@var{y} =} filtfilt (@var{b}, @var{a}, @var{x})

 Forward and reverse filter the signal. This corrects for phase
 distortion introduced by a one-pass filter, though it does square the
 magnitude response in the process. That's the theory at least.  In
 practice the phase correction is not perfect, and magnitude response
 is distorted, particularly in the stop band.

 Example
@example
@group
 [b, a]=butter(3, 0.1);                  # 5 Hz low-pass filter
 t = 0:0.01:1.0;                         # 1 second sample
 x=sin(2*pi*t*2.3)+0.25*randn(size(t));  # 2.3 Hz sinusoid+noise
 y = filtfilt(b,a,x); z = filter(b,a,x); # apply filter
 plot(t,x,';data;',t,y,';filtfilt;',t,z,';filter;')
@end group
@end example
@end deftypefn
@c Filtering filtic
@c -----------------------------------------
@subsection filtic
@cindex filtic
@deftypefn  {Function File} {@var{zf} =} filtic (@var{b}, @var{a}, @var{y})
@deftypefnx {Function File} {@var{zf} =} filtic (@var{b}, @var{a}, @var{y}, @var{x})

 Set initial condition vector for filter function
 The vector zf has the same values that would be obtained
 from function filter given past inputs x and outputs y

 The vectors x and y contain the most recent inputs and outputs
 respectively, with the newest values first:

 x = [x(-1) x(-2) ... x(-nb)], nb = length(b)-1
 y = [y(-1) y(-2) ... y(-na)], na = length(a)-a

 If length(x)<nb then it is zero padded
 If length(y)<na then it is zero padded

 zf = filtic(b, a, y)
    Initial conditions for filter with coefficients a and b
    and output vector y, assuming input vector x is zero

 zf = filtic(b, a, y, x)
    Initial conditions for filter with coefficients a and b
    input vector x and output vector y
@end deftypefn
@c Filtering medfilt1
@c -----------------------------------------
@subsection medfilt1
@cindex medfilt1
@deftypefn  {} {@var{y} =} medfilt1 (@var{x}, @var{n})
@deftypefnx {} {@var{y} =} medfilt1 (@var{x}, @var{n}, [], @var{dim})
@deftypefnx {} {@var{y} =} medfilt1 (..., @var{NaN_flag}, @var{padding})

Apply a one dimensional median filter with a window size of @var{n} to
the data @var{x}, which must be real, double and full.
For @var{n} = 2m+1, @var{y}(i) is the median of @var{x}(i-m:i+m).
For @var{n} = 2m,   @var{y}(i) is the median of @var{x}(i-m:i+m-1).

The calculation is performed over the first non-singleton dimension, or over
dimension @var{dim} if that is specified as the fourth argument.  (The third
argument is ignored; Matlab used to use it to tune its algorithm.)

@var{NaN_flag} may be @qcode{omitnan} or @qcode{includenan} (the default).
If it is @qcode{omitnan} then any NaN values are removed from the window
before the median is taken.
Otherwise, any window containing an NaN returns a median of NaN.

@var{padding} determines how the partial windows at the start and end of
@var{x} are treated.
It may be @qcode{truncate} or @qcode{zeropad} (the default).
If it is @qcode{truncate} then the window for @var{y}(i) is
the intersection of the window stated above with 1:length(@var{x}).
If it is @qcode{zeropad}, then partial windows have additional zeros
to bring them up to size @var{n}.

@xseealso{filter, medfilt2}
@end deftypefn
@c Filtering movingrms
@c -----------------------------------------
@subsection movingrms
@cindex movingrms
@deftypefn {Function File} {[@var{rmsx},@var{w}] =} movingrms (@var{x},@var{w},@var{rc},@var{Fs}=1)
 Calculate moving RMS value of the signal in @var{x}.

 The signal is convoluted against a sigmoid window of width @var{w} and
 risetime @var{rc}. The units of these parameters are relative to the value
 of the sampling frequency given in @var{Fs} (Default value = 1).

 Run @code{demo movingrms} to see an example.

@xseealso{sigmoid_train}
@end deftypefn
@c Filtering sgolayfilt
@c -----------------------------------------
@subsection sgolayfilt
@cindex sgolayfilt
@deftypefn  {Function File} {@var{y} =} sgolayfilt (@var{x})
@deftypefnx {Function File} {@var{y} =} sgolayfilt (@var{x}, @var{p})
@deftypefnx {Function File} {@var{y} =} sgolayfilt (@var{x}, @var{p}, @var{n})
@deftypefnx {Function File} {@var{y} =} sgolayfilt (@var{x}, @var{p}, @var{n}, @var{m})
@deftypefnx {Function File} {@var{y} =} sgolayfilt (@var{x}, @var{p}, @var{n}, @var{m}, @var{ts})
@deftypefnx {Function File} {@var{y} =} sgolayfilt (@var{x}, @var{p}, @var{n}, @var{m}, @var{ts})
@deftypefnx {Function File} {@var{y} =} sgolayfilt (@var{x}, @var{f})
 Smooth the data in x with a Savitsky-Golay smoothing filter of
 polynomial order p and length n, n odd, n > p.  By default, p=3
 and n=p+2 or n=p+3 if p is even.

 If @var{f} is given as a matrix, it is expected to be a filter as
 computed by @code{sgolay}.

 These filters are particularly good at preserving lineshape while
 removing high frequency squiggles. Particularly, compare a 5 sample
 averager, an order 5 butterworth lowpass filter (cutoff 1/3) and
 sgolayfilt(x, 3, 5), the best cubic estimated from 5 points:

@example
@group
 [b, a] = butter (5, 1/3);
 x = [zeros(1,15), 10*ones(1,10), zeros(1,15)];
 plot (sgolayfilt (x), "r;sgolayfilt;", ...
       filtfilt (ones (1,5)/5, 1, x), "g;5 sample average;", ...
       filtfilt (b, a, x), "c;order 5 butterworth;", ...
       x, "+b;original data;");
@end group
@end example

@xseealso{sgolay}
@end deftypefn
@c Filtering sosfilt
@c -----------------------------------------
@subsection sosfilt
@cindex sosfilt
@deftypefn {Loadable Function} {@var{y} =} sosfilt (@var{sos}, @var{x})
Second order section IIR filtering of @var{x}.  The second order section
filter is described by the matrix @var{sos} with:

@multitable {col 1} {this is column two}
@item @tab [ @var{B1} @var{A1} ]@*
@item @var{sos} = @tab [ @dots{} ],@*
@item @tab [ @var{BN} @var{AN} ]@*
@end multitable

where @code{@var{B1} = [b0 b1 b2]} and @code{@var{A1} = [1 a1 a2]} for
section 1, etc.  The b0 entry must be nonzero for each section.
@end deftypefn

@c ---------------------------------------------------
@node Filter Analysis
@section Filter Analysis
@cindex Filter Analysis
@c Filter Analysis filternorm
@c -----------------------------------------
@subsection filternorm
@cindex filternorm
@deftypefn  {Function File} {@var{L} = } filternorm (@var{b}, @var{a})
@deftypefnx {Function File} {@var{L} = } filternorm (@var{b}, @var{a}, @var{pnorm})
@deftypefnx {Function File} {@var{L} = } filternorm (@var{b}, @var{a}, 2, @var{tol})

 Compute the 2-norm of a digital filter defined by the numerator coefficients,
@var{b}, and the denominator coefficients, @var{a}. It is also possible to
 compute the infinity-norm by passing inf in the @var{pnorm} parameter.
@var{pnorm} only accepts 2 or inf.

 Example:
@example
 [b, a] = butter (8, 0.5);
 filternorm (b, a)
@end example
@end deftypefn
@c Filter Analysis filtord
@c -----------------------------------------
@subsection filtord
@cindex filtord
@deftypefn  {Function File} {@var{n} = } filtord (@var{b}, @var{a})
@deftypefnx {Function File} {@var{n} = } filtord (@var{sos})

 Returns the filter order @var{n} for a filter defined by the numerator
 coefficients, @var{b}, and the denominator coefficients, @var{a}.
 It also accepts a filter defined by a matrix of second-order sections,
@var{sos}.

 Example:
@example
 [b, a] = butter (8, 0.5);
 filtord (b, a)
@end example
@end deftypefn
@c Filter Analysis freqs
@c -----------------------------------------
@subsection freqs
@cindex freqs
@deftypefn  {Function File} {@var{h} =} freqs (@var{b}, @var{a}, @var{w})
@deftypefnx {Function File} {} freqs (@var{b}, @var{a}, @var{w})

 Compute the s-plane frequency response of the IIR filter B(s)/A(s) as
 H = polyval(B,j*W)./polyval(A,j*W).  If called with no output
 argument, a plot of magnitude and phase are displayed.

 Example:
@example
 b = [1 2]; a = [1 1];
 w = linspace (0, 4, 128);
 freqs (b, a, w);
@end example
@end deftypefn
@c Filter Analysis freqs_plot
@c -----------------------------------------
@subsection freqs_plot
@cindex freqs_plot
@deftypefn {Function File} {} freqs_plot (@var{w}, @var{h})
 Plot the amplitude and phase of the vector @var{h}.
@end deftypefn
@c Filter Analysis fwhm
@c -----------------------------------------
@subsection fwhm
@cindex fwhm
@deftypefn  {Function File} {@var{f} =} fwhm (@var{y})
@deftypefnx {Function File} {@var{f} =} fwhm (@var{x}, @var{y})
@deftypefnx {Function File} {@var{f} =} fwhm (@dots{}, "zero")
@deftypefnx {Function File} {@var{f} =} fwhm (@dots{}, "min")
@deftypefnx {Function File} {@var{f} =} fwhm (@dots{}, "alevel", @var{level})
@deftypefnx {Function File} {@var{f} =} fwhm (@dots{}, "rlevel", @var{level})

 Compute peak full-width at half maximum (FWHM) or at another level of peak
 maximum for vector or matrix data @var{y}, optionally sampled as @math{y(x)}.
 If @var{y} is a matrix, return FWHM for each column as a row vector.

 The default option "zero" computes fwhm at half maximum, i.e.
@math{0.5*max(y)}.  The option "min" computes fwhm at the middle curve, i.e.
@math{0.5*(min(y)+max(y))}.

 The option "rlevel" computes full-width at the given relative level of peak
 profile, i.e. at @math{rlevel*max(y)} or @math{rlevel*(min(y)+max(y))},
 respectively.  For example, @code{fwhm (@dots{}, "rlevel", 0.1)} computes
 full width at 10 % of peak maximum with respect to zero or minimum; FWHM is
 equivalent to @code{fwhm(@dots{}, "rlevel", 0.5)}.

 The option "alevel" computes full-width at the given absolute level of
@var{y}.

 Return 0 if FWHM does not exist (e.g. monotonous function or the function
 does not cut horizontal line at @math{rlevel*max(y)} or
@math{rlevel*(max(y)+min(y))} or alevel, respectively).

@end deftypefn
@c Filter Analysis grpdelay
@c -----------------------------------------
@subsection grpdelay
@cindex grpdelay
@deftypefn  {Function File} {[@var{g}, @var{w}] =} grpdelay (@var{b})
@deftypefnx {Function File} {[@var{g}, @var{w}] =} grpdelay (@var{b}, @var{a})
@deftypefnx {Function File} {[@var{g}, @var{w}] =} grpdelay (@dots{}, @var{n})
@deftypefnx {Function File} {[@var{g}, @var{w}] =} grpdelay (@dots{}, @var{n}, "whole")
@deftypefnx {Function File} {[@var{g}, @var{f}] =} grpdelay (@dots{}, @var{n}, @var{Fs})
@deftypefnx {Function File} {[@var{g}, @var{f}] =} grpdelay (@dots{}, @var{n}, "whole", @var{Fs})
@deftypefnx {Function File} {[@var{g}, @var{w}] =} grpdelay (@dots{}, @var{w})
@deftypefnx {Function File} {[@var{g}, @var{f}] =} grpdelay (@dots{}, @var{f}, @var{Fs})
@deftypefnx {Function File} {} grpdelay (@dots{})
 Compute the group delay of a filter.

 [g, w] = grpdelay(b)
   returns the group delay g of the FIR filter with coefficients b.
   The response is evaluated at 512 angular frequencies between 0 and
   pi. w is a vector containing the 512 frequencies.
   The group delay is in units of samples.  It can be converted
   to seconds by multiplying by the sampling period (or dividing by
   the sampling rate fs).

 [g, w] = grpdelay(b,a)
   returns the group delay of the rational IIR filter whose numerator
   has coefficients b and denominator coefficients a.

 [g, w] = grpdelay(b,a,n)
   returns the group delay evaluated at n angular frequencies.  For fastest
   computation n should factor into a small number of small primes.

 [g, w] = grpdelay(b,a,n,'whole')
   evaluates the group delay at n frequencies between 0 and 2*pi.

 [g, f] = grpdelay(b,a,n,Fs)
   evaluates the group delay at n frequencies between 0 and Fs/2.

 [g, f] = grpdelay(b,a,n,'whole',Fs)
   evaluates the group delay at n frequencies between 0 and Fs.

 [g, w] = grpdelay(b,a,w)
   evaluates the group delay at frequencies w (radians per sample).

 [g, f] = grpdelay(b,a,f,Fs)
   evaluates the group delay at frequencies f (in Hz).

 grpdelay(...)
   plots the group delay vs. frequency.

 If the denominator of the computation becomes too small, the group delay
 is set to zero.  (The group delay approaches infinity when
 there are poles or zeros very close to the unit circle in the z plane.)

 Theory: group delay, g(w) = -d/dw [arg@{H(e^jw)@}],  is the rate of change of
 phase with respect to frequency.  It can be computed as:

@example
               d/dw H(e^-jw)
        g(w) = -------------
                 H(e^-jw)
@end example

 where

@example
         H(z) = B(z)/A(z) = sum(b_k z^k)/sum(a_k z^k).
@end example

 By the quotient rule,

@example
                    A(z) d/dw B(z) - B(z) d/dw A(z)
        d/dw H(z) = -------------------------------
                               A(z) A(z)
@end example

 Substituting into the expression above yields:

@example
                A dB - B dA
        g(w) =  ----------- = dB/B - dA/A
                    A B
@end example

 Note that,

@example
        d/dw B(e^-jw) = sum(k b_k e^-jwk)
        d/dw A(e^-jw) = sum(k a_k e^-jwk)
@end example

 which is just the FFT of the coefficients multiplied by a ramp.

 As a further optimization when nfft>>length(a), the IIR filter (b,a)
 is converted to the FIR filter conv(b,fliplr(conj(a))).
 For further details, see
 http://ccrma.stanford.edu/~jos/filters/Numerical_Computation_Group_Delay.html
@end deftypefn
@c Filter Analysis impz
@c -----------------------------------------
@subsection impz
@cindex impz
@deftypefn  {Function File} {[@var{x}, @var{t}] =} impz (@var{b})
@deftypefnx {Function File} {[@var{x}, @var{t}] =} impz (@var{b}, @var{a})
@deftypefnx {Function File} {[@var{x}, @var{t}] =} impz (@var{b}, @var{a}, @var{n})
@deftypefnx {Function File} {[@var{x}, @var{t}] =} impz (@var{b}, @var{a}, @var{n}, @var{fs})
@deftypefnx {Function File} {} impz (@dots{})

 Generate impulse-response characteristics of the filter. The filter
 coefficients correspond to the the z-plane rational function with
 numerator b and denominator a.  If a is not specified, it defaults to
 1. If n is not specified, or specified as [], it will be chosen such
 that the signal has a chance to die down to -120dB, or to not explode
 beyond 120dB, or to show five periods if there is no significant
 damping. If no return arguments are requested, plot the results.

@xseealso{freqz, zplane}
@end deftypefn
@c Filter Analysis isallpass
@c -----------------------------------------
@subsection isallpass
@cindex isallpass
@deftypefn  {Function File} {@var{L} = } isallpass (@var{b}, @var{a})
@deftypefnx {Function File} {@var{L} = } isallpass (@var{sos})

 Determine whether a digital filter is allpass. The filter might be defined
 by the numerator coefficients, @var{b}, and the denominator coefficients,
@var{a}, or, alternatively, by a matrix of second-order sections, @var{sos}.

 Example:
@example
 a = [1 2 3];
 b = [3 2 1];
 isallpass (b, a)
@end example

 Ref [1] Shyu, Jong-Jy, & Pei, Soo-Chang,
 A new approach to the design of complex all-pass IIR digital filters,
 Signal Processing, 40(2–3), 207–215, 1994.
 https://doi.org/10.1016/0165-1684(94)90068-x

 Ref [2] Vaidyanathan, P. P. Multirate Systems and Filter Banks.
 1st edition, Pearson College Div, 1992.
@end deftypefn
@c Filter Analysis ismaxphase
@c -----------------------------------------
@subsection ismaxphase
@cindex ismaxphase
@deftypefn  {Function File} {@var{L} = } ismaxphase (@var{b}, @var{a})
@deftypefnx {Function File} {@var{L} = } ismaxphase (@var{sos})
@deftypefnx {Function File} {@var{L} = } ismaxphase (@dots{}, @var{tol})

 Determine whether a digital filter is maximum phase (maximum energy-delay).
 The filter might be defined by the numerator coefficients, @var{b}, and the
 denominator coefficients, @var{a}, or, alternatively, by a matrix of
 second-order sections, @var{sos}. A tolerance @var{tol} might be given to
 define when two numbers are close enough to be considered equal.

 Example:
@example
 b = [1 2 4 4 2 1];
 zplane (b);
 ismaxphase (b)
@end example

 Ref [1] Oppenheim, Alan, and Ronald Schafer. Discrete-Time Signal Processing.
 3rd edition, Pearson, 2009.
@end deftypefn
@c Filter Analysis isminphase
@c -----------------------------------------
@subsection isminphase
@cindex isminphase
@deftypefn  {Function File} {@var{L} = } isminphase (@var{b}, @var{a})
@deftypefnx {Function File} {@var{L} = } isminphase (@var{sos})
@deftypefnx {Function File} {@var{L} = } isminphase (@dots{}, @var{tol})

 Determine whether a digital filter is minimum phase. The filter might be defined
 by the numerator coefficients, @var{b}, and the denominator coefficients,
@var{a}, or, alternatively, by a matrix of second-order sections, @var{sos}.
 A toleranve @var{tol} might be given to define when two numbers are close enough
 to be considered equal.

 Example:
@example
 a = [1 0.5]; b = [3 1];
 isminphase (b, a)
@end example

 Ref [1] Oppenheim, Alan, and Ronald Schafer. Discrete-Time Signal Processing.
 3rd edition, Pearson, 2009.
@end deftypefn
@c Filter Analysis isstable
@c -----------------------------------------
@subsection isstable
@cindex isstable
@deftypefn {Function File} {@var{FLAG} =} isstable (@var{B}, @var{A})
 Returns a logical output equal to TRUE, if the filter is stable.
 This can be done with coeffients of the filer @var{B} and @var{A}.
 Alternatively by using a second order sections matrix (SOS).

 Inputs:
@itemize
@item
@var{B}: Numerator coefficients of the filter

@item
@var{A}: Denominator coeffients of the filter. Can be an empty vector.
@end itemize

 Output:
@itemize
@item
@var{FLAG}: Returns a logical output, equal to TRUE if the filter is stable.
@end itemize

 Examples:
@example
   b = [1 2 3 4 5 5 1 2];
   a = [4 5 6 7 9 10 4 6];
   flag = isstable (b, a)
   flag = 0
@end example

 Using SOS
@example
   [z, p, k] = butter (6, 0.7, 'high');
   sos = zp2sos (z, p, k);
   flag = isstable (sos)
   flag = 1
@end example
@end deftypefn
@c Filter Analysis phasez
@c -----------------------------------------
@subsection phasez
@cindex phasez
@deftypefn  {Function File} {[@var{phi}, @var{w}] = } phasez (@var{b}, @var{a}, @var{n})
@deftypefnx {Function File} {[@var{phi}, @var{w}] = } phasez (@var{b}, @var{a})
@deftypefnx {Function File} {[@var{phi}, @var{w}] = } phasez (@var{sos}, @var{n})
@deftypefnx {Function File} {[@var{phi}, @var{w}] = } phasez (@var{sos})
@deftypefnx {Function File} {[@var{phi}, @var{w}] = } phasez (@dots{}, @var{n}, "whole")
@deftypefnx {Function File} {[@var{phi}, @var{w}] = } phasez (@dots{}, @var{n}, Fs)
@deftypefnx {Function File} {} phasez (@dots{})

 Compute the phase response of digital filter defined either by its
 coefficients (@var{b} and @var{a} are the numerator and denominator
 coefficients respectively) or by its second-order sections representation,
 given by the matrix @var{sos}. The output @var{phi} is the phase response
 computed in a vector the vector of frequencies @var{w}.

 The phase response is evaluated at @var{n} angular frequencies between
 0 and
@ifnottex
 pi.
@end ifnottex
@tex
 $\pi$.
@end tex

@noindent
 If @var{a} is omitted, the denominator is assumed to be 1 (this
 corresponds to a simple FIR filter).

 If @var{n} is omitted, a value of 512 is assumed.

 If the third/forth argument, @qcode{"whole"}, is given, the response is
 evaluated at @var{n} angular frequencies between 0 and
@ifnottex
 2*pi.
@end ifnottex
@tex
 $\pi$.
@end tex
 It is possible also to pass the value @qcode{"half"}, which will lead to
 the default behaviour.

 Example:
@example
 [b, a] = butter (2, [.15,.3]);
 phasez (b, a);
@end example

 Ref [1] Oppenheim, Alan, and Ronald Schafer. Discrete-Time Signal Processing.
 3rd edition, Pearson, 2009.

@xseealso{freqz, phasedelay}
@end deftypefn
@c Filter Analysis zplane
@c -----------------------------------------
@subsection zplane
@cindex zplane
@deftypefn  {Function File} {} zplane (@var{z}, @var{p})
@deftypefnx {Function File} {} zplane (@var{b}, @var{a})
 Plot the poles and zeros on a complex plane.  If the arguments are column
 vectors @var{z} and @var{p}, the complex zeros @var{z} and poles @var{p}
 are displayed. If the arguments are row vectors @var{b} and @var{a}, the
 zeros and poles of the transfer function represented by these filter
 coefficients are displayed.

 If @var{z} and @var{p} are matrices, the columns are distinct sets of zeros
 and poles and are displayed together in distinct colors.

 Note that due to the nature of the @code{roots} function, poles and zeros
 may be displayed as occurring around a circle rather than at a single
 point.

 The transfer function is

@example
@group
        B(z)   b0 + b1 z^(-1) + b2 z^(-2) + ... + bM z^(-M)
 H(z) = ---- = --------------------------------------------
        A(z)   a0 + a1 z^(-1) + a2 z^(-2) + ... + aN z^(-N)

               b0          (z - z1) (z - z2) ... (z - zM)
             = -- z^(-M+N) ------------------------------
               a0          (z - p1) (z - p2) ... (z - pN)
@end group
@end example

 If called with only one argument, the poles @var{p} defaults to an empty
 vector, and the denominator coefficient vector @var{a} defaults to 1.
@end deftypefn
@c ---------------------------------------------------
@node Filter Conversion
@section Filter Conversion
@cindex Filter Conversion
@c Filter Conversion polystab
@c Filter Conversion residued
@c -----------------------------------------
@subsection residued
@cindex residued
@deftypefn {Function File} {[@var{r}, @var{p}, @var{f}, @var{m}] =} residued (@var{b}, @var{a})
 Compute the partial fraction expansion (PFE) of filter
@math{H(z) = B(z)/A(z)}.  In the usual PFE function @code{residuez}, the
 IIR part (poles @var{p} and residues @var{r}) is driven @emph{in parallel}
 with the FIR part (@var{f}).  In this variant, the IIR part is driven by
 the @emph{output} of the FIR part.  This structure can be more accurate in
 signal modeling applications.

 INPUTS:
@var{b} and @var{a} are vectors specifying the digital filter
@math{H(z) = B(z)/A(z)}.  See @code{help filter} for documentation of the
@var{b} and @var{a} filter coefficients.

 RETURNED:
@itemize
@item @var{r} = column vector containing the filter-pole residues
@item @var{p} = column vector containing the filter poles
@item @var{f} = row vector containing the FIR part, if any
@item @var{m} = column vector of pole multiplicities
@end itemize

 EXAMPLES:
@example
 See @code{test residued verbose} to see a number of examples.
@end example

 For the theory of operation, see
@indicateurl{http://ccrma.stanford.edu/~jos/filters/residued.html}

@xseealso{residue, residued}
@end deftypefn
@c Filter Conversion residuez
@c -----------------------------------------
@subsection residuez
@cindex residuez
@deftypefn {Function File} {[@var{r}, @var{p}, @var{f}, @var{m}] =} residuez (@var{b}, @var{a})
 Compute the partial fraction expansion of filter @math{H(z) = B(z)/A(z)}.

 INPUTS:
@var{b} and @var{a} are vectors specifying the digital filter
@math{H(z) = B(z)/A(z)}. See @code{help filter} for documentation of the
@var{b} and @var{a} filter coefficients.

 RETURNED:
@itemize
@item @var{r} = column vector containing the filter-pole residues
@item @var{p} = column vector containing the filter poles
@item @var{f} = row vector containing the FIR part, if any
@item @var{m} = column vector of pole multiplicities
@end itemize

 EXAMPLES:
@example
 See @code{test residuez verbose} to see a number of examples.
@end example

 For the theory of operation, see
@indicateurl{http://ccrma.stanford.edu/~jos/filters/residuez.html}

@xseealso{residue, residued}
@end deftypefn
@c Filter Conversion sos2ss
@c -----------------------------------------
@subsection sos2ss
@cindex sos2ss
@deftypefn  {Function File} {[@var{a}, @var{b}, @var{c}, @var{d}] =} sos2ss (@var{sos})
 Convert series second-order sections to state-space.

@xseealso{sos2ss, ss2tf}
@end deftypefn
@c Filter Conversion sos2tf
@c -----------------------------------------
@subsection sos2tf
@cindex sos2tf
@deftypefn  {Function File} {[@var{b}, @var{a}] =} sos2tf (@var{sos})
@deftypefnx {Function File} {[@var{b}, @var{a}] =} sos2tf (@var{sos}, @var{g})
 Convert series second-order sections to transfer function.

 INPUTS:
@itemize

@item
@var{sos} = matrix of series second-order sections, one per row:
@example
@var{sos} = [@var{B1}.' @var{A1}.'; ...; @var{BN}.' @var{AN}.']
@end example
 where
@code{@var{B1}.' = [b0 b1 b2] and @var{A1}.' = [a0 a1 a2]} for
 section 1, etc.

 a0 is usually equal to 1 because all 2nd order transfer functions
 can be scaled so that a0 = 1.
 However, this is not mandatory for this implementation, which supports
 all kinds of transfer functions, including first order transfer functions.
 See @code{filter} for documentation of the second-order direct-form filter
 coefficients @var{B}i and @var{A}i.

@item
@var{g} is an overall gain factor that effectively scales
 the output @var{b} vector (or any one of the input @var{B}i vectors).
 If not given the gain is assumed to be 1.
@end itemize

 RETURNED:
@var{b} and @var{a} are vectors specifying the analog or digital filter
@math{H(s) = B(s)/A(s)} or @math{H(z) = B(z)/A(z)}.
 See @code{filter} for further details.

@xseealso{tf2sos, zp2sos, sos2pz, zp2tf, tf2zp}
@end deftypefn
@c Filter Conversion sos2zp
@c -----------------------------------------
@subsection sos2zp
@cindex sos2zp
@deftypefn  {Function File} {[@var{z}, @var{p}, @var{k}] =} sos2zp (@var{sos})
@deftypefnx {Function File} {[@var{z}, @var{p}, @var{k}] =} sos2zp (@var{sos}, @var{g})
 Convert series second-order sections to zeros, poles, and gains
 (pole residues).

 INPUTS:
@itemize

@item
@var{sos} = matrix of series second-order sections, one per row:
@example
@var{sos} = [@var{B1}.' @var{A1}.'; ...; @var{BN}.' @var{AN}.']
@end example
 where
@code{@var{B1}.' = [b0 b1 b2] and @var{A1}.' = [a0 a1 a2]} for
 section 1, etc.

 a0 is usually equal to 1 because all 2nd order transfer functions can
 be scaled so that a0 = 1.
 However, this is not mandatory for this implementation, which supports
 all kinds of transfer functions, including first order transfer functions.
 See @code{filter} for documentation of the second-order direct-form filter
 coefficients @var{B}i and @var{A}i.

@item
@var{g} is an overall gain factor that effectively scales
 any one of the input @var{B}i vectors.
 If not given the gain is assumed to be 1.
@end itemize

 RETURNED:
@itemize
@item
@var{z} = column-vector containing all zeros (roots of B(z))
@item
@var{p} = column-vector containing all poles (roots of A(z))
@item
@var{k} = overall gain = @var{B}(Inf)
@end itemize

 EXAMPLE:
@example
 [z, p, k] = sos2zp ([1 0 1, 1 0 -0.81; 1 0 0, 1 0 0.49])
   @result{} z =
      0 + 1i
      0 - 1i
      0 + 0i
      0 + 0i
   @result{} p =
     -0.9000 + 0i
      0.9000 + 0i
      0 + 0.7000i
      0 - 0.7000i
   @result{} k =  1
@end example

@xseealso{zp2sos, sos2tf, tf2sos, zp2tf, tf2zp}
@end deftypefn
@c Filter Conversion ss2tf
@c -----------------------------------------
@subsection ss2tf
@cindex ss2tf
@deftypefn {Function File} {[@var{num}, @var{den}] =} ss2tf (@var{a}, @var{b}, @var{c}, @var{d})
 Conversion from state-space to transfer function representation.
 The state space system:
@tex
 $$ \dot x = Ax + Bu $$
 $$ y = Cx + Du $$
@end tex
@ifnottex
@example
@group
       .
       x = Ax + Bu
       y = Cx + Du
@end group
@end example
@end ifnottex

 is converted to a transfer function:
@tex
 $$ G(s) = { { \rm num }(s) \over { \rm den }(s) } $$
@end tex
@ifnottex
@example
@group
                 num(s)
           G(s)=-------
                 den(s)
@end group
@end example
@end ifnottex

@end deftypefn
@c Filter Conversion ss2zp
@c -----------------------------------------
@subsection ss2zp
@cindex ss2zp
@deftypefn {Function File} {[@var{z}, @var{p}, @var{k}] =} ss2zp (@var{a}, @var{b}, @var{c}, @var{d})
 Converts a state space representation to a set of poles and zeros;
@var{k} is a gain associated with the zeros.

@end deftypefn
@c Filter Conversion tf2sos
@c -----------------------------------------
@subsection tf2sos
@cindex tf2sos
@deftypefn  {Function File} {[@var{sos}, @var{g}] =} tf2sos (@var{b}, @var{a})
@deftypefnx {Function File} {@var{sos} =} tf2sos (@var{b}, @var{a})
 Convert direct-form filter coefficients to series second-order sections.

 INPUTS:

@var{b} and @var{a} are vectors specifying the digital filter
@math{H(z) = B(z)/A(z)}.  See @code{filter} for documentation of the @var{b}
 and @var{a} filter coefficients.

 RETURNED:
@itemize
@item
@var{sos} = matrix of series second-order sections, one per row:
@example
@var{sos} = [@var{b1}.' @var{a1}.'; ...; @var{bn}.' @var{an}.']
@end example
 where
@code{@var{B1}.' = [b0 b1 b2] and @var{A1}.' = [1 a1 a2]} for
 section 1, etc.  The b0 entry must be nonzero for each section (zeros at
 infinity not supported).
@item
@var{g} is an overall gain factor that effectively scales
 any one of the @var{B}i vectors.
@end itemize

 If called with only one output argument, the overall filter gain is
 applied to the first second-order section in the matrix @var{sos}.

 EXAMPLE:
@example
 B = [1 0 0 0 0 1];
 A = [1 0 0 0 0 .9];
 [sos, g] = tf2sos (B, A)

 sos =

    1.00000   0.61803   1.00000   1.00000   0.60515   0.95873
    1.00000  -1.61803   1.00000   1.00000  -1.58430   0.95873
    1.00000   1.00000  -0.00000   1.00000   0.97915  -0.00000

 g = 1
@end example

@xseealso{sos2tf, zp2sos, sos2pz, zp2tf, tf2zp}
@end deftypefn
@c Filter Conversion tf2ss
@c -----------------------------------------
@subsection tf2ss
@cindex tf2ss
@deftypefn {Function File} {[@var{a}, @var{b}, @var{c}, @var{d}] =} tf2ss (@var{num}, @var{den})
 Conversion from transfer function to state-space.
 The state space system:
@tex
 $$ \dot x = Ax + Bu $$
 $$ y = Cx + Du $$
@end tex
@ifnottex
@example
@group
       .
       x = Ax + Bu
       y = Cx + Du
@end group
@end example
@end ifnottex
 is obtained from a transfer function:
@tex
 $$ G(s) = { { \rm num }(s) \over { \rm den }(s) } $$
@end tex
@ifnottex
@example
@group
                 num(s)
           G(s)=-------
                 den(s)
@end group
@end example
@end ifnottex

 The state space system matrices obtained from this function
 will be in observable companion form as Wolovich's Observable
 Structure Theorem is used.
@end deftypefn
@c Filter Conversion tf2zp
@c -----------------------------------------
@subsection tf2zp
@cindex tf2zp
@deftypefn {Function File} {[@var{z}, @var{p}, @var{k}] =} tf2zp (@var{num}, @var{den})
 Convert transfer functions to poles-and-zero representations.

 Returns the zeros and poles of the system defined
 by @var{num}/@var{den}.
@var{k} is a gain associated with the system zeros.
@end deftypefn
@c Filter Conversion zp2sos
@c -----------------------------------------
@subsection zp2sos
@cindex zp2sos
@deftypefn  {Function File} {[@var{sos}, @var{g}] =} zp2sos (@var{z})
@deftypefnx {Function File} {[@var{sos}, @var{g}] =} zp2sos (@var{z}, @var{p})
@deftypefnx {Function File} {[@var{sos}, @var{g}] =} zp2sos (@var{z}, @var{p}, @var{k})
@deftypefnx {Function File} {@var{sos} =} zp2sos (@dots{})
 Convert filter poles and zeros to second-order sections.

 INPUTS:
@itemize
@item
@var{z} = column-vector containing the filter zeros
@item
@var{p} = column-vector containing the filter poles
@item
@var{k} = overall filter gain factor. If not given the gain is assumed to be 1.
@end itemize

 RETURNED:
@itemize
@item
@var{sos} = matrix of series second-order sections, one per row:
@example
@var{sos} = [@var{B1}.' @var{A1}.'; ...; @var{BN}.' @var{AN}.']
@end example
 where
@code{@var{B1}.' = [b0 b1 b2] and @var{A1}.' = [a0 a1 a2]} for
 section 1, etc.
 See @code{filter} for documentation of the second-order direct-form filter
 coefficients @var{B}i and %@var{A}i, i=1:N.

@item
@var{g} is the overall gain factor that effectively scales
 any one of the @var{B}i vectors.
@end itemize

 If called with only one output argument, the overall filter gain is
 applied to the first second-order section in the matrix @var{sos}.

 EXAMPLE:
@example
   [z, p, k] = tf2zp ([1 0 0 0 0 1], [1 0 0 0 0 .9]);
   [sos, g] = zp2sos (z, p, k)

 sos =
    1.0000    0.6180    1.0000    1.0000    0.6051    0.9587
    1.0000   -1.6180    1.0000    1.0000   -1.5843    0.9587
    1.0000    1.0000         0    1.0000    0.9791         0

 g =
     1
@end example

@xseealso{sos2zp, sos2tf, tf2sos, zp2tf, tf2zp}
@end deftypefn
@c Filter Conversion zp2ss
@c -----------------------------------------
@subsection zp2ss
@cindex zp2ss
@deftypefn {Function File} {[@var{a}, @var{b}, @var{c}, @var{d}] =} zp2ss (@var{z}, @var{p}, @var{k})
 Conversion from zero / pole to state space.

@strong{Inputs}
@table @var
@item  z
@itemx p
 Vectors of (possibly) complex poles and zeros of a transfer
 function. Complex values must come in conjugate pairs
 (i.e., @math{x+jy} in @var{z} means that @math{x-jy} is also in @var{z}).
@item k
 Real scalar (leading coefficient).
@end table

@strong{Outputs}
@table @var
@item @var{a}
@itemx @var{b}
@itemx @var{c}
@itemx @var{d}
 The state space system, in the form:
@tex
 $$ \dot x = Ax + Bu $$
 $$ y = Cx + Du $$
@end tex
@ifnottex
@example
@group
      .
      x = Ax + Bu
      y = Cx + Du
@end group
@end example
@end ifnottex
@end table
@end deftypefn
@c Filter Conversion zp2tf
@c -----------------------------------------
@subsection zp2tf
@cindex zp2tf
@deftypefn {Function File} {[@var{num}, @var{den}] =} zp2tf (@var{z}, @var{p}, @var{k})
 Converts zeros / poles to a transfer function.

@strong{Inputs}
@table @var
@item  z
@itemx p
 Vectors of (possibly complex) poles and zeros of a transfer
 function.  Complex values must appear in conjugate pairs.
@item k
 Real scalar (leading coefficient).
@end table
@end deftypefn
@c ---------------------------------------------------
@node IIR Filter Design
@section IIR Filter Design
@cindex IIR Filter Design
@c IIR Filter Design besselap
@c -----------------------------------------
@subsection besselap
@cindex besselap
@deftypefn {Function File} {[@var{zero}, @var{pole}, @var{gain}] =} besselap (@var{n})
 Return bessel analog filter prototype.

 References:

 http://en.wikipedia.org/wiki/Bessel_polynomials
@end deftypefn
@c IIR Filter Design besself
@c -----------------------------------------
@subsection besself
@cindex besself
@deftypefn  {Function File} {[@var{b}, @var{a}] =} besself (@var{n}, @var{w})
@deftypefnx {Function File} {[@var{b}, @var{a}] =} besself (@var{n}, @var{w}, "high")
@deftypefnx {Function File} {[@var{z}, @var{p}, @var{g}] =} besself (@dots{})
@deftypefnx {Function File} {[@var{a}, @var{b}, @var{c}, @var{d}] =} besself (@dots{})
@deftypefnx {Function File} {[@dots{}] =} besself (@dots{}, "z")
 Generate a Bessel filter.
 Default is a Laplace space (s) filter.

 [b,a] = besself(n, Wc)
    low pass filter with cutoff pi*Wc radians

 [b,a] = besself(n, Wc, 'high')
    high pass filter with cutoff pi*Wc radians

 [z,p,g] = besself(...)
    return filter as zero-pole-gain rather than coefficients of the
    numerator and denominator polynomials.

 [...] = besself(...,'z')
     return a discrete space (Z) filter, W must be less than 1.

 [a,b,c,d] = besself(...)
  return  state-space matrices

 References:

 Proakis & Manolakis (1992). Digital Signal Processing. New York:
 Macmillan Publishing Company.
@end deftypefn
@c IIR Filter Design bilinear
@c -----------------------------------------
@subsection bilinear
@cindex bilinear
@deftypefn  {Function File} {[@var{Zb}, @var{Za}] =} bilinear (@var{Sb}, @var{Sa}, @var{T})
@deftypefnx {Function File} {[@var{Zb}, @var{Za}] =} bilinear (@var{Sz}, @var{Sp}, @var{Sg}, @var{T})
@deftypefnx {Function File} {[@var{Zz}, @var{Zp}, @var{Zg}] =} bilinear (@dots{})
 Transform a s-plane filter specification into a z-plane
 specification. Filters can be specified in either zero-pole-gain or
 transfer function form. The input form does not have to match the
 output form. 1/T is the sampling frequency represented in the z plane.

 Note: this differs from the bilinear function in the signal processing
 toolbox, which uses 1/T rather than T.

 Theory: Given a piecewise flat filter design, you can transform it
 from the s-plane to the z-plane while maintaining the band edges by
 means of the bilinear transform.  This maps the left hand side of the
 s-plane into the interior of the unit circle.  The mapping is highly
 non-linear, so you must design your filter with band edges in the
 s-plane positioned at 2/T tan(w*T/2) so that they will be positioned
 at w after the bilinear transform is complete.

 The following table summarizes the transformation:

@example
 +---------------+-----------------------+----------------------+
 | Transform     | Zero at x             | Pole at x            |
 |    H(S)       |   H(S) = S-x          |    H(S)=1/(S-x)      |
 +---------------+-----------------------+----------------------+
 |       2 z-1   | zero: (2+xT)/(2-xT)   | zero: -1             |
 |  S -> - ---   | pole: -1              | pole: (2+xT)/(2-xT)  |
 |       T z+1   | gain: (2-xT)/T        | gain: (2-xT)/T       |
 +---------------+-----------------------+----------------------+
@end example

 With tedious algebra, you can derive the above formulae yourself by
 substituting the transform for S into H(S)=S-x for a zero at x or
 H(S)=1/(S-x) for a pole at x, and converting the result into the
 form:

@example
    H(Z)=g prod(Z-Xi)/prod(Z-Xj)
@end example

 Please note that a pole and a zero at the same place exactly cancel.
 This is significant since the bilinear transform creates numerous
 extra poles and zeros, most of which cancel. Those which do not
 cancel have a "fill-in" effect, extending the shorter of the sets to
 have the same number of as the longer of the sets of poles and zeros
 (or at least split the difference in the case of the band pass
 filter). There may be other opportunistic cancellations but I will
 not check for them.

 Also note that any pole on the unit circle or beyond will result in
 an unstable filter.  Because of cancellation, this will only happen
 if the number of poles is smaller than the number of zeros.  The
 analytic design methods all yield more poles than zeros, so this will
 not be a problem.

 References:

 Proakis & Manolakis (1992). Digital Signal Processing. New York:
 Macmillan Publishing Company.
@end deftypefn
@c IIR Filter Design buttap
@c -----------------------------------------
@subsection buttap
@cindex buttap
@deftypefn {Function File} {[@var{z}, @var{p}, @var{g}] =} buttap (@var{n})
 Design lowpass analog Butterworth filter.

 This function exists for @sc{matlab} compatibility only, and is equivalent
 to @code{butter (@var{n}, 1, "s")}.

@xseealso{butter}
@end deftypefn
@c IIR Filter Design butter
@c -----------------------------------------
@subsection butter
@cindex butter
@deftypefn  {Function File} {[@var{b}, @var{a}] =} butter (@var{n}, @var{wc})
@deftypefnx {Function File} {[@var{b}, @var{a}] =} butter (@var{n}, @var{wc}, @var{filter_type})
@deftypefnx {Function File} {[@var{z}, @var{p}, @var{g}] =} butter (@dots{})
@deftypefnx {Function File} {[@var{a}, @var{b}, @var{c}, @var{d}] =} butter (@dots{})
@deftypefnx {Function File} {[@dots{}] =} butter (@dots{}, "s")
 Generate a Butterworth filter.
 Default is a discrete space (Z) filter.

 The cutoff frequency, @var{wc} should be specified in radians for
 analog filters.  For digital filters, it must be a value between zero
 and one.  For bandpass filters, @var{wc} is a two-element vector
 with @code{w(1) < w(2)}.

 The filter type must be one of @qcode{"low"}, @qcode{"high"},
@qcode{"bandpass"}, or @qcode{"stop"}.  The default is @qcode{"low"}
 if @var{wc} is a scalar and @qcode{"bandpass"} if @var{wc} is a
 two-element vector.

 If the final input argument is @qcode{"s"} design an analog Laplace
 space filter.

 Low pass filter with cutoff @code{pi*Wc} radians:

@example
 [b, a] = butter (n, Wc)
@end example

 High pass filter with cutoff @code{pi*Wc} radians:

@example
 [b, a] = butter (n, Wc, "high")
@end example

 Band pass filter with edges @code{pi*Wl} and @code{pi*Wh} radians:

@example
 [b, a] = butter (n, [Wl, Wh])
@end example

 Band reject filter with edges @code{pi*Wl} and @code{pi*Wh} radians:

@example
 [b, a] = butter (n, [Wl, Wh], "stop")
@end example

 Return filter as zero-pole-gain rather than coefficients of the
 numerator and denominator polynomials:

@example
 [z, p, g] = butter (@dots{})
@end example

 Return a Laplace space filter, @var{Wc} can be larger than 1:

@example
 [@dots{}] = butter (@dots{}, "s")
@end example

 Return state-space matrices:

@example
 [a, b, c, d] = butter (@dots{})
@end example

 References:

 Proakis & Manolakis (1992). Digital Signal Processing. New York:
 Macmillan Publishing Company.
@end deftypefn
@c IIR Filter Design buttord
@c -----------------------------------------
@subsection buttord
@cindex buttord
@deftypefn  {Function File} {@var{n} =} buttord (@var{wp}, @var{ws}, @var{rp}, @var{rs})
@deftypefnx {Function File} {@var{n} =} buttord ([@var{wp1}, @var{wp2}], [@var{ws1}, @var{ws2}], @var{rp}, @var{rs})
@deftypefnx {Function File} {@var{n} =} buttord ([@var{wp1}, @var{wp2}], [@var{ws1}, @var{ws2}], @var{rp}, @var{rs}, "s")
@deftypefnx {Function File} {[@var{n}, @var{wc_p}] =} buttord (@dots{})
@deftypefnx {Function File} {[@var{n}, @var{wc_p}, @var{wc_s}] =} buttord (@dots{})
 Compute the minimum filter order of a Butterworth filter with the desired
 response characteristics.  The filter frequency band edges are specified by
 the passband frequency @var{wp} and stopband frequency @var{ws}.  Frequencies
 are normalized to the Nyquist frequency in the range [0,1].  @var{rp} is the
 allowable passband ripple measured in decibels, and @var{rs} is the minimum
 attenuation in the stop band, also in decibels.

 The output arguments @var{n} and @var{wc_p} (or @var{n} and @var{wc_n}) can
 be given as inputs to @code{butter}.
 Using @var{wc_p} makes the filter characteristic touch at least one pass band
 corner and using @var{wc_s} makes the characteristic touch at least one
 stop band corner.

 If @var{wp} and @var{ws} are scalars, then @var{wp} is the passband cutoff
 frequency and @var{ws} is the stopband edge frequency.  If @var{ws} is
 greater than @var{wp}, the filter is a low-pass filter.  If @var{wp} is
 greater than @var{ws}, the filter is a high-pass filter.

 If @var{wp} and @var{ws} are vectors of length 2, then @var{wp} defines the
 passband interval and @var{ws} defines the stopband interval.  If @var{wp}
 is contained within @var{ws} (@var{ws1} < @var{wp1} < @var{wp2} < @var{ws2}),
 the filter is a band-pass filter.  If @var{ws} is contained within @var{wp}
 (@var{wp1} < @var{ws1} < @var{ws2} < @var{wp2}), the filter is a band-stop
 or band-reject filter.

 If the optional argument @code{"s"} is given, the minimum order for an analog
 elliptic filter is computed.  All frequencies @var{wp} and @var{ws} are
 specified in radians per second.

 Theory: For Low pass filters, |H(W)|^2 = 1/[1+(W/Wc)^(2N)] = 10^(-R/10).
 With some algebra, you can solve simultaneously for Wc and N given
 Ws,Rs and Wp,Rp. Rounding N to the next greater integer, one can recalculate
 the allowable range for Wc (filter caracteristic touching the pass band edge
 or the stop band edge).

 For other types of filter, before making the above calculation, the
 requirements must be transformed to LP requirements. After calculation, Wc
 must be transformed back to original filter type.
@xseealso{butter, cheb1ord, cheb2ord, ellipord}
@end deftypefn
@c IIR Filter Design cheb
@c -----------------------------------------
@subsection cheb
@cindex cheb
@deftypefn {Function File} {} cheb (@var{n}, @var{x})
 Returns the value of the nth-order Chebyshev polynomial calculated at
 the point x. The Chebyshev polynomials are defined by the equations:

@example
@group
           / cos(n acos(x),    |x| <= 1
   Tn(x) = |
           \ cosh(n acosh(x),  |x| > 1
@end group
@end example

 If x is a vector, the output is a vector of the same size, where each
 element is calculated as y(i) = Tn(x(i)).
@end deftypefn
@c IIR Filter Design cheb1ap
@c -----------------------------------------
@subsection cheb1ap
@cindex cheb1ap
@deftypefn {Function File} {[@var{z}, @var{p}, @var{g}] =} cheb1ap (@var{n}, @var{Rp})
 Design lowpass analog Chebyshev type I filter.

 This function exists for @sc{matlab} compatibility only, and is equivalent
 to @code{cheby1 (@var{n}, @var{Rp}, 1, "s")}.

@xseealso{cheby1}
@end deftypefn
@c IIR Filter Design cheb1ord
@c -----------------------------------------
@subsection cheb1ord
@cindex cheb1ord
@deftypefn  {Function File} {@var{n} =} cheb1ord (@var{wp}, @var{ws}, @var{rp}, @var{rs})
@deftypefnx {Function File} {@var{n} =} cheb1ord ([@var{wp1}, @var{wp2}], [@var{ws1}, @var{ws2}], @var{rp}, @var{rs})
@deftypefnx {Function File} {@var{n} =} cheb1ord ([@var{wp1}, @var{wp2}], [@var{ws1}, @var{ws2}], @var{rp}, @var{rs}, "s")
@deftypefnx {Function File} {[@var{n}, @var{wc}] =} cheb1ord (@dots{})
@deftypefnx {Function File} {[@var{n}, @var{wc_p}, @var{wc_s}] =} cheb1ord (@dots{})
 Compute the minimum filter order of a Chebyshev type I filter with the
 desired response characteristics. The filter frequency band edges are
 specified by the passband frequency @var{wp} and stopband frequency @var{ws}.
 Frequencies are normalized to the Nyquist frequency in the range [0,1].
@var{rp} is the allowable passband ripple measured in decibels, and @var{rs}
 is the minimum attenuation in the stop band, also in decibels.

 The output arguments @var{n} and @var{wc_p} (or @var{n} and @var{wc_s}) can
 be given as inputs to @code{cheby1}.
 Using @var{wc_p} makes the filter characteristic touch at least one pass band
 corner and using @var{wc_s} makes the characteristic touch at least one
 stop band corner.

 If @var{wp} and @var{ws} are scalars, then @var{wp} is the passband cutoff
 frequency and @var{ws} is the stopband edge frequency.  If @var{ws} is
 greater than @var{wp}, the filter is a low-pass filter.  If @var{wp} is
 greater than @var{ws}, the filter is a high-pass filter.

 If @var{wp} and @var{ws} are vectors of length 2, then @var{wp} defines the
 passband interval and @var{ws} defines the stopband interval.  If @var{wp}
 is contained within @var{ws} (@var{ws1} < @var{wp1} < @var{wp2} < @var{ws2}),
 the filter is a band-pass filter.  If @var{ws} is contained within @var{wp}
 (@var{wp1} < @var{ws1} < @var{ws2} < @var{wp2}), the filter is a band-stop
 or band-reject filter.

 If the optional argument @code{"s"} is given, the minimum order for an analog
 elliptic filter is computed.  All frequencies @var{wp} and @var{ws} are
 specified in radians per second.
@xseealso{buttord, cheby1, cheb2ord, ellipord}
@end deftypefn
@c IIR Filter Design cheb2ap
@c -----------------------------------------
@subsection cheb2ap
@cindex cheb2ap
@deftypefn {Function File} {[@var{z}, @var{p}, @var{g}] =} cheb2ap (@var{n}, @var{Rs})
 Design lowpass analog Chebyshev type II filter.

 This function exists for @sc{matlab} compatibility only, and is equivalent
 to @code{cheby2 (@var{n}, @var{Rs}, 1, "s")}.

 Demo
@example
 demo cheb2ap
@end example

@xseealso{cheby2}
@end deftypefn
@c IIR Filter Design cheb2ord
@c -----------------------------------------
@subsection cheb2ord
@cindex cheb2ord
@deftypefn  {Function File} {@var{n} =} cheb2ord (@var{wp}, @var{ws}, @var{rp}, @var{rs})
@deftypefnx {Function File} {@var{n} =} cheb2ord ([@var{wp1}, @var{wp2}], [@var{ws1}, @var{ws2}], @var{rp}, @var{rs})
@deftypefnx {Function File} {@var{n} =} cheb2ord ([@var{wp1}, @var{wp2}], [@var{ws1}, @var{ws2}], @var{rp}, @var{rs}, "s")
@deftypefnx {Function File} {[@var{n}, @var{wc_s}] =} cheb2ord (@dots{})
@deftypefnx {Function File} {[@var{n}, @var{wc_s}, @var{wc_p}] =} cheb2ord (@dots{})
 Compute the minimum filter order of a Chebyshev type II filter with the
 desired response characteristics. The filter frequency band edges are
 specified by the passband frequency @var{wp} and stopband frequency @var{ws}.
 Frequencies are normalized to the Nyquist frequency in the range [0,1].
@var{rp} is the allowable passband ripple measured in decibels, and @var{rs}
 is the minimum attenuation in the stop band, also in decibels.

 The output arguments @var{n} and @var{wc_p} (or @var{n} and @var{wc_s}) can
 be given as inputs to @code{cheby2}.
 Using @var{wc_p} makes the filter characteristic touch at least one pass band
 corner and using @var{wc_s} makes the characteristic touch at least one
 stop band corner.

 If @var{wp} and @var{ws} are scalars, then @var{wp} is the passband cutoff
 frequency and @var{ws} is the stopband edge frequency.  If @var{ws} is
 greater than @var{wp}, the filter is a low-pass filter.  If @var{wp} is
 greater than @var{ws}, the filter is a high-pass filter.

 If @var{wp} and @var{ws} are vectors of length 2, then @var{wp} defines the
 passband interval and @var{ws} defines the stopband interval.  If @var{wp}
 is contained within @var{ws} (@var{ws1} < @var{wp1} < @var{wp2} < @var{ws2}),
 the filter is a band-pass filter.  If @var{ws} is contained within @var{wp}
 (@var{wp1} < @var{ws1} < @var{ws2} < @var{wp2}), the filter is a band-stop
 or band-reject filter.

 If the optional argument @code{"s"} is given, the minimum order for an analog
 elliptic filter is computed.  All frequencies @var{wp} and @var{ws} are
 specified in radians per second.
@xseealso{buttord, cheb1ord, cheby2, ellipord}
@end deftypefn
@c IIR Filter Design cheby1
@c -----------------------------------------
@subsection cheby1
@cindex cheby1
@deftypefn  {Function File} {[@var{b}, @var{a}] =} cheby1 (@var{n}, @var{rp}, @var{w})
@deftypefnx {Function File} {[@var{b}, @var{a}] =} cheby1 (@var{n}, @var{rp}, @var{w}, "high")
@deftypefnx {Function File} {[@var{b}, @var{a}] =} cheby1 (@var{n}, @var{rp}, [@var{wl}, @var{wh}])
@deftypefnx {Function File} {[@var{b}, @var{a}] =} cheby1 (@var{n}, @var{rp}, [@var{wl}, @var{wh}], "stop")
@deftypefnx {Function File} {[@var{z}, @var{p}, @var{g}] =} cheby1 (@dots{})
@deftypefnx {Function File} {[@var{a}, @var{b}, @var{c}, @var{d}] =} cheby1 (@dots{})
@deftypefnx {Function File} {[@dots{}] =} cheby1 (@dots{}, "s")
 Generate a Chebyshev type I filter with @var{rp} dB of passband ripple.

 [b, a] = cheby1(n, Rp, Wc)
    low pass filter with cutoff pi*Wc radians

 [b, a] = cheby1(n, Rp, Wc, 'high')
    high pass filter with cutoff pi*Wc radians

 [b, a] = cheby1(n, Rp, [Wl, Wh])
    band pass filter with edges pi*Wl and pi*Wh radians

 [b, a] = cheby1(n, Rp, [Wl, Wh], 'stop')
    band reject filter with edges pi*Wl and pi*Wh radians

 [z, p, g] = cheby1(...)
    return filter as zero-pole-gain rather than coefficients of the
    numerator and denominator polynomials.

 [...] = cheby1(...,'s')
     return a Laplace space filter, W can be larger than 1.

 [a,b,c,d] = cheby1(...)
  return  state-space matrices

 References:

 Parks & Burrus (1987). Digital Filter Design. New York:
 John Wiley & Sons, Inc.
@end deftypefn
@c IIR Filter Design cheby2
@c -----------------------------------------
@subsection cheby2
@cindex cheby2
@deftypefn  {Function File} {[@var{b}, @var{a}] =} cheby2 (@var{n}, @var{rs}, @var{wc})
@deftypefnx {Function File} {[@var{b}, @var{a}] =} cheby2 (@var{n}, @var{rs}, @var{wc}, "high")
@deftypefnx {Function File} {[@var{b}, @var{a}] =} cheby2 (@var{n}, @var{rs}, [@var{wl}, @var{wh}])
@deftypefnx {Function File} {[@var{b}, @var{a}] =} cheby2 (@var{n}, @var{rs}, [@var{wl}, @var{wh}], "stop")
@deftypefnx {Function File} {[@var{z}, @var{p}, @var{g}] =} cheby2 (@dots{})
@deftypefnx {Function File} {[@var{a}, @var{b}, @var{c}, @var{d}] =} cheby2 (@dots{})
@deftypefnx {Function File} {[@dots{}] =} cheby2 (@dots{}, "s")
 Generate a Chebyshev type II filter with @var{rs} dB of stopband attenuation.

 [b, a] = cheby2(n, Rs, Wc)
    low pass filter with cutoff pi*Wc radians

 [b, a] = cheby2(n, Rs, Wc, 'high')
    high pass filter with cutoff pi*Wc radians

 [b, a] = cheby2(n, Rs, [Wl, Wh])
    band pass filter with edges pi*Wl and pi*Wh radians

 [b, a] = cheby2(n, Rs, [Wl, Wh], 'stop')
    band reject filter with edges pi*Wl and pi*Wh radians

 [z, p, g] = cheby2(...)
    return filter as zero-pole-gain rather than coefficients of the
    numerator and denominator polynomials.

 [...] = cheby2(...,'s')
     return a Laplace space filter, W can be larger than 1.

 [a,b,c,d] = cheby2(...)
  return  state-space matrices

 References:

 Parks & Burrus (1987). Digital Filter Design. New York:
 John Wiley & Sons, Inc.
@end deftypefn
@c IIR Filter Design ellip
@c -----------------------------------------
@subsection ellip
@cindex ellip
@deftypefn  {Function File} {[@var{b}, @var{a}] =} ellip (@var{n}, @var{rp}, @var{rs}, @var{wp})
@deftypefnx {Function File} {[@var{b}, @var{a}] =} ellip (@var{n}, @var{rp}, @var{rs}, @var{wp}, "high")
@deftypefnx {Function File} {[@var{b}, @var{a}] =} ellip (@var{n}, @var{rp}, @var{rs}, @var{[wl}, @var{wh}])
@deftypefnx {Function File} {[@var{b}, @var{a}] =} ellip (@var{n}, @var{rp}, @var{rs}, @var{[wl}, @var{wh}], "stop")
@deftypefnx {Function File} {[@var{z}, @var{p}, @var{g}] =} ellip (@dots{})
@deftypefnx {Function File} {[@var{a}, @var{b}, @var{c}, @var{d}] =} ellip (@dots{})
@deftypefnx {Function File} {[@dots{}] =} ellip (@dots{}, "s")

 Generate an elliptic or Cauer filter with @var{rp} dB of passband ripple and
@var{rs} dB of stopband attenuation.

 [b,a] = ellip(n, Rp, Rs, Wp)
  low pass filter with order n, cutoff pi*Wp radians, Rp decibels
  of ripple in the passband and a stopband Rs decibels down.

 [b,a] = ellip(n, Rp, Rs, Wp, 'high')
  high pass filter with cutoff pi*Wp...

 [b,a] = ellip(n, Rp, Rs, [Wl, Wh])
  band pass filter with band pass edges pi*Wl and pi*Wh ...

 [b,a] = ellip(n, Rp, Rs, [Wl, Wh], 'stop')
  band reject filter with edges pi*Wl and pi*Wh, ...

 [z,p,g] = ellip(...)
  return filter as zero-pole-gain.

 [...] = ellip(...,'s')
     return a Laplace space filter, W can be larger than 1.

 [a,b,c,d] = ellip(...)
  return  state-space matrices

 References:

 - Oppenheim, Alan V., Discrete Time Signal Processing, Hardcover, 1999.
 - Parente Ribeiro, E., Notas de aula da disciplina TE498 -  Processamento
   Digital de Sinais, UFPR, 2001/2002.
@end deftypefn
@c IIR Filter Design ellipap
@c -----------------------------------------
@subsection ellipap
@cindex ellipap
@deftypefn {Function File} {[@var{z}, @var{p}, @var{g}] =} ellipap (@var{n}, @var{Rp}, @var{Rs})
 Design lowpass analog elliptic filter.

 This function exists for @sc{matlab} compatibility only, and is equivalent
 to @code{ellip (@var{n}, @var{Rp}, @var{Rs}, 1, "s")}.

@xseealso{ellip}
@end deftypefn
@c IIR Filter Design ellipord
@c -----------------------------------------
@subsection ellipord
@cindex ellipord
@deftypefn  {Function File} {@var{n} =} ellipord (@var{wp}, @var{ws}, @var{rp}, @var{rs})
@deftypefnx {Function File} {@var{n} =} ellipord ([@var{wp1}, @var{wp2}], [@var{ws1}, @var{ws2}], @var{rp}, @var{rs})
@deftypefnx {Function File} {@var{n} =} ellipord ([@var{wp1}, @var{wp2}], [@var{ws1}, @var{ws2}], @var{rp}, @var{rs}, "s")
@deftypefnx {Function File} {[@var{n}, @var{wc}] =} ellipord (@dots{})
 Compute the minimum filter order of an elliptic filter with the desired
 response characteristics.  The filter frequency band edges are specified
 by the passband frequency @var{wp} and stopband frequency @var{ws}.
 Frequencies are normalized to the Nyquist frequency in the range [0,1].
@var{rp} is the allowable passband ripple measured in decibels, and @var{rs}
 is the minimum attenuation in the stop band, also in decibels.  The output
 arguments @var{n} and @var{wc} can be given as inputs to @code{ellip}.

 If @var{wp} and @var{ws} are scalars, then @var{wp} is the passband cutoff
 frequency and @var{ws} is the stopband edge frequency.  If @var{ws} is
 greater than @var{wp}, the filter is a low-pass filter.  If @var{wp} is
 greater than @var{ws}, the filter is a high-pass filter.

 If @var{wp} and @var{ws} are vectors of length 2, then @var{wp} defines the
 passband interval and @var{ws} defines the stopband interval.  If @var{wp}
 is contained within @var{ws} (@var{ws1} < @var{wp1} < @var{wp2} < @var{ws2}),
 the filter is a band-pass filter.  If @var{ws} is contained within @var{wp}
 (@var{wp1} < @var{ws1} < @var{ws2} < @var{wp2}), the filter is a band-stop
 or band-reject filter.

 If the optional argument @code{"s"} is given, the minimum order for an analog
 elliptic filter is computed.  All frequencies @var{wp} and @var{ws} are
 specified in radians per second.

 Reference: Lamar, Marcus Vinicius, @cite{Notas de aula da disciplina TE 456 -
 Circuitos Analogicos II}, UFPR, 2001/2002.
@xseealso{buttord, cheb1ord, cheb2ord, ellip}
@end deftypefn
@c IIR Filter Design firpm
@c -----------------------------------------
@subsection firpm
@cindex firpm
@deftypefn  {Loadable Function} {@var{b} =} firpm (@var{n}, @var{f}, @var{a})
@deftypefnx {Loadable Function} {@var{b} =} firpm (@var{n}, @var{f}, @@@var{respFn})
@deftypefnx {Loadable Function} {@var{b} =} firpm (@var{n}, @var{f}, @{@@@var{respFn}, @dots{}@})
@deftypefnx {Loadable Function} {@var{b} =} firpm (@dots{}, @var{w})
@deftypefnx {Loadable Function} {@var{b} =} firpm (@dots{}, @var{class})
@deftypefnx {Loadable Function} {@var{b} =} firpm (@dots{}, @{@var{accuracy, @dots{}@}})
@deftypefnx {Loadable Function} {[@var{b}, @var{minimax}] =} firpm (@dots{})
@deftypefnx {Loadable Function} {[@var{b}, @var{minimax}, @var{res}] =} firpm (@dots{})
@cindex signal processing

Designs a linear-phase FIR filter according to given specifications and the
`minimax' criterion.  The method (per McClellan et al.@footnote{ J. H.
McClellan, T.  W. Parks and L. R.  Rabiner, `A Computer Program for Designing
Optimum FIR Linear Phase Digital Filters', IEEE Trans.@: Audio Electroacoust.,
vol.@: AU-21, 1973, pp.@: 506--525.}) uses successive approximation to minimize
the maximum weighted error between the desired and actual frequency response of
the filter.  Such filters are variably described as being `minimax',
`equiripple', or `optimal (in the Chebyshev sense)'.

@heading Arguments

@table @var

@item @dots{}
Where shown as the first argument to @code{firpm}, indicates that any
previously-indicated list of arguments may substitute for the ellipsis.

@item n
A positive integer giving the filter order.

@item f
A vector of real-numbers, increasing in the range [0,1], giving the frequencies
of the left and right edges of each band for which a specific amplitude
response is desired: [l1 r1 l2 r2 @dots{}].  1 represents the
Nyquist-frequency.  Transition-bands are defined implicitly as the regions
between or outside the given bands.

@item a
A vector of real-numbers giving the desired amplitude response.  An amplitude
value is given either for each band edge: [a(l1) a(r1) a(l2) a(r2) @dots{}], or
for each band: [a1 a2 @dots{}].  In the former case, in-band amplitude is
determined by linear interpolation between the given band-edge values.  1
represents unity-gain, 0 represents infinite attenuation, and @minus{}1
represents a phase change of pi radians.

Note that amplitude response is necessarily zero at @var{f}=0 for type III and
IV filters, and at @var{f}=1 for type II and III filters.

@item @@respFn
A handle to a `response function' that supplies the desired amplitude response
and error-weighting.  This, unlike @var{a} above, allows the response to be
arbitrary (subject to the note above).  @qcode{firpm} invokes the response
function according to the following syntax:

@example
@var{ag} = @qcode{respFn} (@var{n},@var{f},@var{g},@var{w}, @dots{})
[@var{ag} @var{wg}] = @qcode{respFn} (@var{n},@var{f},@var{g},@var{w}, @dots{})
@var{symmetry} = @qcode{respFn} ("defaults", @{@var{n},@var{f},@var{g},@var{w}, @dots{}@})
@end example

where:
@itemize
@item
@var{n} and @var{f} are as given to @qcode{firpm}.

@item
@var{w} is as given to @qcode{firpm}, or ones if not given.

@item
@var{ag} and @var{wg} are the desired amplitude and weighting functions
evaluated at each frequency in vector @var{g} (which are frequencies within the
non-transition bands of @var{f}).  Returning @var{ag} alone gives uniform
weighting.

@item
@var{symmetry} is either @qcode{"even"} or @qcode{"odd"}; this provides an
alternative to using the @var{class} values @qcode{"symmetric"}
and @qcode{"antisymmetric"}.

@item
Per the ellipses shown here and above, when @@@var{respFn} is given contained
in a cell-array, any additionally contained values are appended to the
@var{respFn} invocation argument-list.

@end itemize

@item w
When used in conjunction with @var{a}, @var{w} is a vector of positive
real-numbers giving error-weightings to be applied at each given band-edge
[w(l1) w(r1) w(l2) w(r2) @dots{}], or for each band [w1 w2 @dots{}].  In the
former case, in-band weighting is determined by linear interpolation between
the given band-edge values.  A higher relative error weighting yields a lower
relative error.

When used in conjunction with @@@var{respFn}, @var{w} is a vector (constrained
as above) that is passed through to @var{respFn}.

@item class
A string, which may be abbreviated, giving the filter-class:
@itemize

@item
@qcode{"symmetric"} (the default) for type I or II filters,

@item
@qcode{"antisymmetric"} (or @qcode{"hilbert"}) for standard type III or IV
filters,

@item
@qcode{"differentiator"} for type III or IV filters with inverted phase and
with error-weighting (further to @var{w}) of 2/f applied in the pass-band(s).
@end itemize

@item accuracy, @dots{}
Up to three properties contained within a cell-array: @var{accuracy},
@var{persistence}, @var{robustness}, that respectively control how close the
computed filter will be to the ideal minimax solution, the number of
computation iterations over which the required accuracy will be sought, and the
precision of certain internal processing.  Each can each be set to a small
positive number (typically @leq{}3), to increase the relevant item; this may
increase computation time, but the need to do so should be rare.  A value of 0
can be used to leave an item unchanged.

Alternatively, setting @var{accuracy} @geq{}16 emulates @sc{matlab}'s
@var{lgrid} argument.

@end table

@heading Results

If a problem occurs during the computation, a diagnostic message will normally
be displayed.  If this happens, adjusting @var{accuracy}, @var{persistence}, or
@var{robustness} may provide the solution.  Some filters however, may not be
realizable due to machine-precision limitations.  If a filter can be computed,
returned values are as follows:

@table @var

@item b
A length @var{N}+1 row-vector containing the computed filter coefficients.

@item minimax
The absolute value of the minimized, maximum weighted error, or this number
negated if the required accuracy could not be achieved.

@item res
A structure of data relating to the filter computation and a partial
response-analysis of the resultant filter; fields are vectors:
@quotation
@multitable @columnfractions .125 .6
@item @code{fgrid}
@tab Analysis frequencies per @var{f}.
@item @code{des}
@tab Desired amplitude response.
@item @code{wt}
@tab Error weighting.
@item @code{H}
@tab Complex frequency response.
@item @code{error}
@tab Desired minus actual amplitude response.
@item @code{iextr}
@tab Indices of local peaks in @code{error}.
@item @code{fextr}
@tab Frequencies of local peaks in @code{error}.
@end multitable
@end quotation

@end table

Using @var{res} is not recommended because it can be slow to compute and, since
the analysis excludes transition-bands, any `anomalies'@footnote{ Tapio
Saram@"aki, `Finite impulse response filter design', Chapter 4 in `Handbook for
Digital Signal Processing', edited by S.  K. Mitra and J. F. Kaiser, John Wiley
and Sons, New York, 1993, pp.@: 155--277.
(@url{http://www.cs.tut.fi/~ts/Mitra_Kaiser.pdf})} therein are not easy to
discern.  In general, @code{freqz} suffices to check that the response of the
computed filter is satisfactory.

@heading Examples
@example
@group
# Low-pass with frequencies in Hz:
Fs = 96000; Fn = Fs/2; # Sampling & Nyquist frequencies.
b = firpm (50, [0 20000 28000 48000] / Fn, [1 0]);
@end group
@end example

@example
@group
# Type IV high-pass:
b = firpm (31, [0 0.5 0.7 1], [0 1], "antisym");
@end group
@end example

@example
@group
# Inverse-sinc (arbitrary response):
b = firpm (20, [0 0.5 0.9 1], @@(n,f,g) ...
deal ((g<=f(2))./sinc (g), (g>=f(3))*9+1));
@end group
@end example

@example
@group
# Band-pass with filter-response check:
freqz (firpm (40, [0 3 4 6 8 10]/10, [0 1 0]))
@end group
@end example

Further examples can be found in the @code{firpm} and @code{firpmord}
demonstration scripts.

@heading Compatibility
Given invalid filter specifications, Octave emits an error and does not produce
a filter; @sc{matlab} in such circumstances may still produce filter
coefficients.

Unlike with @sc{matlab}, with Octave @var{minimax} can be negative; for
compatibility, take the absolute value.

@xseealso{firpmord}

@end deftypefn

@c IIR Filter Design firpmord
@c -----------------------------------------
@subsection firpmord
@cindex firpmord
@deftypefn  {Function File} {[@var{n}, @var{Fout}, @var{a}, @var{w}] =} firpmord (@var{f}, @var{a}, @var{d})
@deftypefnx {Function File} {[@var{n}, @var{Fout}, @var{a}, @var{w}] =} firpmord (@var{f}, @var{a}, @var{d}, @var{fs})
@deftypefnx {Function File} {@var{c} =} firpmord (@var{f}, @var{a}, @var{d}, "cell")
@deftypefnx {Function File} {@var{c} =} firpmord (@var{f}, @var{a}, @var{d}, @var{fs}, "cell")
@cindex signal processing

 Estimate the filter-order needed for @code{firpm} to design a type-I or
 type-II linear-phase FIR filter according to the given specifications.

@heading Arguments

@table @var

@item f
 A vector of real-numbers, increasing in the range (0, @var{fs}/2), giving the
 frequencies of the left and right edges of each band for which a specific
 amplitude response is desired (omitting 0 and @var{fs}/2, which are implied):
 [r1 l2 r2 @dots{}].  Transition-bands are defined implicitly as the regions
 between the given bands.

@item a
 A vector of real-numbers giving the ideal amplitude response.  An amplitude
 value is given for each band specified by @var{f}: [a1 a2 @dots{}].  1
 represents unity-gain, 0 represents infinite attenuation, and @minus{}1
 represents a phase change of pi radians.

@item d
 A vector of positive real-numbers giving the maximum allowable linear
 deviation from the amplitudes given in @var{a}, thus constraining the actual
 amplitude response (where defined by @var{f}) to be within @var{a} +/@minus{}
@var{d}.  Note that, though related, @var{d} does not equate to
@code{firpm}'s @var{w} argument.

@item fs

 The sampling-frequency, which defaults to 2.

@end table

@heading Usage

 The function returns the estimated filter-order, together with the other
 design specification values, in one of two forms suitable for use with
@code{firpm}.  By default, multiple return values are used; alternatively, by
 giving @qcode{"cell"} (or @qcode{"c"}) as the last argument to @code{firpmord},
 the returned values are contained within a cell-array that can, if desired,
 be passed directly to @code{firpm}.

 The following examples illustrate the use of both mechanisms, as well as
 aspects of @code{firpmord} usage in general:

@example
@group
 # Low-pass; frequencies in kHz:
 [n f a w] = firpmord ([2.5 3], [1 0], [0.01 db2mag(-60)], 8);
 b = firpm (n, f, a, w);
@end group
@end example

@example
@group
 # Band-pass:
 c = firpmord ([3 4 8 9], [0 1 0], [1e-3 1e-2 1e-3], 20, "cell");
 b = firpm (c@{:@});
@end group
@end example

@example
@group
 # High-pass:
 b = firpm (firpmord ([6.4 8]/16, [0 1], [1e-4 0.01], "c")@{:@});
@end group
@end example

 In cases where elements of @var{d} follow a repeating pattern (e.g.@: all the
 elements are equal, or elements corresponding to pass-bands are equal and
 elements corresponding to stop-bands are equal), only as many elements as are
 needed to establish the pattern need be given.

 For example, the following @code{firpmord} invocation pairs are equivalent:

@example
@group
 # Low-pass:
 firpmord ([0.4 0.5], [0 1], [db2mag(-72) db2mag(-72)]);
 firpmord ([0.4 0.5], [0 1], [db2mag(-72)]);
@end group
@end example

@example
@group
 # Multi-band-pass:
 ds = db2mag(-80); dp = 0.01;
 firpmord ([1 2 3 4 5 6 7 8]/10, [0 1 0 1 0], [ds dp ds dp ds]);
 firpmord ([1 2 3 4 5 6 7 8]/10, [0 1 0 1 0], [ds dp]);
@end group
@end example

@heading Notes

 The estimation algorithm used is per Ichige et al.@footnote{ K. Ichige, M.
 Iwaki, algorithm and R. Ishii, `Accurate Estimation of Minimum Filter Length
 for Optimum FIR Digital Filters', IEEE Transactions on Circuits and Systems,
 Vol.@: 47, No.@: 10, 2000, pp.@: 1008--1017} Accuracy tends to decrease as
 the number of bands increases.  Even with two bands (i.e.@: high-pass or
 low-pass), the algorithm may under- or over-estimate.  See the
@code{firpmord} demonstrations for some examples.

 In order to precisely determine the minimum order needed for a particular
 design, @code{firpmord} could be used to seed an algorithm iterating
 invocations of @code{firpm} (as exemplified in demonstration number five).

@heading Related documentation

@xseealso{firpm, kaiserord}

@end deftypefn
@c IIR Filter Design iirlp2mb
@c IIR Filter Design impinvar
@c -----------------------------------------
@subsection impinvar
@cindex impinvar
@deftypefn  {Function File} {[@var{b_out}, @var{a_out}] =} impinvar (@var{b}, @var{a}, @var{fs}, @var{tol})
@deftypefnx {Function File} {[@var{b_out}, @var{a_out}] =} impinvar (@var{b}, @var{a}, @var{fs})
@deftypefnx {Function File} {[@var{b_out}, @var{a_out}] =} impinvar (@var{b}, @var{a})
 Converts analog filter with coefficients @var{b} and @var{a} to digital,
 conserving impulse response.

 If @var{fs} is not specified, or is an empty vector, it defaults to 1Hz.

 If @var{tol} is not specified, it defaults to 0.0001 (0.1%)
 This function does the inverse of impinvar so that the following example should
 restore the original values of @var{a} and @var{b}.

@command{invimpinvar} implements the reverse of this function.
@example
 [b, a] = impinvar (b, a);
 [b, a] = invimpinvar (b, a);
@end example

 Reference: Thomas J. Cavicchi (1996) ``Impulse invariance and multiple-order
 poles''. IEEE transactions on signal processing, Vol 44 (9): 2344--2347

@xseealso{bilinear, invimpinvar}
@end deftypefn
@c IIR Filter Design invimpinvar
@c -----------------------------------------
@subsection invimpinvar
@cindex invimpinvar
@deftypefn  {Function File} {[@var{b_out}, @var{a_out}] =} invimpinvar (@var{b}, @var{a}, @var{fs}, @var{tol})
@deftypefnx {Function File} {[@var{b_out}, @var{a_out}] =} invimpinvar (@var{b}, @var{a}, @var{fs})
@deftypefnx {Function File} {[@var{b_out}, @var{a_out}] =} invimpinvar (@var{b}, @var{a})
 Converts digital filter with coefficients @var{b} and @var{a} to analog,
 conserving impulse response.

 This function does the inverse of impinvar so that the following example should
 restore the original values of @var{a} and @var{b}.
@example
 [b, a] = impinvar (b, a);
 [b, a] = invimpinvar (b, a);
@end example

 If @var{fs} is not specified, or is an empty vector, it defaults to 1Hz.

 If @var{tol} is not specified, it defaults to 0.0001 (0.1%)

 Reference: Thomas J. Cavicchi (1996) ``Impulse invariance and multiple-order
 poles''. IEEE transactions on signal processing, Vol 40 (9): 2344--2347

@xseealso{bilinear, impinvar}
@end deftypefn
@c IIR Filter Design ncauer
@c -----------------------------------------
@subsection ncauer
@cindex ncauer
@deftypefn {Function File} {[@var{z}, @var{p}, @var{g}] =} cauer(@var{Rp}, @var{Rs}, @var{n})
 Analog prototype for Cauer filter.

@table @asis
@item Rp
 Passband ripple
@item Rs
 Stopband ripple
@item n
 Desired order
@item z
 complex vector of zeros for the model.
@item p
 complex vector of poles for the model.
@item g
 gain value.
@end table

 References:

 - Serra, Celso Penteado, Teoria e Projeto de Filtros, Campinas: CARTGRAF,
   1983.

 - Lamar, Marcus Vinicius, Notas de aula da disciplina TE 456 - Circuitos
   Analogicos II, UFPR, 2001/2002.
@end deftypefn
@c IIR Filter Design pei_tseng_notch
@c -----------------------------------------
@subsection pei_tseng_notch
@cindex pei_tseng_notch
@deftypefn {Function File} {[@var{b}, @var{a}] =} pei_tseng_notch (@var{frequencies}, @var{bandwidths})
 Return coefficients for an IIR notch-filter with one or more filter frequencies and according (very narrow) bandwidths
 to be used with @code{filter} or @code{filtfilt}.
 The filter construction is based on an allpass which performs a reversal of phase at the filter frequencies.
 Thus, the mean of the phase-distorted and the original signal has the respective frequencies removed.
 See the demo for an illustration.

 Original source:
 Pei, Soo-Chang, and Chien-Cheng Tseng
 "IIR Multiple Notch Filter Design Based on Allpass Filter"
 1996 IEEE Tencon
 doi: 10.1109/TENCON.1996.608814)
@end deftypefn
@c IIR Filter Design sftrans
@c -----------------------------------------
@subsection sftrans
@cindex sftrans
@deftypefn {Function File} {[@var{Sz}, @var{Sp}, @var{Sg}] =} sftrans (@var{Sz}, @var{Sp}, @var{Sg}, @var{W}, @var{stop})

 Transform band edges of a generic lowpass filter (cutoff at W=1)
 represented in splane zero-pole-gain form.  W is the edge of the
 target filter (or edges if band pass or band stop). Stop is true for
 high pass and band stop filters or false for low pass and band pass
 filters. Filter edges are specified in radians, from 0 to pi (the
 nyquist frequency).

 Theory: Given a low pass filter represented by poles and zeros in the
 splane, you can convert it to a low pass, high pass, band pass or
 band stop by transforming each of the poles and zeros individually.
 The following table summarizes the transformation:

@example
 Transform         Zero at x                  Pole at x
 ----------------  -------------------------  ------------------------
 Low Pass          zero: Fc x/C               pole: Fc x/C
 S -> C S/Fc       gain: C/Fc                 gain: Fc/C
 ----------------  -------------------------  ------------------------
 High Pass         zero: Fc C/x               pole: Fc C/x
 S -> C Fc/S       pole: 0                    zero: 0
                   gain: -x                   gain: -1/x
 ----------------  -------------------------  ------------------------
 Band Pass         zero: b +- sqrt(b^2-FhFl)  pole: b +- sqrt(b^2-FhFl)
        S^2+FhFl   pole: 0                    zero: 0
 S -> C --------   gain: C/(Fh-Fl)            gain: (Fh-Fl)/C
        S(Fh-Fl)   b=x/C (Fh-Fl)/2            b=x/C (Fh-Fl)/2
 ----------------  -------------------------  ------------------------
 Band Stop         zero: b +- sqrt(b^2-FhFl)  pole: b +- sqrt(b^2-FhFl)
        S(Fh-Fl)   pole: +-sqrt(-FhFl)        zero: +-sqrt(-FhFl)
 S -> C --------   gain: -x                   gain: -1/x
        S^2+FhFl   b=C/x (Fh-Fl)/2            b=C/x (Fh-Fl)/2
 ----------------  -------------------------  ------------------------
 Bilinear          zero: (2+xT)/(2-xT)        pole: (2+xT)/(2-xT)
      2 z-1        pole: -1                   zero: -1
 S -> - ---        gain: (2-xT)/T             gain: (2-xT)/T
      T z+1
 ----------------  -------------------------  ------------------------
@end example

 where C is the cutoff frequency of the initial lowpass filter, Fc is
 the edge of the target low/high pass filter and [Fl,Fh] are the edges
 of the target band pass/stop filter.  With abundant tedious algebra,
 you can derive the above formulae yourself by substituting the
 transform for S into H(S)=S-x for a zero at x or H(S)=1/(S-x) for a
 pole at x, and converting the result into the form:

@example
    H(S)=g prod(S-Xi)/prod(S-Xj)
@end example

 The transforms are from the references.  The actual pole-zero-gain
 changes I derived myself.

 Please note that a pole and a zero at the same place exactly cancel.
 This is significant for High Pass, Band Pass and Band Stop filters
 which create numerous extra poles and zeros, most of which cancel.
 Those which do not cancel have a "fill-in" effect, extending the
 shorter of the sets to have the same number of as the longer of the
 sets of poles and zeros (or at least split the difference in the case
 of the band pass filter).  There may be other opportunistic
 cancellations but I will not check for them.

 Also note that any pole on the unit circle or beyond will result in
 an unstable filter.  Because of cancellation, this will only happen
 if the number of poles is smaller than the number of zeros and the
 filter is high pass or band pass.  The analytic design methods all
 yield more poles than zeros, so this will not be a problem.

 References:

 Proakis & Manolakis (1992). Digital Signal Processing. New York:
 Macmillan Publishing Company.
@end deftypefn
@c ---------------------------------------------------
@node FIR Filter Design
@section FIR Filter Design
@cindex FIR Filter Design
@c FIR Filter Design cl2bp
@c -----------------------------------------
@subsection cl2bp
@cindex cl2bp
@deftypefn  {Loadable Function} {@var{h} =} cl2bp (@var{m}, @var{w1}, @var{w2}, @var{up}, @var{lo})
@deftypefnx {Loadable Function} {@var{h} =} cl2bp (@var{m}, @var{w1}, @var{w2}, @var{up}, @var{lo}, @var{gridsize})

Constrained L2 bandpass FIR filter design.  This is a fast implementation of
the algorithm cited below.  Compared to @dfn{remez}, it offers implicit
specification of transition bands, a higher likelihood of convergence, and an
error criterion combining features of both L2 and Chebyshev approaches.

Inputs:

@table @var
@item m
degree of cosine polynomial, i.e. the number of output coefficients will be
@var{m}*2+1
@item  w1
@itemx w2
bandpass filter cutoffs in the range 0 <= @var{w1} < @var{w2} <= pi,
where pi is the Nyquist frequency
@item up
vector of 3 upper bounds for [stopband1, passband, stopband2]
@item lo
vector of 3 lower bounds for [stopband1, passband, stopband2]
@item gridsize
search grid size; larger values may improve accuracy,
but greatly increase calculation time.
@end table

Output:

A vector of @var{m}*2+1 FIR coefficients, or an empty value if the solver
failed to converge.

Example:
@example
@code{h = cl2bp(30, 0.3*pi, 0.6*pi, [0.02, 1.02, 0.02], [-0.02, 0.98, -0.02], 2^11);}
@end example

Original Paper:  I. W. Selesnick, M. Lang, and C. S. Burrus.  A modified
algorithm for constrained least square design of multiband FIR filters without
specified transition bands.
IEEE Trans. on Signal Processing, 46(2):497-501, February 1998.
@end deftypefn
@xseealso{remez}

@c FIR Filter Design fir1
@c -----------------------------------------
@subsection fir1
@cindex fir1
@deftypefn  {Function File} {@var{b} =} fir1 (@var{n}, @var{w})
@deftypefnx {Function File} {@var{b} =} fir1 (@var{n}, @var{w}, @var{type})
@deftypefnx {Function File} {@var{b} =} fir1 (@var{n}, @var{w}, @var{type}, @var{window})
@deftypefnx {Function File} {@var{b} =} fir1 (@var{n}, @var{w}, @var{type}, @var{window}, @var{noscale})

 Produce an order @var{n} FIR filter with the given frequency cutoff @var{w},
 returning the @var{n}+1 filter coefficients in @var{b}.  If @var{w} is a
 scalar, it specifies the frequency cutoff for a lowpass or highpass filter.
 If @var{w} is a two-element vector, the two values specify the edges of a
 bandpass or bandstop filter.  If @var{w} is an N-element vector, each
 value specifies a band edge of a multiband pass/stop filter.

 The filter @var{type} can be specified with one of the following strings:
 "low", "high", "stop", "pass", "bandpass", "DC-0", or "DC-1".  The default
 is "low" is @var{w} is a scalar, "pass" if @var{w} is a pair, or "DC-0" if
@var{w} is a vector with more than 2 elements.

 An optional shaping @var{window} can be given as a vector with length
@var{n}+1.  If not specified, a Hamming window of length @var{n}+1 is used.

 With the option "noscale", the filter coefficients are not normalized. The
 default is to normalize the filter such that the magnitude response of the
 center of the first passband is 1.

 To apply the filter, use the return vector @var{b} with the @code{filter}
 function, for example @code{y = filter (b, 1, x)}.

 Examples:
@example
 freqz (fir1 (40, 0.3));
 freqz (fir1 (15, [0.2, 0.5], "stop"));  # note the zero-crossing at 0.1
 freqz (fir1 (15, [0.2, 0.5], "stop", "noscale"));
@end example
@xseealso{filter, fir2}
@end deftypefn
@c FIR Filter Design fir2
@c -----------------------------------------
@subsection fir2
@cindex fir2
@deftypefn  {Function File} {@var{b} =} fir2 (@var{n}, @var{f}, @var{m})
@deftypefnx {Function File} {@var{b} =} fir2 (@var{n}, @var{f}, @var{m}, @var{grid_n})
@deftypefnx {Function File} {@var{b} =} fir2 (@var{n}, @var{f}, @var{m}, @var{grid_n}, @var{ramp_n})
@deftypefnx {Function File} {@var{b} =} fir2 (@var{n}, @var{f}, @var{m}, @var{grid_n}, @var{ramp_n}, @var{window})

 Produce an order @var{n} FIR filter with arbitrary frequency response
@var{m} over frequency bands @var{f}, returning the @var{n}+1 filter
 coefficients in @var{b}.  The vector @var{f} specifies the frequency band
 edges of the filter response and @var{m} specifies the magnitude response
 at each frequency.

 The vector @var{f} must be nondecreasing over the range [0,1], and the
 first and last elements must be 0 and 1, respectively.  A discontinuous
 jump in the frequency response can be specified by duplicating a band edge
 in @var{f} with different values in @var{m}.

 The resolution over which the frequency response is evaluated can be
 controlled with the @var{grid_n} argument.  The default is 512 or the
 next larger power of 2 greater than the filter length.

 The band transition width for discontinuities can be controlled with the
@var{ramp_n} argument.  The default is @var{grid_n}/25.  Larger values
 will result in wider band transitions but better stopband rejection.

 An optional shaping @var{window} can be given as a vector with length
@var{n}+1.  If not specified, a Hamming window of length @var{n}+1 is used.

 To apply the filter, use the return vector @var{b} with the @code{filter}
 function, for example @code{y = filter (b, 1, x)}.

 Example:
@example
 f = [0, 0.3, 0.3, 0.6, 0.6, 1]; m = [0, 0, 1, 1/2, 0, 0];
 [h, w] = freqz (fir2 (100, f, m));
 plot (f, m, ";target response;", w/pi, abs (h), ";filter response;");
@end example
@xseealso{filter, fir1}
@end deftypefn
@c FIR Filter Design firls
@c -----------------------------------------
@subsection firls
@cindex firls
@deftypefn  {Function File} {@var{b} =} firls (@var{n}, @var{f}, @var{a})
@deftypefnx {Function File} {@var{b} =} firls (@var{n}, @var{f}, @var{a}, @var{w})

 FIR filter design using least squares method. Returns a length @var{n}+1
 linear phase filter such that the integral of the weighted mean
 squared error in the specified bands is minimized.

 The vector @var{f} specifies the frequencies of the band edges, normalized
 so that half the sample frequency is equal to 1.  Each band is specified by
 two frequencies, to the vector must have an even length.

 The vector @var{a} specifies the amplitude of the desired response at each
 band edge.

 The optional argument @var{w} is a weighting function that contains one
 value for each band that weights the mean squared error in that band.

@var{a} must be the same length as @var{f}, and @var{w} must be half the
 length of @var{f}.  @var{n} must be even.  If given an odd value,
@code{firls} increments it by 1.

 The least squares optimization algorithm for computing FIR filter
 coefficients is derived in detail in:

 I. Selesnick, "Linear-Phase FIR Filter Design by Least Squares,"
 http://cnx.org/content/m10577
@end deftypefn
@c FIR Filter Design kaiserord
@c -----------------------------------------
@subsection kaiserord
@cindex kaiserord
@deftypefn  {Function File} {[@var{n}, @var{Wn}, @var{beta}, @var{ftype}] =} kaiserord (@var{f}, @var{m}, @var{dev})
@deftypefnx {Function File} {[@dots{}] =} kaiserord (@var{f}, @var{m}, @var{dev}, @var{fs})

 Return the parameters needed to produce a filter of the desired
 specification from a Kaiser window.  The vector @var{f} contains pairs of
 frequency band edges in the range [0,1].  The vector @var{m} specifies the
 magnitude response for each band.  The values of @var{m} must be zero for
 all stop bands and must have the same magnitude for all pass bands. The
 deviation of the filter @var{dev} can be specified as a scalar or a vector
 of the same length as @var{m}.  The optional sampling rate @var{fs} can be
 used to indicate that @var{f} is in Hz in the range [0,@var{fs}/2].

 The returned value @var{n} is the required order of the filter (the length
 of the filter minus 1).  The vector @var{Wn} contains the band edges of
 the filter suitable for passing to @code{fir1}.  The value @var{beta} is
 the parameter of the Kaiser window of length @var{n}+1 to shape the filter.
 The string @var{ftype} contains the type of filter to specify to
@code{fir1}.

 The Kaiser window parameters n and beta are computed from the
 relation between ripple (A=-20*log10(dev)) and transition width
 (dw in radians) discovered empirically by Kaiser:

@example
@group
           / 0.1102(A-8.7)                        A > 50
    beta = | 0.5842(A-21)^0.4 + 0.07886(A-21)     21 <= A <= 50
           \ 0.0                                  A < 21

    n = (A-8)/(2.285 dw)
@end group
@end example

 Example:
@example
@group
 [n, w, beta, ftype] = kaiserord ([1000, 1200], [1, 0], [0.05, 0.05], 11025);
 b = fir1 (n, w, kaiser (n+1, beta), ftype, "noscale");
 freqz (b, 1, [], 11025);
@end group
@end example
@xseealso{fir1, kaiser}
@end deftypefn
@c FIR Filter Design qp_kaiser
@c -----------------------------------------
@subsection qp_kaiser
@cindex qp_kaiser
@deftypefn  {Function File} {} qp_kaiser (@var{nb}, @var{at})
@deftypefnx {Function File} {} qp_kaiser (@var{nb}, @var{at}, @var{linear})

 Computes a finite impulse response (FIR) filter for use with a
 quasi-perfect reconstruction polyphase-network filter bank. This
 version utilizes a Kaiser window to shape the frequency response of
 the designed filter. Tha number nb of bands and the desired
 attenuation at in the stop-band are given as parameters.

 The Kaiser window is multiplied by the ideal impulse response
 h(n)=a.sinc(a.n) and converted to its minimum-phase version by means
 of a Hilbert transform.

 By using a third non-null argument, the minimum-phase calculation is
 omitted at all.
@end deftypefn
@c FIR Filter Design remez
@c -----------------------------------------
@subsection remez
@cindex remez
@deftypefn  {Loadable Function} {@var{b} =} remez (@var{n}, @var{f}, @var{a})
@deftypefnx {Loadable Function} {@var{b} =} remez (@var{n}, @var{f}, @var{a}, @var{w})
@deftypefnx {Loadable Function} {@var{b} =} remez (@var{n}, @var{f}, @var{a}, @var{w}, @var{ftype})
@deftypefnx {Loadable Function} {@var{b} =} remez (@var{n}, @var{f}, @var{a}, @var{w}, @var{ftype}, @var{griddensity})
Parks-McClellan optimal FIR filter design.
@table @var
@item n
gives the filter order, where the generated filter length taps is n+1
@item f
gives frequency at the band edges [b1 e1 b2 e2 b3 e3 @dots{}]
@item a
gives amplitude at the band edges [a(b1) a(e1) a(b2) a(e2) @dots{}]
@item w
gives weighting applied to each band
@item ftype
is "bandpass", "hilbert" or "differentiator"
@item griddensity
determines how accurately the filter will be
constructed. The minimum value is 16, but higher numbers are
slower to compute.
@end table

Frequency is in the range (0, 1), with 1 being the Nyquist frequency.
@end deftypefn
@c FIR Filter Design sgolay
@c -----------------------------------------
@subsection sgolay
@cindex sgolay
@deftypefn  {Function File} {@var{f} =} sgolay (@var{p}, @var{n})
@deftypefnx {Function File} {@var{f} =} sgolay (@var{p}, @var{n}, @var{m})
@deftypefnx {Function File} {@var{f} =} sgolay (@var{p}, @var{n}, @var{m}, @var{ts})
 Computes the filter coefficients for all Savitzsky-Golay smoothing
 filters of order p for length n (odd). m can be used in order to
 get directly the mth derivative. In this case, ts is a scaling factor.

 The early rows of F smooth based on future values and later rows
 smooth based on past values, with the middle row using half future
 and half past.  In particular, you can use row i to estimate x(k)
 based on the i-1 preceding values and the n-i following values of x
 values as y(k) = F(i,:) * x(k-i+1:k+n-i).

 Normally, you would apply the first (n-1)/2 rows to the first k
 points of the vector, the last k rows to the last k points of the
 vector and middle row to the remainder, but for example if you were
 running on a realtime system where you wanted to smooth based on the
 all the data collected up to the current time, with a lag of five
 samples, you could apply just the filter on row n-5 to your window
 of length n each time you added a new sample.

 Reference: Numerical recipes in C. p 650

@xseealso{sgolayfilt}
@end deftypefn
@c ---------------------------------------------------
@node Transforms
@section Transforms
@cindex Transforms
@c Transforms bitrevorder
@c -----------------------------------------
@subsection bitrevorder
@cindex bitrevorder
@deftypefn  {Function File} {@var{y} =} bitrevorder (@var{x})
@deftypefnx {Function File} {[@var{y} @var{i}] =} bitrevorder (@var{x})
 Reorder the elements of the vector @var{x} in bit-reversed order.
 Equivalent to calling @code{digitrevorder (@var{x}, 2)}.
@xseealso{digitrevorder, fft, ifft}
@end deftypefn
@c Transforms cceps
@c -----------------------------------------
@subsection cceps
@cindex cceps
@deftypefn  {Function File} {} cceps (@var{x})
@deftypefnx {Function File} {} cceps (@var{x}, @var{correct})
 Return the complex cepstrum of the vector @var{x}.
 If the optional argument @var{correct} has the value 1, a correction
 method is applied.  The default is not to do this.
@end deftypefn
@c Transforms cplxreal
@c -----------------------------------------
@subsection cplxreal
@cindex cplxreal
@deftypefn  {Function File} {[@var{zc}, @var{zr}] =} cplxreal (@var{z})
@deftypefnx {Function File} {[@var{zc}, @var{zr}] =} cplxreal (@var{z}, @var{tol})
@deftypefnx {Function File} {[@var{zc}, @var{zr}] =} cplxreal (@var{z}, @var{tol}, @var{dim})
 Sort the numbers @var{z} into complex-conjugate-valued and real-valued
 elements.  The positive imaginary complex numbers of each complex conjugate
 pair are returned in @var{zc} and the real numbers are returned in @var{zr}.

@var{tol} is a weighting factor in the range [0, 1) which determines the
 tolerance of the matching.  The default value is @code{100 * eps} and the
 resulting tolerance for a given complex pair is
@code{@var{tol} * abs (@var{z}(i)))}.

 By default the complex pairs are sorted along the first non-singleton
 dimension of @var{z}.  If @var{dim} is specified, then the complex pairs are
 sorted along this dimension.

 Signal an error if some complex numbers could not be paired.  Signal an
 error if all complex numbers are not exact conjugates (to within @var{tol}).
 Note that there is no defined order for pairs with identical real parts but
 differing imaginary parts.
@xseealso{cplxpair}
@end deftypefn
@c Transforms czt
@c -----------------------------------------
@subsection czt
@cindex czt
@deftypefn  {Function File} {} czt (@var{x})
@deftypefnx {Function File} {} czt (@var{x}, @var{m})
@deftypefnx {Function File} {} czt (@var{x}, @var{m}, @var{w})
@deftypefnx {Function File} {} czt (@var{x}, @var{m}, @var{w}, @var{a})
 Chirp z-transform.  Compute the frequency response starting at a and
 stepping by w for m steps.  a is a point in the complex plane, and
 w is the ratio between points in each step (i.e., radius increases
 exponentially, and angle increases linearly).

 To evaluate the frequency response for the range f1 to f2 in a signal
 with sampling frequency Fs, use the following:

@example
@group
 m = 32;                               ## number of points desired
 w = exp(-j*2*pi*(f2-f1)/((m-1)*Fs));  ## freq. step of f2-f1/m
 a = exp(j*2*pi*f1/Fs);                ## starting at frequency f1
 y = czt(x, m, w, a);
@end group
@end example

 If you don't specify them, then the parameters default to a Fourier
 transform:
     m=length(x), w=exp(-j*2*pi/m), a=1

 If x is a matrix, the transform will be performed column-by-column.
@end deftypefn
@c Transforms dct
@c -----------------------------------------
@subsection dct
@cindex dct
@deftypefn  {Function File} {} dct (@var{x})
@deftypefnx {Function File} {} dct (@var{x}, @var{n})
 Compute the discrete cosine transform of @var{x}.  If @var{n} is given,
 then @var{x} is padded or trimmed to length @var{n} before computing the
 transform.  If @var{x} is a matrix, compute the transform along the columns
 of the the matrix.  The transform is faster if @var{x} is real-valued and
 has even length.

 The discrete cosine transform @var{x} can be defined as follows:

@example
@group
               N-1
   X[k] = w(k) sum x[n] cos (pi (2n+1) k / 2N ),  k = 0, ..., N-1
               n=0
@end group
@end example

 with w(0) = sqrt(1/N) and w(k) = sqrt(2/N), k = 1, ..., N-1.  There
 are other definitions with different scaling of X[k], but this form
 is common in image processing.

@xseealso{idct, dct2, idct2, dctmtx}
@end deftypefn
@c Transforms dct2
@c -----------------------------------------
@subsection dct2
@cindex dct2
@deftypefn  {Function File} {} dct2 (@var{x})
@deftypefnx {Function File} {} dct2 (@var{x}, @var{m}, @var{n})
@deftypefnx {Function File} {} dct2 (@var{x}, [@var{m}, @var{n}])
 Compute the 2-D discrete cosine transform of matrix @var{x}.  If
@var{m} and @var{n} are specified, the input is padded or trimmed
 to the desired size.
@xseealso{dct, idct, idct2}
@end deftypefn
@c Transforms dctmtx
@c -----------------------------------------
@subsection dctmtx
@cindex dctmtx
@deftypefn {Function File} {} dctmtx (@var{n})
 Return the DCT transformation matrix of size @var{n}-by-@var{n}.

 If A is an @var{n}-by-@var{n} matrix, then the following are true:

@example
@group
     T*A    == dct(A),  T'*A   == idct(A)
     T*A*T' == dct2(A), T'*A*T == idct2(A)
@end group
@end example

 A DCT transformation matrix is useful for doing things like jpeg
 image compression, in which an 8x8 DCT matrix is applied to
 non-overlapping blocks throughout an image and only a subblock on the
 top left of each block is kept.  During restoration, the remainder of
 the block is filled with zeros and the inverse transform is applied
 to the block.

@xseealso{dct, idct, dct2, idct2}
@end deftypefn
@c Transforms dftmtx
@c -----------------------------------------
@subsection dftmtx
@cindex dftmtx
@deftypefn {Function File} {@var{d} =} dftmtx (@var{n})
 Compute the @var{n}-by-@var{n} Fourier transformation matrix.  This is
 the matrix @var{d} such that the Fourier transform of a column vector of
 length @var{n} is given by @code{dftmtx(@var{n}) * @var{x}} and the
 inverse Fourier transform is given by @code{inv(dftmtx(@var{n})) * @var{x}}.

 In general this is less efficient than calling the @code{fft} and
@code{ifft} functions directly.
@xseealso{fft, ifft}
@end deftypefn
@c Transforms digitrevorder
@c -----------------------------------------
@subsection digitrevorder
@cindex digitrevorder
@deftypefn  {Function File} {@var{y} =} digitrevorder (@var{x}, @var{r})
@deftypefnx {Function File} {[@var{y}, @var{i}] =} digitrevorder (@var{x}, @var{r})
 Reorder the elements of the vector @var{x} in digit-reversed order.
 The elements of @var{x} are converted to radix @var{r} and reversed.
 The reordered indices of the elements of @var{x} are returned in @var{i}.
@xseealso{bitrevorder, fft, ifft}
@end deftypefn
@c Transforms dst
@c -----------------------------------------
@subsection dst
@cindex dst
@deftypefn  {Function File} {@var{y} =} dst (@var{x})
@deftypefnx {Function File} {@var{y} =} dst (@var{x}, @var{n})
 Computes the type I discrete sine transform of @var{x}.  If @var{n} is given,
 then @var{x} is padded or trimmed to length @var{n} before computing the transform.
 If @var{x} is a matrix, compute the transform along the columns of the
 the matrix.

 The discrete sine transform X of x can be defined as follows:

@verbatim
        N
 X[k] = sum x[n] sin (pi n k / (N+1) ),  k = 1, ..., N
        n=1
@end verbatim

@xseealso{idst}
@end deftypefn
@c Transforms dwt
@c -----------------------------------------
@subsection dwt
@cindex dwt
@deftypefn  {Function File} {[@var{u}, @var{v}] =} dwt (@var{x}, @var{wname})
@deftypefnx {Function File} {[@var{u}, @var{v}] =} dwt (@var{x}, @var{Hp}, @var{Gp})
@deftypefnx {Function File} {[@var{u}, @var{v}] =} dwt (@var{x}, @var{Hp}, @var{Gp}, @dots{})
 Discrete wavelet transform (1D).

@strong{Inputs}
@table @var
@item x
 Signal vector.
@item wname
 Wavelet name.
@item Hp
 Coefficients of low-pass decomposition @acronym{FIR} filter.
@item Gp
 Coefficients of high-pass decomposition @acronym{FIR} filter.
@end table

@strong{Outputs}
@table @var
@item u
 Signal vector of average, approximation.
@item v
 Signal vector of difference, detail.
@end table
@end deftypefn
@c Transforms fht
@c -----------------------------------------
@subsection fht
@cindex fht
@deftypefn  {Function File} {@var{m} =} fht (@var{d})
@deftypefnx {Function File} {@var{m} =} fht (@var{d}, @var{n})
@deftypefnx {Function File} {@var{m} =} fht (@var{d}, @var{n}, @var{dim})
 Calculate the Fast Hartley Transform of real input @var{d}.  If @var{d} is
 a matrix, the Hartley transform is calculated along the columns by default.
 The options @var{n} and @var{dim} are similar to the options of FFT
 function.

 The forward and inverse Hartley transforms are the same (except for a
 scale factor of 1/N for the inverse Hartley transform), but
 implemented using different functions.

 The definition of the forward hartley transform for vector d,
@math{
 m[K] = \sum_{i=0}^{N-1} d[i]*(cos[K*2*pi*i/N] + sin[K*2*pi*i/N]), for  0 <= K < N.
 m[K] = \sum_{i=0}^{N-1} d[i]*CAS[K*i], for  0 <= K < N. }

@example
 fht(1:4)
@end example
@xseealso{ifht, fft}
@end deftypefn
@c Transforms fwht
@c -----------------------------------------
@subsection fwht
@cindex fwht
@deftypefn  {Function File} {} fwht (@var{x})
@deftypefnx {Function File} {} fwht (@var{x}, @var{n})
@deftypefnx {Function File} {} fwht (@var{x}, @var{n}, @var{order})
 Compute the Walsh-Hadamard transform of @var{x} using the Fast
 Walsh-Hadamard Transform (FWHT) algorithm.  If the input is a matrix,
 the FWHT is calculated along the columns of @var{x}.

 The number of elements of @var{x} must be a power of 2; if not, the
 input will be extended and filled with zeros.  If a second argument
 is given, the input is truncated or extended to have length @var{n}.

 The third argument specifies the @var{order} in which the returned
 Walsh-Hadamard transform coefficients should be arranged.  The
@var{order} may be any of the following strings:

@table @asis
@item "sequency"
 The coefficients are returned in sequency order.  This is the default
 if @var{order} is not given.

@item "hadamard"
 The coefficients are returned in Hadamard order.

@item "dyadic"
 The coefficients are returned in Gray code order.
@end table

@xseealso{ifwht}
@end deftypefn
@c Transforms hilbert
@c -----------------------------------------
@subsection hilbert
@cindex hilbert
@deftypefn {Function File} {@var{h} =} hilbert (@var{f}, @var{N}, @var{dim})
 Analytic extension of real valued signal.

@code{@var{h} = hilbert (@var{f})} computes the extension of the real
 valued signal @var{f} to an analytic signal. If @var{f} is a matrix,
 the transformation is applied to each column. For N-D arrays,
 the transformation is applied to the first non-singleton dimension.

@code{real (@var{h})} contains the original signal @var{f}.
@code{imag (@var{h})} contains the Hilbert transform of @var{f}.

@code{hilbert (@var{f}, @var{N})} does the same using a length @var{N}
 Hilbert transform. The result will also have length @var{N}.

@code{hilbert (@var{f}, [], @var{dim})} or
@code{hilbert (@var{f}, @var{N}, @var{dim})} does the same along
 dimension @var{dim}.
@end deftypefn
@c Transforms idct
@c -----------------------------------------
@subsection idct
@cindex idct
@deftypefn  {Function File} {@var{y} =} idct (@var{x})
@deftypefnx {Function File} {@var{y} =} idct (@var{x}, @var{n})
 Compute the inverse discrete cosine transform of @var{x}.  If @var{n} is
 given, then @var{x} is padded or trimmed to length @var{n} before computing
 the transform.  If @var{x} is a matrix, compute the transform along the
 columns of the the matrix.  The transform is faster if @var{x} is
 real-valued and even length.

 The inverse discrete cosine transform @var{x} can be defined as follows:

@example
          N-1
   x[n] = sum w(k) X[k] cos (pi (2n+1) k / 2N ),  n = 0, ..., N-1
          k=0
@end example

 with w(0) = sqrt(1/N) and w(k) = sqrt(2/N), k = 1, ..., N-1

@xseealso{dct, dct2, idct2, dctmtx}
@end deftypefn
@c Transforms idct2
@c -----------------------------------------
@subsection idct2
@cindex idct2
@deftypefn  {Function File} {@var{y} =} idct2 (@var{x})
@deftypefnx {Function File} {@var{y} =} idct2 (@var{x}, @var{m}, @var{n})
@deftypefnx {Function File} {@var{y} =} idct2 (@var{x}, [@var{m}, @var{n}])
 Compute the inverse 2-D discrete cosine transform of matrix @var{x}.
 If @var{m} and @var{n} are specified, the input is either padded or truncated
 to have @var{m} rows and @var{n} columns.
@end deftypefn
@c Transforms idst
@c -----------------------------------------
@subsection idst
@cindex idst
@deftypefn  {Function File} {@var{y} =} idst (@var{x})
@deftypefnx {Function File} {@var{y} =} idst (@var{x}, @var{n})
 Computes the inverse type I discrete sine transform of @var{y}.  If @var{n} is
 given, then @var{y} is padded or trimmed to length @var{n} before computing
 the transform.  If @var{y} is a matrix, compute the transform along the
 columns of the the matrix.
@xseealso{dst}
@end deftypefn
@c Transforms ifht
@c -----------------------------------------
@subsection ifht
@cindex ifht
@deftypefn {Function File} {@var{m} =} ifht (@var{d}, @var{n}, @var{dim})
 Calculate the inverse Fast Hartley Transform of real input @var{d}.  If
@var{d} is a matrix, the inverse Hartley transform is calculated along the
 columns by default.  The options @var{n} and @var{dim} are similar to the
 options of FFT function.

 The forward and inverse Hartley transforms are the same (except for a
 scale factor of 1/N for the inverse hartley transform), but
 implemented using different functions.

 The definition of the forward hartley transform for vector d,
@math{
 m[K] = 1/N \sum_{i=0}^{N-1} d[i]*(cos[K*2*pi*i/N] + sin[K*2*pi*i/N]), for  0 <= K < N.
 m[K] = 1/N \sum_{i=0}^{N-1} d[i]*CAS[K*i], for  0 <= K < N. }

@example
 ifht(1:4)
@end example
@xseealso{fht, fft}
@end deftypefn
@c Transforms ifwht
@c -----------------------------------------
@subsection ifwht
@cindex ifwht
@deftypefn  {Function File} {} ifwht (@var{x})
@deftypefnx {Function File} {} ifwht (@var{x}, @var{n})
@deftypefnx {Function File} {} ifwht (@var{x}, @var{n}, @var{order})
 Compute the inverse Walsh-Hadamard transform of @var{x} using the
 Fast Walsh-Hadamard Transform (FWHT) algorithm.  If the input is a
 matrix, the inverse FWHT is calculated along the columns of @var{x}.

 The number of elements of @var{x} must be a power of 2; if not, the
 input will be extended and filled with zeros.  If a second argument
 is given, the input is truncated or extended to have length @var{n}.

 The third argument specifies the @var{order} in which the returned
 inverse Walsh-Hadamard transform coefficients should be arranged.
 The @var{order} may be any of the following strings:

@table @asis
@item "sequency"
 The coefficients are returned in sequency order.  This is the default
 if @var{order} is not given.

@item "hadamard"
 The coefficients are returned in Hadamard order.

@item "dyadic"
 The coefficients are returned in Gray code order.
@end table

@xseealso{fwht}
@end deftypefn
@c Transforms rceps
@c -----------------------------------------
@subsection rceps
@cindex rceps
@deftypefn {Function File} {[@var{y}, @var{ym}] =} rceps (@var{x})
 Return the cepstrum of the signal @var{x}.

 If @var{x} is a matrix, return the cepstrum of each column.

 If called with two output arguments, the minimum phase reconstruction of
 the signal @var{x} is returned in @var{ym}.

 For example:

@example
@group
 f0 = 70; Fs = 10000;            # 100 Hz fundamental, 10kHz sampling rate
 a = poly (0.985 * exp (1i * pi * [0.1, -0.1, 0.3, -0.3])); # two formants
 s = 0.005 * randn (1024, 1);    # Noise excitation signal
 s(1:Fs/f0:length(s)) = 1;       # Impulse glottal wave
 x = filter (1, a, s);           # Speech signal
 [y, ym] = rceps (x .* hanning (1024));
@end group
@end example

 Reference: @cite{Programs for Digital Signal Processing}, IEEE Press,
 John Wiley & Sons, New York, 1979.
@end deftypefn
@c ---------------------------------------------------
@node Power Spectrum Analysis
@section Power Spectrum Analysis
@cindex Power Spectrum Analysis
@c Power Spectrum Analysis __power
@c -----------------------------------------
@subsection __power
@cindex __power
@deftypefn  {Function File} {[@var{P}, @var{w}] =} __power (@var{b}, @var{a})
@deftypefnx {Function File} {[@dots{}] =} __power (@var{b}, @var{a}, @var{nfft})
@deftypefnx {Function File} {[@dots{}] =} __power (@var{b}, @var{a}, @var{nfft}, @var{Fs})
@deftypefnx {Function File} {[@dots{}] =} __power (@var{b}, @var{a}, @var{nfft}, @var{Fs}, @var{range})
@deftypefnx {Function File} {[@dots{}] =} __power (@var{b}, @var{a}, @var{nfft}, @var{Fs}, @var{range}, @var{units})
@deftypefnx {Function File} {} __power (@dots{})

 Plot the power spectrum of the given ARMA model.

 b, a: filter coefficients (b=numerator, a=denominator)
 nfft is number of points at which to sample the power spectrum
 Fs is the sampling frequency of x
 range is 'half' (default) or 'whole'
 units is  'squared' or 'db' (default)
 range and units may be specified any time after the filter, in either
 order

 Returns P, the magnitude vector, and w, the frequencies at which it
 is sampled.  If there are no return values requested, then plot the power
 spectrum and don't return anything.
@end deftypefn
@c Power Spectrum Analysis ar_psd
@c -----------------------------------------
@subsection ar_psd
@cindex ar_psd
@deftypefn  {Function File} {} ar_psd (@var{a}, @var{v})
@deftypefnx {Function File} {} ar_psd (@var{a}, @var{v}, @var{freq})
@deftypefnx {Function File} {} ar_psd (@var{a}, @var{v}, @var{freq}, @var{Fs})
@deftypefnx {Function File} {} ar_psd (@dots{}, @var{range})
@deftypefnx {Function File} {} ar_psd (@dots{}, @var{method})
@deftypefnx {Function File} {} ar_psd (@dots{}, @var{plottype})
@deftypefnx {Function File} {[@var{psd}, @var{f_out}] =} ar_psd (@dots{})

 Calculate the power spectrum of the autoregressive model

@example
@group
                        M
 x(n) = sqrt(v).e(n) + SUM a(k).x(n-k)
                       k=1
@end group
@end example

 where @math{x(n)} is the output of the model and @math{e(n)} is white noise.
 This function is intended for use with
@code{[a, v, k] = arburg (x, poles, criterion)}
 which use the Burg (1968) method to calculate a "maximum entropy"
 autoregressive model of @var{x}.

 If the @var{freq} argument is a vector (of frequencies) the spectrum is
 calculated using the polynomial method and the @var{method} argument is
 ignored.  For scalar @var{freq}, an integer power of 2, or @var{method} =
 "FFT", causes the spectrum to be calculated by FFT.  Otherwise, the spectrum
 is calculated as a polynomial.  It may be computationally more
 efficient to use the FFT method if length of the model is not much
 smaller than the number of frequency values.  The spectrum is scaled so
 that spectral energy (area under spectrum) is the same as the time-domain
 energy (mean square of the signal).

 ARGUMENTS:
 All but the first two arguments are optional and may be empty.
@itemize
@item
@var{a}
 list of M=(order+1) autoregressive model
 coefficients.  The first element of "ar_coeffs" is the
 zero-lag coefficient, which always has a value of 1.
@item
@var{v}
 square of the moving-average coefficient of the AR model.
@item
@var{freq}
 frequencies at which power spectral density is calculated, or a scalar
 indicating the number of uniformly distributed frequency
 values at which spectral density is calculated.
 (default = 256)
@item
@var{Fs}
 sampling frequency (Hertz) (default=1)
@end itemize

 CONTROL-STRING ARGUMENTS -- each of these arguments is a character string.
 Control-string arguments can be in any order after the other arguments.

 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'.

 Method:

 'fft':  use FFT to calculate power spectrum.
 'poly': calculate power spectrum 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.

 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.

 RETURNED VALUES:
 If returned values are not required by the caller, the spectrum
 is plotted and nothing is returned.
@itemize
@item
@var{psd}
 estimate of power-spectral density
@item
@var{f_out}
 frequency values
@end itemize

 REFERENCE
 [1] Equation 2.28 from Steven M. Kay and Stanley Lawrence Marple Jr.:
   "Spectrum analysis -- a modern perspective",
   Proceedings of the IEEE, Vol 69, pp 1380-1419, Nov., 1981

@end deftypefn
@c Power Spectrum Analysis cohere
@c -----------------------------------------
@subsection cohere
@cindex cohere
@deftypefn {Function File} {[@var{Pxx}, @var{freq}]} = cohere(@var{x},@var{y},@var{Nfft},@var{Fs},@var{window},@var{overlap},@var{range},@var{plot_type},@var{detrend})
 Estimate (mean square) coherence of signals "x" and "y".

 Use the Welch (1967) periodogram/FFT method.

 Compatible with Matlab R11 cohere and earlier.

 See "help pwelch" for description of arguments, hints and references
 --- especially hint (7) for Matlab R11 defaults.
@end deftypefn
@c Power Spectrum Analysis cpsd
@c -----------------------------------------
@subsection cpsd
@cindex cpsd
@deftypefn  {Function File} {[@var{Pxx}, @var{freq}] =} cpsd (@var{x}, @var{y})
@deftypefnx {Function File} {[@dots{}] =} cpsd (@var{x}, @var{y}, @var{window})
@deftypefnx {Function File} {[@dots{}] =} cpsd (@var{x}, @var{y}, @var{window}, @var{overlap})
@deftypefnx {Function File} {[@dots{}] =} cpsd (@var{x}, @var{y}, @var{window}, @var{overlap}, @var{Nfft})
@deftypefnx {Function File} {[@dots{}] =} cpsd (@var{x}, @var{y}, @var{window}, @var{overlap}, @var{Nfft}, @var{Fs})
@deftypefnx {Function File} {[@dots{}] =} cpsd (@var{x}, @var{y}, @var{window}, @var{overlap}, @var{Nfft}, @var{Fs}, @var{range})
@deftypefnx {Function File} {} cpsd (@dots{})

 Estimate cross power spectrum of data @var{x} and @var{y} by the Welch (1967)
 periodogram/FFT method.
@xseealso{pwelch}
@end deftypefn
@c Power Spectrum Analysis csd
@c -----------------------------------------
@subsection csd
@cindex csd
@deftypefn {Function File} {[@var{Pxx},@var{freq}]} = csd(@var{x}, @var{y}, @var{Nfft}, @var{Fs}, @var{window}, @var{overlap}, @var{range}, @var{plot_type}, @var{detrend})
 Estimate cross power spectrum of data "x" and "y" by the Welch (1967)
 periodogram/FFT method.

 Compatible with Matlab R11 csd and earlier.

 See "help pwelch" for description of arguments, hints and references
 --- especially hint (7) for Matlab R11 defaults.
@end deftypefn
@c Power Spectrum Analysis db2pow
@c -----------------------------------------
@subsection db2pow
@cindex db2pow
@deftypefn {Function File} {} db2pow (@var{x})
 Convert decibels (dB) to power.

 The power of @var{x} is defined as
@tex
 $p = 10^{x/10}$.
@end tex
@ifnottex
@var{p} = @code{10 ^ (x/10)}.
@end ifnottex

 If @var{x} is a vector, matrix, or N-dimensional array, the power is
 computed over the elements of @var{x}.

 Example:

@example
@group
 db2pow ([-10, 0, 10])
@result{} 0.1000 1.0000 10.0000
@end group
@end example
@xseealso{pow2db}
@end deftypefn
@c Power Spectrum Analysis mscohere
@c -----------------------------------------
@subsection mscohere
@cindex mscohere
@deftypefn  {Function File} {[@var{Pxx}, @var{freq}] =} mscohere (@var{x}, @var{y})
@deftypefnx {Function File} {[@dots{}] =} mscohere (@var{x}, @var{y}, @var{window})
@deftypefnx {Function File} {[@dots{}] =} mscohere (@var{x}, @var{y}, @var{window}, @var{overlap})
@deftypefnx {Function File} {[@dots{}] =} mscohere (@var{x}, @var{y}, @var{window}, @var{overlap}, @var{Nfft})
@deftypefnx {Function File} {[@dots{}] =} mscohere (@var{x}, @var{y}, @var{window}, @var{overlap}, @var{Nfft}, @var{Fs})
@deftypefnx {Function File} {[@dots{}] =} mscohere (@var{x}, @var{y}, @var{window}, @var{overlap}, @var{Nfft}, @var{Fs}, @var{range})
@deftypefnx {Function File} {} mscohere (@dots{})

 Estimate (mean square) coherence of signals @var{x} and @var{y}.
 Use the Welch (1967) periodogram/FFT method.
@xseealso{pwelch}
@end deftypefn
@c Power Spectrum Analysis pburg
@c -----------------------------------------
@subsection pburg
@cindex pburg
@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
@c Power Spectrum Analysis pow2db
@c -----------------------------------------
@subsection pow2db
@cindex pow2db
@deftypefn {Function File} {} pow2db (@var{x})
 Convert power to decibels (dB).

 The decibel value of @var{x} is defined as
@tex
 $d = 10 * \log_{10} (x)$.
@end tex
@ifnottex
@var{d} = @code{10 * log10 (x)}.
@end ifnottex

 If @var{x} is a vector, matrix, or N-dimensional array, the decibel value
 is computed over the elements of @var{x}.

 Examples:

@example
@group
 pow2db ([0, 10, 100])
@result{} -Inf 10 20
@end group
@end example
@xseealso{db2pow}
@end deftypefn
@c Power Spectrum Analysis pwelch
@c -----------------------------------------
@subsection pwelch
@cindex pwelch
@deftypefn {Function File} {[@var{spectra},@var{freq}] =} pwelch(@var{x}, @var{window}, @var{overlap}, @var{Nfft}, @var{Fs}, @var{range}, @var{plot_type}, @var{detrend}, @var{sloppy})
 Estimate power spectral density of data "x" by the Welch (1967) periodogram/FFT method.

 All arguments except "x" are optional.

 The data is divided into segments.  If "window" is a vector, each
 segment has the same length as "window" and is multiplied by "window"
 before (optional) zero-padding and calculation of its periodogram. If
 "window" is a scalar, each segment has a length of "window" and a
 Hamming window is used.

 The spectral density is the mean of the periodograms, scaled so that
 area under the spectrum is the same as the mean square of the
 data.  This equivalence is supposed to be exact, but in practice there
 is a mismatch of up to 0.5% when comparing area under a periodogram
 with the mean square of the data.

 [spectra,freq] = pwelch(x,y,window,overlap,Nfft,Fs,
                          range,plot_type,detrend,sloppy,results)

 Two-channel spectrum analyser.  Estimate power spectral density, cross-
 spectral density, transfer function and/or coherence functions of time-
 series input data "x" and output data "y" by the Welch (1967)
 periodogram/FFT method.

 pwelch treats the second argument as "y" if there is a control-string
 argument "cross", "trans", "coher" or "ypower"; "power" does not force
 the 2nd argument to be treated as "y".  All other arguments are
 optional.  All spectra are returned in matrix "spectra".

 [spectra,Pxx_ci,freq] = pwelch(x,window,overlap,Nfft,Fs,conf,
                                range,plot_type,detrend,sloppy)

 [spectra,Pxx_ci,freq] = pwelch(x,y,window,overlap,Nfft,Fs,conf,
                                range,plot_type,detrend,sloppy,results)

 Estimates confidence intervals for the spectral density.

 See Hint (7) below for compatibility options.

 Confidence level "conf" is the 6th or 7th numeric argument.  If "results" control-string
 arguments are used, one of them must be "power" when the "conf"
 argument is present; pwelch can estimate confidence intervals only for
 the power spectrum of the "x" data.  It does not know how to estimate
 confidence intervals of the cross-power spectrum, transfer function or
 coherence; if you can suggest a good method, please send a bug report.

 ARGUMENTS

 All but the first argument are optional and may be empty, except that
 the "results" argument may require the second argument to be "y".
@table @asis
@item x
  [non-empty vector] system-input time-series data
@item y
  [non-empty vector] system-output time-series data
@item window
  [real vector] of window-function values between 0 and 1; the
             data segment has the same length as the window.
             Default window shape is Hamming.

  [integer scalar] length of each data segment.  The default
             value is window=sqrt(length(x)) rounded up to the
             nearest integer power of 2; see 'sloppy' argument.

@item overlap
   [real scalar] segment overlap expressed as a multiple of
             window or segment length.   0 <= overlap < 1,
             The default is overlap=0.5 .

@item Nfft
   [integer scalar] Length of FFT.  The default is the length
             of the "window" vector or has the same value as the
             scalar "window" argument.  If Nfft is larger than the
             segment length, "seg_len", the data segment is padded
             with "Nfft-seg_len" zeros.  The default is no padding.
             Nfft values smaller than the length of the data
             segment (or window) are ignored silently.

@item Fs
  [real scalar] sampling frequency (Hertz); default=1.0

@item conf
   [real scalar] confidence level between 0 and 1.  Confidence
             intervals of the spectral density are estimated from
             scatter in the periodograms and are returned as Pxx_ci.
             Pxx_ci(:,1) is the lower bound of the confidence
             interval and Pxx_ci(:,2) is the upper bound.  If there
             are three return values, or conf is an empty matrix,
             confidence intervals are calculated for conf=0.95 .
             If conf is zero or is not given, confidence intervals
             are not calculated. Confidence intervals can be
             obtained only for the power spectral density of x;
             nothing else.
@end table

 CONTROL-STRING ARGUMENTS -- each of these arguments is a character string.
   Control-string arguments must be after the other arguments but can be in
   any order.

@table @asis
@item range
  'half',  'onesided' : frequency range of the spectrum is
           zero up to but not including Fs/2.  Power from
           negative frequencies is added to the positive side of
           the spectrum, but not at zero or Nyquist (Fs/2)
           frequencies.  This keeps power equal in time and
           spectral domains.  See reference [2].

  'whole', 'twosided' : frequency range of the spectrum is
           -Fs/2 to Fs/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 data (x and y) are real, the default range is 'half',
           otherwise default range is 'whole'.

@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 detrend
   'no-strip', 'none' -- do NOT remove mean value from the data

   'short', 'mean' -- remove the mean value of each segment from
           each segment of the data.

   'linear',       -- remove linear trend from each segment of
           the data.

   'long-mean'     -- remove the mean value from the data before
           splitting it into segments.  This is the default.

  @item sloppy
    'sloppy': FFT length is rounded up to the nearest integer
           power of 2 by zero padding.  FFT length is adjusted
           after addition of padding by explicit Nfft argument.
           The default is to use exactly the FFT and window/
           segment lengths specified in argument list.

  @item results
  specifies what results to return (in the order specified
           and as many as desired).

    'power' calculate power spectral density of "x"

    'cross' calculate cross spectral density of "x" and "y"

    'trans' calculate transfer function of a system with
           input "x" and output "y"

    'coher' calculate coherence function of "x" and "y"

    'ypower' calculate power spectral density of "y"

    The default is 'power', with argument "y" omitted.
@end table

 RETURNED VALUES:

   If return values are not required by the caller, the results are
     plotted and nothing is returned.

@table @asis
   @item spectra
     [real-or-complex matrix] columns of the matrix contain results
           in the same order as specified by "results" arguments.
           Each column contains one of the result vectors.

   @item Pxx_ci
     [real matrix] estimate of confidence interval for power
           spectral density of x.  First column is the lower
           bound.  Second column is the upper bound.

   @item freq
     [real column vector] frequency values
@end table

 HINTS
@enumerate
@item EMPTY ARGS:
    if you don't want to use an optional argument you can leave it empty
    by writing its value as [].

@item FOR BEGINNERS:
    The profusion of arguments may make pwelch difficult to use, and an
    unskilled user can easily produce a meaningless result or can easily
    mis-interpret the result.  With real data "x" and sampling frequency
    "Fs", the easiest and best way for a beginner to use pwelch is
    probably "pwelch(x,[],[],[],Fs)".  Use the "window" argument to
    control the length of the spectrum vector.  For real data and integer
    scalar M, "pwelch(x,2*M,[],[],Fs)" gives an M+1 point spectrum.
    Run "demo pwelch" (octave only).

@item WINDOWING FUNCTIONS:
    Without a window function, sharp spectral peaks can have strong
    sidelobes because the FFT of a data in a segment is in effect convolved
    with a rectangular window.  A window function which tapers off
    (gradually) at the ends produces much weaker sidelobes in the FFT.
    Hann (hanning), hamming, bartlett, blackman, flattopwin etc are
    available as separate Matlab/sigproc or Octave functions.  The sidelobes
    of the Hann window have a roll-off rate of 60dB/decade of frequency.
    The first sidelobe of the Hamming window is suppressed and is about 12dB
    lower than the first Hann sidelobe, but the roll-off rate is only
    20dB/decade.  You can inspect the FFT of a Hann window by plotting
    "abs(fft(postpad(hanning(256),4096,0)))".
    The default window is Hamming.

@item ZERO PADDING:
    Zero-padding reduces the frequency step in the
    spectrum, and produces an artificially smoothed spectrum.  For example,
    "Nfft=2*length(window)" gives twice as many frequency values, but
    adjacent PSD (power spectral density) values are not independent;
    adjacent PSD values are independent if "Nfft=length(window)", which is
    the default value of Nfft.

@item REMOVING MEAN FROM SIGNAL:
    If the mean is not removed from the signal there is a large spectral
    peak at zero frequency and the sidelobes of this peak are likely to
    swamp the rest of the spectrum.  For this reason, the default behavior
    is to remove the mean.  However, the matlab pwelch does not do this.

@item WARNING ON CONFIDENCE INTERVALS
    Confidence intervals are obtained by measuring the sample variance of
    the periodograms and assuming that the periodograms have a Gaussian
    probability distribution.  This assumption is not accurate.  If, for
    example, the data (x) is Gaussian, the periodogram has a Rayleigh
    distribution.  However, the confidence intervals may still be  useful.

@item COMPATIBILITY WITH Matlab R11, R12, etc
    When used without the second data (y) argument, arguments are compatible
    with the pwelch of Matlab R12, R13, R14, 2006a and 2006b except that

     1) overlap is expressed as a multiple of window length ---
        effect of overlap scales with window length

     2) default values of length(window), Nfft and Fs are more sensible, and

     3) Goertzel algorithm is not available so Nfft cannot be an array of
        frequencies as in Matlab 2006b.

    Pwelch has four persistent Matlab-compatibility levels.  Calling pwelch
    with an empty first argument sets the order of arguments and defaults
    specified above in the USAGE and ARGUMENTS section of this documentation.
    @example
          prev_compat=pwelch([]);
          [Pxx,f]=pwelch(x,window,overlap,Nfft,Fs,conf,...);
    @end example
    Calling pwelch with a single string argument (as described below) gives
    compatibility with Matlab R11 or R12, or the R14 spectrum.welch
    defaults.  The returned value is the PREVIOUS compatibility string.

    Matlab R11:  For compatibility with the Matlab R11 pwelch:
    @example
          prev_compat=pwelch('R11-');
          [Pxx,f]=pwelch(x,Nfft,Fs,window,overlap,conf,range,units);
          %% units of overlap are "number of samples"
          %% defaults: Nfft=min(length(x),256), Fs=2*pi, length(window)=Nfft,
          %%           window=Hanning, do not detrend,
          %% N.B.  "Sloppy" is not available.
    @end example

    Matlab R12:  For compatibility with Matlab R12 to 2006a pwelch:
    @example
          prev_compat=pwelch('R12+');
          [Pxx,f]=pwelch(x,window,overlap,nfft,Fs,...);
          %% units of overlap are "number of samples"
          %% defaults: length(window)==length(x)/8, window=Hamming,
          %%           Nfft=max(256,NextPow2), Fs=2*pi, do not detrend
          %% NextPow2 is the next power of 2 greater than or equal to the
          %% window length. "Sloppy", "conf" are not available.  Default
          %% window length gives very poor amplitude resolution.
    @end example

    To adopt defaults of the Matlab R14 "spectrum.welch" spectrum object
    associated "psd" method.
    @example
          prev_compat=pwelch('psd');
          [Pxx,f] = pwelch(x,window,overlap,Nfft,Fs,conf,...);
          %% overlap is expressed as a percentage of window length,
          %% defaults: length(window)==64, Nfft=max(256,NextPow2), Fs=2*pi
          %%           do not detrend
          %% NextPow2 is the next power of 2 greater than or equal to the
          %% window length. "Sloppy" is not available.
          %% Default window length gives coarse frequency resolution.
    @end example
@end enumerate

 REFERENCES

  [1] Peter D. Welch (June 1967):
   "The use of fast Fourier transform for the estimation of power spectra:
   a method based on time averaging over short, modified periodograms."
   IEEE Transactions on Audio Electroacoustics, Vol AU-15(6), pp 70-73

  [2] William H. Press and Saul A. Teukolsky and William T. Vetterling and
               Brian P. Flannery",
   "Numerical recipes in C, The art of scientific computing", 2nd edition,
      Cambridge University Press, 2002 --- Section 13.7.
@end deftypefn
@c Power Spectrum Analysis pyulear
@c -----------------------------------------
@subsection pyulear
@cindex pyulear
@deftypefn {Function File} {[psd,f_out] =} pyulear(x,poles,freq,Fs,range,method,plot_type)
 Calculates a Yule-Walker autoregressive (all-pole) model of the data "x"
 and computes the power spectrum of the model.

 This is a wrapper for functions "aryule" and "ar_psd" which perform the
 argument checking.

 See "help aryule" 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 spectrum.

      'poly': calculate power spectrum 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.
@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-spectrum estimate
   @item f_out
   [real vector] frequency values
@end table

 HINTS

   This function is a wrapper for aryule and ar_psd.

   See "help aryule", "help ar_psd".
@end deftypefn
@c Power Spectrum Analysis tfe
@c -----------------------------------------
@subsection tfe
@cindex tfe
@deftypefn {Function File} {[Pxx,freq] =} tfe(x,y,Nfft,Fs,window,overlap,range,plot_type,detrend)
 Estimate transfer function of system with input "x" and output "y".

 Use the Welch (1967) periodogram/FFT method.

 Compatible with Matlab R11 tfe and earlier.

 See "help pwelch" for description of arguments, hints and references
 --- especially hint (7) for Matlab R11 defaults.
@end deftypefn
@c Power Spectrum Analysis tfestimate
@c -----------------------------------------
@subsection tfestimate
@cindex tfestimate
@deftypefn  {Function File} {} tfestimate (@var{x}, @var{y})
@deftypefnx {Function File} {} tfestimate (@var{x}, @var{y}, @var{window})
@deftypefnx {Function File} {} tfestimate (@var{x}, @var{y}, @var{window}, @var{overlap})
@deftypefnx {Function File} {} tfestimate (@var{x}, @var{y}, @var{window}, @var{overlap}, @var{Nfft})
@deftypefnx {Function File} {} tfestimate (@var{x}, @var{y}, @var{window}, @var{overlap}, @var{Nfft}, @var{Fs})
@deftypefnx {Function File} {} tfestimate (@var{x}, @var{y}, @var{window}, @var{overlap}, @var{Nfft}, @var{Fs}, @var{range})
@deftypefnx {Function File} {[@var{Pxx}, @var{freq}] =} tfestimate (@dots{})

 Estimate transfer function of system with input @var{x} and output @var{y}.
 Use the Welch (1967) periodogram/FFT method.
@xseealso{pwelch}
@end deftypefn
@c ---------------------------------------------------
@node Window Functions
@section Window Functions
@cindex Window Functions
@c Window Functions barthannwin
@c -----------------------------------------
@subsection barthannwin
@cindex barthannwin
@deftypefn {Function File} {} barthannwin (@var{m})
 Return the filter coefficients of a modified Bartlett-Hann window of length
@var{m}.
@xseealso{rectwin, bartlett}
@end deftypefn
@c Window Functions blackmanharris
@c -----------------------------------------
@subsection blackmanharris
@cindex blackmanharris
@deftypefn  {Function File} {} blackmanharris (@var{m})
@deftypefnx {Function File} {} blackmanharris (@var{m}, "periodic")
@deftypefnx {Function File} {} blackmanharris (@var{m}, "symmetric")
 Return the filter coefficients of a Blackman-Harris window of length @var{m}.

 If the optional argument @code{"periodic"} is given, the periodic form
 of the window is returned.  This is equivalent to the window of length
@var{m}+1 with the last coefficient removed.  The optional argument
@code{"symmetric"} is equivalent to not specifying a second argument.

@xseealso{rectwin, bartlett}
@end deftypefn
@c Window Functions blackmannuttall
@c -----------------------------------------
@subsection blackmannuttall
@cindex blackmannuttall
@deftypefn  {Function File} {} blackmannuttall (@var{m})
@deftypefnx {Function File} {} blackmannuttall (@var{m}, "periodic")
@deftypefnx {Function File} {} blackmannuttall (@var{m}, "symmetric")
 Return the filter coefficients of a Blackman-Nuttall window of length
@var{m}.

 If the optional argument @code{"periodic"} is given, the periodic form
 of the window is returned.  This is equivalent to the window of length
@var{m}+1 with the last coefficient removed.  The optional argument
@code{"symmetric"} is equivalent to not specifying a second argument.

@xseealso{nuttallwin, kaiser}
@end deftypefn
@c Window Functions bohmanwin
@c -----------------------------------------
@subsection bohmanwin
@cindex bohmanwin
@deftypefn {Function File} {} bohmanwin (@var{m})
 Return the filter coefficients of a Bohman window of length @var{m}.
@xseealso{rectwin, bartlett}
@end deftypefn
@c Window Functions boxcar
@c -----------------------------------------
@subsection boxcar
@cindex boxcar
@deftypefn {Function File} {} boxcar (@var{m})
 Return the filter coefficients of a rectangular window of length @var{m}.
@end deftypefn
@c Window Functions chebwin
@c -----------------------------------------
@subsection chebwin
@cindex chebwin
@deftypefn  {Function File} {} chebwin (@var{m})
@deftypefnx {Function File} {} chebwin (@var{m}, @var{at})

 Return the filter coefficients of a Dolph-Chebyshev window of length @var{m}.
 The Fourier transform of the window has a stop-band attenuation of @var{at}
 dB.  The default attenuation value is 100 dB.

 For the definition of the Chebyshev window, see

 * Peter Lynch, "The Dolph-Chebyshev Window: A Simple Optimal Filter",
   Monthly Weather Review, Vol. 125, pp. 655-660, April 1997.
   (http://www.maths.tcd.ie/~plynch/Publications/Dolph.pdf)

 * C. Dolph, "A current distribution for broadside arrays which
   optimizes the relationship between beam width and side-lobe level",
   Proc. IEEE, 34, pp. 335-348.

 The window is described in frequency domain by the expression:

@example
@group
          Cheb(m-1, beta * cos(pi * k/m))
   W(k) = -------------------------------
                 Cheb(m-1, beta)
@end group
@end example

 with

@example
@group
   beta = cosh(1/(m-1) * acosh(10^(at/20))
@end group
@end example

 and Cheb(m,x) denoting the m-th order Chebyshev polynomial calculated
 at the point x.

 Note that the denominator in W(k) above is not computed, and after
 the inverse Fourier transform the window is scaled by making its
 maximum value unitary.

@xseealso{kaiser}
@end deftypefn
@c Window Functions flattopwin
@c -----------------------------------------
@subsection flattopwin
@cindex flattopwin
@deftypefn  {Function File} {} flattopwin (@var{m})
@deftypefnx {Function File} {} flattopwin (@var{m}, "periodic")
@deftypefnx {Function File} {} flattopwin (@var{m}, "symmetric")

 Return the filter coefficients of a Flat Top window of length @var{m}.
 The Flat Top window is defined by the function f(w):

@example
@group
   f(w) = 1 - 1.93 cos(2 pi w) + 1.29 cos(4 pi w)
            - 0.388 cos(6 pi w) + 0.0322cos(8 pi w)
@end group
@end example

 where w = i/(m-1) for i=0:m-1 for a symmetric window, or
 w = i/m for i=0:m-1 for a periodic window.  The default
 is symmetric.  The returned window is normalized to a peak
 of 1 at w = 0.5.

 This window has low pass-band ripple, but high bandwidth.

 According to [1]:

    The main use for the Flat Top window is for calibration, due
    to its negligible amplitude errors.

 [1] Gade, S; Herlufsen, H; (1987) "Use of weighting functions in DFT/FFT
 analysis (Part I)", Bruel & Kjaer Technical Review No.3.
@end deftypefn
@c Window Functions gaussian
@c -----------------------------------------
@subsection gaussian
@cindex gaussian
@deftypefn  {Function File} {} gaussian (@var{m})
@deftypefnx {Function File} {} gaussian (@var{m}, @var{a})

 Return a Gaussian convolution window of length @var{m}.  The width of the
 window is inversely proportional to the parameter @var{a}.  Use larger
@var{a} for a narrower window.  Use larger @var{m} for longer tails.

     w = exp ( -(a*x)^2/2 )

 for x = linspace ( -(m-1)/2, (m-1)/2, m ).

 Width a is measured in frequency units (sample rate/num samples).
 It should be f when multiplying in the time domain, but 1/f when
 multiplying in the frequency domain (for use in convolutions).
@end deftypefn
@c Window Functions gausswin
@c -----------------------------------------
@subsection gausswin
@cindex gausswin
@deftypefn  {Function File} {} gausswin (@var{m})
@deftypefnx {Function File} {} gausswin (@var{m}, @var{a})

 Return the filter coefficients of a Gaussian window of length @var{m}.
 The width of the window is inversely proportional to the parameter @var{a}.
 Use larger @var{a} for a narrow window.  Use larger @var{m} for a smoother
 curve.

     w = exp ( -(a*x)^2/2 )

 for x = linspace(-(m-1)/m, (m-1)/m, m)
@end deftypefn
@c Window Functions hann
@c -----------------------------------------
@subsection hann
@cindex hann
@deftypefn  {Function File} {} hann (@var{m})
@deftypefnx {Function File} {} hann (@var{m}, "periodic")
@deftypefnx {Function File} {} hann (@var{m}, "symmetric")
 Return the filter coefficients of a Hanning window of length @var{m}.

 If the optional argument @code{"periodic"} is given, the periodic form
 of the window is returned.  This is equivalent to the window of length
@var{m}+1 with the last coefficient removed.  The optional argument
@code{"symmetric"} is equivalent to not specifying a second argument.

 This function exists for @sc{matlab} compatibility only, and is equivalent
 to @code{hanning (@var{m})}.

@xseealso{hanning}
@end deftypefn
@c Window Functions kaiser
@c -----------------------------------------
@subsection kaiser
@cindex kaiser
@deftypefn  {Function File} {} kaiser (@var{m})
@deftypefnx {Function File} {} kaiser (@var{m}, @var{beta})

 Return the filter coefficients of a Kaiser window of length @var{m}.  The
 Fourier transform of the window has a stop-band attenuation that is derived
 from the parameter @var{beta}.

 For the definition of the Kaiser window, see A. V. Oppenheim &
 R. W. Schafer, "Discrete-Time Signal Processing".

 The continuous version of width m centered about x=0 is:

@example
@group
         besseli(0, beta * sqrt(1-(2*x/m).^2))
 k(x) =  -------------------------------------,  m/2 <= x <= m/2
                besseli(0, beta)
@end group
@end example

@xseealso{kaiserord}
@end deftypefn
@c Window Functions nuttallwin
@c -----------------------------------------
@subsection nuttallwin
@cindex nuttallwin
@deftypefn  {Function File} {} nuttallwin (@var{m})
@deftypefnx {Function File} {} nuttallwin (@var{m}, "periodic")
@deftypefnx {Function File} {} nuttallwin (@var{m}, "symmetric")
 Return the filter coefficients of a Blackman-Harris window defined by
 Nuttall of length @var{m}.

 If the optional argument @code{"periodic"} is given, the periodic form
 of the window is returned.  This is equivalent to the window of length
@var{m}+1 with the last coefficient removed.  The optional argument
@code{"symmetric"} is equivalent to not specifying a second argument.

@xseealso{blackman, blackmanharris}
@end deftypefn
@c Window Functions parzenwin
@c -----------------------------------------
@subsection parzenwin
@cindex parzenwin
@deftypefn {Function File} {} parzenwin (@var{m})
 Return the filter coefficients of a Parzen window of length @var{m}.
@xseealso{rectwin, bartlett}
@end deftypefn
@c Window Functions rectwin
@c -----------------------------------------
@subsection rectwin
@cindex rectwin
@deftypefn {Function File} {} rectwin (@var{m})
 Return the filter coefficients of a rectangular window of length @var{m}.
@xseealso{boxcar, hamming, hanning}
@end deftypefn
@c Window Functions triang
@c -----------------------------------------
@subsection triang
@cindex triang
@deftypefn {Function File} {} triang (@var{m})

 Return the filter coefficients of a triangular window of length @var{m}.
 Unlike the Bartlett window, @code{triang} does not go to zero at the edges
 of the window.  For odd @var{m}, @code{triang (@var{m})} is equal to
@code{bartlett (@var{m} + 2)} except for the zeros at the edges of the
 window.
@xseealso{bartlett}
@end deftypefn
@c Window Functions tukeywin
@c -----------------------------------------
@subsection tukeywin
@cindex tukeywin
@deftypefn  {Function File} {} tukeywin (@var{m})
@deftypefnx {Function File} {} tukeywin (@var{m}, @var{r})
 Return the filter coefficients of a Tukey window (also known as the
 cosine-tapered window) of length @var{m}.  @var{r} defines the ratio
 between the constant section and and the cosine section.  It has to be
 between 0 and 1.  The function returns a Hanning window for @var{r}
 equal to 1 and a rectangular window for @var{r} equal to 0.
 The default value of @var{r} is 1/2.

 For a definition of the Tukey window, see e.g. Fredric J. Harris,
 "On the Use of Windows for Harmonic Analysis with the Discrete Fourier
 Transform, Proceedings of the IEEE", Vol. 66, No. 1, January 1978,
 Page 67, Equation 38.
@xseealso{hanning}
@end deftypefn
@c Window Functions ultrwin
@c -----------------------------------------
@subsection ultrwin
@cindex ultrwin
@deftypefn  {Function File} {[@var{w}, @var{xmu}] =} ultrwin (@var{m}, @var{mu}, @var{beta})
@deftypefnx {Function File} {[@var{w}, @var{xmu}] =} ultrwin (@var{m}, @var{mu}, @var{att}, "att")
@deftypefnx {Function File} {[@var{w}, @var{xmu}] =} ultrwin (@var{m}, @var{mu}, @var{latt}, "latt")
@deftypefnx {Function File} {@var{w} =} ultrwin (@var{m}, @var{mu}, @var{xmu}, "xmu")
 Return the coefficients of an Ultraspherical window of length @var{m}.
 The parameter @var{mu} controls the window's Fourier transform's side-lobe
 to side-lobe ratio, and the third given parameter controls the transform's
 main-lobe width/side-lobe-ratio; normalize @var{w} such that the central
 coefficient(s) value is unitary.

 By default, the third parameter is @var{beta}, which sets the main lobe width
 to @var{beta} times that of a rectangular window.  Alternatively, giving
@var{att} or @var{latt} sets the ripple ratio at the first or last side-lobe
 respectively, or giving @var{xmu} sets the (un-normalized) window's Fourier
 transform according to its canonical definition:

@verbatim
              (MU)
      W(k) = C   [ XMU cos(pi k/M) ],  k = 0, 1, ..., M-1,
              M-1
@end verbatim

 where C is the Ultraspherical (a.k.a. Gegenbauer) polynomial, which can be
 defined using the recurrence relationship:

@verbatim
       (l)    1                  (l)                    (l)
      C (x) = - [ 2x(m + l - 1) C   (x) - (m + 2l - 2) C   (x) ]
       m      m                  m-1                    m-2

                                 (l)        (l)
      for m an integer > 1, and C (x) = 1, C (x) = 2lx.
                                 0          1
@end verbatim

 For given @var{beta}, @var{att}, or @var{latt}, the corresponding
 (determined) value of @var{xmu} is also returned.

 The Dolph-Chebyshev and Saramaki windows are special cases of the
 Ultraspherical window, with @var{mu} set to 0 and 1 respectively.  Note that
 when not giving @var{xmu}, stability issues may occur with @var{mu} <= -1.5.
 For further information about the window, see

@itemize @bullet
@item
 Kabal, P., 2009: Time Windows for Linear Prediction of Speech.
 Technical Report, Dept. Elec. & Comp. Eng., McGill University.
@item
 Bergen, S., Antoniou, A., 2004: Design of Ultraspherical Window
 Functions with Prescribed Spectral Characteristics. Proc. JASP, 13/13,
 pp. 2053-2065.
@item
 Streit, R., 1984: A two-parameter family of weights for nonrecursive
 digital filters and antennas. Trans. ASSP, 32, pp. 108-118.
@end itemize
@xseealso{chebwin, kaiser}
@end deftypefn
@c Window Functions welchwin
@c -----------------------------------------
@subsection welchwin
@cindex welchwin
@deftypefn  {Function File} {} welchwin (@var{m})
@deftypefnx {Function File} {} welchwin (@var{m}, "periodic")
@deftypefnx {Function File} {} welchwin (@var{m}, "symmetric")
 Return the filter coefficients of a Welch window of length @var{m}.  The
 Welch window is given by
@var{w}(n)=1-(n/N-1)^2,   n=[0,1, ... @var{m}-1].
 The optional argument specifies a "symmetric" window (the default) or a
 "periodic" window.

 A symmetric window has zero at each end and maximum in the middle, and the
 length must be an integer greater than 2.  The variable @var{N} in the
 formula above is @code{(@var{m}-1)/2}.

 A periodic window wraps around the cyclic interval [0,1, ... @var{m}-1],
 and is intended for use with the DFT.  The length must be an integer
 greater than 1.  The variable @var{N} in the formula above is
@code{@var{m}/2}.

@xseealso{blackman, kaiser}
@end deftypefn
@c Window Functions window
@c -----------------------------------------
@subsection window
@cindex window
@deftypefn  {Function File} {@var{w} =} window (@var{f}, @var{m})
@deftypefnx {Function File} {@var{w} =} window (@var{f}, @var{m}, @var{opts})
 Create an @var{m}-point window from the function @var{f}.  The function
@var{f} can be for example @code{@@blackman}.  Any additional
 arguments @var{opt} are passed to the windowing function.
@end deftypefn
@c ---------------------------------------------------
@node System Identification
@section System Identification
@cindex System Identification
@c System Identification arburg
@c -----------------------------------------
@subsection arburg
@cindex arburg
@deftypefn  {Function File} {[@var{a}, @var{v}, @var{k}] =} arburg (@var{x}, @var{poles})
@deftypefnx {Function File} {[@var{a}, @var{v}, @var{k}] =} arburg (@var{x}, @var{poles}, @var{criterion})

 Calculate coefficients of an autoregressive (AR) model of complex data
@var{x} using the whitening lattice-filter method of Burg (1968).  The
 inverse of the model is a moving-average filter which reduces @var{x} to
 white noise.  The power spectrum of the AR model is an estimate of the
 maximum entropy power spectrum of the data.  The function @code{ar_psd}
 calculates the power spectrum of the AR model.

 ARGUMENTS:
@itemize
@item
@var{x}
 sampled data
@item
@var{poles}
 number of poles in the AR model or limit to the number of poles if a
 valid @var{criterion} is provided.
@item
@var{criterion}
 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 itemize

 RETURNED VALUES:
@itemize
@item
@var{a}
 list of (P+1) autoregression coefficients; for data input @math{x(n)} and
 white noise @math{e(n)}, the model is

@example
@group
                       P+1
 x(n) = sqrt(v).e(n) + SUM a(k).x(n-k)
                       k=1
@end group
@end example

@var{v}
 mean square of residual noise from the whitening operation of the Burg
 lattice filter.
@item
@var{k}
 reflection coefficients defining the lattice-filter embodiment of the model
@end itemize

 HINTS:

  (1) arburg does not remove the mean from the data.  You should remove
      the mean from the data if you want a power spectrum.  A non-zero mean
      can produce large errors in a power-spectrum estimate.  See
      "help detrend".
  (2) If you don't know what the value of "poles" should be, choose the
      largest (reasonable) value you could want and use the recommended
      value, criterion='AKICc', so that arburg can find it.
      E.g. arburg(x,64,'AKICc')
      The AKICc has the least bias and best resolution of the available
      model-selection criteria.
  (3) Autoregressive and moving-average filters are stored as polynomials
      which, in matlab, are row vectors.

 NOTE ON SELECTION CRITERION:

   AIC, AICc, KIC and AKICc are based on information theory.  They  attempt
   to balance the complexity (or length) of the model against how well the
   model fits the data.  AIC and KIC are biased estimates of the asymmetric
   and the symmetric Kullback-Leibler divergence respectively.  AICc and
   AKICc attempt to correct the bias. See reference [4].


 REFERENCES:

 [1] John Parker Burg (1968)
   "A new analysis technique for time series data",
   NATO advanced study Institute on Signal Processing with Emphasis on
   Underwater Acoustics, Enschede, Netherlands, Aug. 12-23, 1968.

 [2] Steven M. Kay and Stanley Lawrence Marple Jr.:
   "Spectrum analysis -- a modern perspective",
   Proceedings of the IEEE, Vol 69, pp 1380-1419, Nov., 1981

 [3] William H. Press and Saul A. Teukolsky and William T. Vetterling and
               Brian P. Flannery
   "Numerical recipes in C, The art of scientific computing", 2nd edition,
   Cambridge University Press, 2002 --- Section 13.7.

 [4] Abd-Krim Seghouane and Maiza Bekara
   "A small sample model selection criterion based on Kullback's symmetric
   divergence", IEEE Transactions on Signal Processing,
   Vol. 52(12), pp 3314-3323, Dec. 2004

@xseealso{ar_psd}
@end deftypefn
@c System Identification aryule
@c -----------------------------------------
@subsection aryule
@cindex aryule
@deftypefn  {Function File} {@var{a} =} aryule (@var{x}, @var{p})
@deftypefnx {Function File} {[@var{a}, @var{v}, @var{k}] =} aryule (@var{x}, @var{p})
 Fit an AR (@var{p})-model with Yule-Walker estimates.
@table @var
@item x
 data vector to estimate
@item a
 AR coefficients
@item v
 variance of white noise
@item k
 reflection coefficients for use in lattice filter
@end table

 The power spectrum of the resulting filter can be plotted with
 pyulear(x, p), or you can plot it directly with ar_psd(a,v,...).

 See also:
 pyulear, power, freqz, impz -- for observing characteristics of the model
 arburg -- for alternative spectral estimators

 Example: Use example from arburg, but substitute aryule for arburg.

 Note: Orphanidis '85 claims lattice filters are more tolerant of
 truncation errors, which is why you might want to use them.  However,
 lacking a lattice filter processor, I haven't tested that the lattice
 filter coefficients are reasonable.
@end deftypefn
@c System Identification invfreq
@c -----------------------------------------
@subsection invfreq
@cindex invfreq
@deftypefn {Function File} {[B,A] =} invfreq(H,F,nB,nA)
@deftypefnx {} {[B,A] =} invfreq(H,F,nB,nA,W)
@deftypefnx {} {[B,A] =} invfreq(H,F,nB,nA,W,[],[],plane)
@deftypefnx {} {[B,A] =} invfreq(H,F,nB,nA,W,iter,tol,plane)
 Fit filter B(z)/A(z) or B(s)/A(s) to complex frequency response at
 frequency points F.

 A and B are real polynomial coefficients of order
 nA and nB respectively.  Optionally, the fit-errors can be weighted vs
 frequency according to the weights W. Also, the transform plane can be
 specified as either 's' for continuous time or 'z' for discrete time. 'z'
 is chosen by default.  Eventually, Steiglitz-McBride iterations will be
 specified by iter and tol.

 H: desired complex frequency response
     It is assumed that A and B are real polynomials, hence H is one-sided.

 F: vector of frequency samples in radians

 nA: order of denominator polynomial A

 nB: order of numerator polynomial B

 plane='z': F on unit circle (discrete-time spectra, z-plane design)

 plane='s': F on jw axis     (continuous-time spectra, s-plane design)

 H(k) = spectral samples of filter frequency response at points zk,
  where zk=exp(sqrt(-1)*F(k)) when plane='z' (F(k) in [0,.5])
     and zk=(sqrt(-1)*F(k)) when plane='s' (F(k) nonnegative)

 Example:
@example
     [B,A] = butter(12,1/4);
     [H,w] = freqz(B,A,128);
     [Bh,Ah] = invfreq(H,F,4,4);
     Hh = freqz(Bh,Ah);
     disp(sprintf('||frequency response error|| = %f',norm(H-Hh)));
@end example

 References:

 J. O. Smith, "Techniques for Digital Filter Design and System
      Identification with Application to the Violin, Ph.D. Dissertation,
      Elec. Eng. Dept., Stanford University, June 1983, page 50; or,

 http://ccrma.stanford.edu/~jos/filters/FFT_Based_Equation_Error_Method.html
@end deftypefn
@c System Identification invfreqs
@c -----------------------------------------
@subsection invfreqs
@cindex invfreqs
@deftypefn {Function File} {[B,A] =} invfreqs(H,F,nB,nA)
@deftypefnx {} {[B,A] =} invfreqs(H,F,nB,nA,W)
@deftypefnx {} {[B,A] =} invfreqs(H,F,nB,nA,W,iter,tol,'trace')
 Fit filter B(s)/A(s)to the complex frequency response H at frequency
 points F.

 A and B are real polynomial coefficients of order nA and nB.

 Optionally, the fit-errors can be weighted vs frequency according to
 the weights W.

 Note: all the guts are in invfreq.m

 H: desired complex frequency response

 F: frequency (must be same length as H)

 nA: order of the denominator polynomial A

 nB: order of the numerator polynomial B

 W: vector of weights (must be same length as F)

 Example:
@example
       B = [1/2 1];
       A = [1 1];
       w = linspace(0,4,128);
       H = freqs(B,A,w);
       [Bh,Ah] = invfreqs(H,w,1,1);
       Hh = freqs(Bh,Ah,w);
       plot(w,[abs(H);abs(Hh)])
       legend('Original','Measured');
       err = norm(H-Hh);
       disp(sprintf('L2 norm of frequency response error = %f',err));
@end example
@end deftypefn
@c System Identification invfreqz
@c -----------------------------------------
@subsection invfreqz
@cindex invfreqz
@deftypefn {Function File} {[B,A] =} invfreqz(H,F,nB,nA)
@deftypefnx {} {[B,A] =} invfreqz(H,F,nB,nA,W)
@deftypefnx {} {[B,A] =} invfreqz(H,F,nB,nA,W,iter,tol,'trace')
 Fit filter B(z)/A(z)to the complex frequency response H at frequency
 points F.

 A and B are real polynomial coefficients of order nA and nB.
 Optionally, the fit-errors can be weighted vs frequency according to
 the weights W.

 Note: all the guts are in invfreq.m

 H: desired complex frequency response

 F: normalized frequency (0 to pi) (must be same length as H)

 nA: order of the denominator polynomial A

 nB: order of the numerator polynomial B

 W: vector of weights (must be same length as F)

 Example:
@example
     [B,A] = butter(4,1/4);
     [H,F] = freqz(B,A);
     [Bh,Ah] = invfreq(H,F,4,4);
     Hh = freqz(Bh,Ah);
     disp(sprintf('||frequency response error|| = %f',norm(H-Hh)));
@end example
@end deftypefn
@c System Identification levinson
@c -----------------------------------------
@subsection levinson
@cindex levinson
@deftypefn  {Function File} {[@var{a}, @var{v}, @var{ref}] =} levinson (@var{acf})
@deftypefnx {Function File} {[@dots{}] =} levinson (@var{acf}, @var{p})

 Use the Durbin-Levinson algorithm to solve:
    toeplitz(acf(1:p)) * x = -acf(2:p+1).
 The solution [1, x'] is the denominator of an all pole filter
 approximation to the signal x which generated the autocorrelation
 function acf.

 acf is the autocorrelation function for lags 0 to p.
 p defaults to length(acf)-1.
 Returns
   a=[1, x'] the denominator filter coefficients.
   v= variance of the white noise = square of the numerator constant
   ref = reflection coefficients = coefficients of the lattice
         implementation of the filter
 Use freqz(sqrt(v),a) to plot the power spectrum.

 REFERENCE
 [1] Steven M. Kay and Stanley Lawrence Marple Jr.:
   "Spectrum analysis -- a modern perspective",
   Proceedings of the IEEE, Vol 69, pp 1380-1419, Nov., 1981
@end deftypefn
@c System Identification lpc
@c -----------------------------------------
@subsection lpc
@cindex lpc
@deftypefn  {Function File} {@var{a} = } lpc (@var{x})
@deftypefnx {Function File} {@var{a} = } lpc (@var{x}, @var{p})
@deftypefnx {Function File} {[@var{a}, @var{g}] = } lpc (@dots{})
@deftypefnx {Function File} {[@var{a}, @var{g}] = } lpc (@var{x}, @var{p})

 Determines the forward linear predictor by minimizing the prediction error
 in the least squares sense. Use the Durbin-Levinson algorithm to solve
 the Yule-Walker equations obtained by the autocorrelation of the input
 signal.

@var{x} is a data vector used to estimate the lpc model of @var{p}-th order,
 given by the prediction polynomial @code{@var{a} = [1 @var{a}(2) @dots{}
@var{a}(@var{p}+1)]}. If @var{p} is not provided, @code{length(@var{p}) - 1}
 is used as default.

@var{x} might also be a matrix, in which case each column is regarded as a
 separate signal. @code{lpc} will return a model estimate for each column of
@var{x}.

@var{g} is the variance (power) of the prediction error for each signal in
@var{x}.

@xseealso{aryule,levinson}
@end deftypefn
@c ---------------------------------------------------
@node Sample Rate Change
@section Sample Rate Change
@cindex Sample Rate Change
@c Sample Rate Change data2fun
@c -----------------------------------------
@subsection data2fun
@cindex data2fun
@deftypefn  {Function File} {[@var{fhandle}, @var{fullname}] =} data2fun (@var{ti}, @var{yi})
@deftypefnx {Function File} {[@dots{}] =} data2fun (@dots{}, @var{property}, @var{value})
 Create a vectorized function based on data samples using interpolation.

 The values given in @var{yi} (N-by-k matrix) correspond to evaluations of the
 function y(t) at the points @var{ti} (N-by-1 matrix).
 The data is interpolated and the function handle to the generated interpolant
 is returned.

 The function accepts @var{property}-@var{value} pairs described below.

@table @samp
@item file
 Code is generated and .m file is created. The @var{value} contains the name
 of the function. The returned function handle is a handle to that file. If
@var{value} is empty, then a name is automatically generated using
@code{tempname} and the file is created in the current directory. @var{value}
 must not have an extension, since .m will be appended.
 Numerical values used in the function are stored in a .mat file with the same
 name as the function.

@item interp
 Type of interpolation. See @code{interp1}.
@end table

@xseealso{interp1}
@end deftypefn
@c Sample Rate Change decimate
@c -----------------------------------------
@subsection decimate
@cindex decimate
@deftypefn  {Function File} {@var{y} =} decimate (@var{x}, @var{q})
@deftypefnx {Function File} {@var{y} =} decimate (@var{x}, @var{q}, @var{n})
@deftypefnx {Function File} {@var{y} =} decimate (@dots{}, "fir")

 Downsample the signal @var{x} by a reduction factor of @var{q}. A lowpass
 antialiasing filter is applied to the signal prior to reducing the input
 sequence. By default, an order @var{n} Chebyshev type I filter is used.
 If @var{n} is not specified, the default is 8.

 If the optional argument @code{"fir"} is given, an order @var{n} FIR filter
 is used, with a default order of 30 if @var{n} is not given.

 Note that @var{q} must be an integer for this rate change method.

 Example:
@example
 ## Generate a signal that starts away from zero, is slowly varying
 ## at the start and quickly varying at the end, decimate and plot.
 ## Since it starts away from zero, you will see the boundary
 ## effects of the antialiasing filter clearly.  Next you will see
 ## how it follows the curve nicely in the slowly varying early
 ## part of the signal, but averages the curve in the quickly
 ## varying late part of the signal.
 t = 0:0.01:2;
 x = chirp (t, 2, .5, 10, "quadratic") + sin (2*pi*t*0.4);
 y = decimate (x, 4);
 stem (t(1:121) * 1000, x(1:121), "-g;Original;"); hold on; # original
 stem (t(1:4:121) * 1000, y(1:31), "-r;Decimated;"); hold off; # decimated
@end example
@end deftypefn
@c Sample Rate Change downsample
@c -----------------------------------------
@subsection downsample
@cindex downsample
@deftypefn  {Function File} {@var{y} =} downsample (@var{x}, @var{n})
@deftypefnx {Function File} {@var{y} =} downsample (@var{x}, @var{n}, @var{offset})
 Downsample the signal, selecting every @var{n}th element.  If @var{x}
 is a matrix, downsample every column.

 For most signals you will want to use @code{decimate} instead since
 it prefilters the high frequency components of the signal and
 avoids aliasing effects.

 If @var{offset} is defined, select every @var{n}th element starting at
 sample @var{offset}.
@xseealso{decimate, interp, resample, upfirdn, upsample}
@end deftypefn
@c Sample Rate Change interp
@c -----------------------------------------
@subsection interp
@cindex interp
@deftypefn  {Function File} {@var{y} =} interp (@var{x}, @var{q})
@deftypefnx {Function File} {@var{y} =} interp (@var{x}, @var{q}, @var{n})
@deftypefnx {Function File} {@var{y} =} interp (@var{x}, @var{q}, @var{n}, @var{Wc})

 Upsample the signal x by a factor of q, using an order 2*q*n+1 FIR
 filter. Note that q must be an integer for this rate change method.
 n defaults to 4 and Wc defaults to 0.5.

 Example
@example
@group
 # Generate a signal.
 t=0:0.01:2; x=chirp(t,2,.5,10,'quadratic')+sin(2*pi*t*0.4);
 y = interp(x(1:4:length(x)),4,4,1);   # interpolate a sub-sample
 stem(t(1:121)*1000,x(1:121),"-g;Original;"); hold on;
 stem(t(1:121)*1000,y(1:121),"-r;Interpolated;");
 stem(t(1:4:121)*1000,x(1:4:121),"-b;Subsampled;"); hold off;
@end group
@end example

@xseealso{decimate, resample}
@end deftypefn
@c Sample Rate Change resample
@c -----------------------------------------
@subsection resample
@cindex resample
@deftypefn  {Function File} {[@var{y}, @var{h}] =} resample (@var{x}, @var{p}, @var{q})
@deftypefnx {Function File} {@var{y} =} resample (@var{x}, @var{p}, @var{q}, @var{h})
 Change the sample rate of @var{x} by a factor of @var{p}/@var{q}.  This is
 performed using a polyphase algorithm.  The impulse response @var{h} of
 the antialiasing filter is either specified or either designed with a
 Kaiser-windowed sinecard.

 Ref [1] J. G. Proakis and D. G. Manolakis,
 Digital Signal Processing: Principles, Algorithms, and Applications,
 4th ed., Prentice Hall, 2007. Chap. 6

 Ref [2] A. V. Oppenheim, R. W. Schafer and J. R. Buck,
 Discrete-time signal processing, Signal processing series,
 Prentice-Hall, 1999
@end deftypefn
@c Sample Rate Change upfirdn
@c -----------------------------------------
@subsection upfirdn
@cindex upfirdn
@deftypefn {Loadable Function} {@var{y} =} upfirdn (@var{x}, @var{h}, @var{p}, @var{q})
Upsample, FIR filtering, and downsample.
@end deftypefn

@c Sample Rate Change upsample
@c -----------------------------------------
@subsection upsample
@cindex upsample
@deftypefn  {Function File} {@var{y} =} upsample (@var{x}, @var{n})
@deftypefnx {Function File} {@var{y} =} upsample (@var{x}, @var{n}, @var{offset})
 Upsample the signal, inserting @var{n}-1 zeros between every element.

 If @var{x} is a matrix, upsample every column.

 If @var{offset} is specified, control the position of the inserted sample in
 the block of @var{n} zeros.
@xseealso{decimate, downsample, interp, resample, upfirdn}
@end deftypefn
@c ---------------------------------------------------
@node Pulse Metrics
@section Pulse Metrics
@cindex Pulse Metrics
@c Pulse Metrics statelevels
@c -----------------------------------------
@subsection statelevels
@cindex statelevels
@deftypefn {Function File} {@var{levels} =} statelevels (@var{A})
@deftypefnx {Function File} {@var{levels} =} statelevels (@var{A}, @var{nbins})
@deftypefnx {Function File} {@var{levels} =} statelevels (@var{A}, @var{nbins}, @var{method})
@deftypefnx {Function File} {@var{levels} =} statelevels (@var{A}, @var{nbins}, @var{method}, @var{bounds})
@deftypefnx {Function File} {[@var{levels}, @var{histograms}] =} statelevels (@dots{})
@deftypefnx {Function File} {[@var{levels}, @var{histograms}, @var{binlevels}] =} statelevels (@dots{})
@deftypefnx {Function File} {} statelevels (@dots{})
 Estimate state-level for bilevel waveform @var{A} using histogram method

 INPUTS:

@table @var
@item A
 Bylevel waveform
@item nbins
 Number of histogram bins (100 default)
@item method
 State-level estimation method 'mode' (default) or 'mean'.
@item bounds
 2 element vector for histogram lower and upper bounds. Values outside of this will be ignored.
@end table

 OUTPUTS:

@table @var
@item levels
 Levels of high and low states
@item histograms
 Histogram counts
@item binlevels
 Histogram bincenters
@end table

 If no outputs are provided, the signal and histogram will be plotted, and display the levels.

@end deftypefn
@c ---------------------------------------------------
@node Utility
@section Utility
@cindex Utility
@c Utility buffer
@c -----------------------------------------
@subsection buffer
@cindex buffer
@deftypefn  {Function File} {@var{y} =} buffer (@var{x}, @var{n}, @var{p}, @var{opt})
@deftypefnx {Function File} {[@var{y}, @var{z}, @var{opt}] =} buffer (@dots{})
 Buffer a signal into a data frame. The arguments to @code{buffer} are

@table @asis
@item @var{x}
 The data to be buffered.

@item @var{n}
 The number of rows in the produced data buffer. This is an positive
 integer value and must be supplied.

@item @var{p}
 An integer less than @var{n} that specifies the under- or overlap
 between column in the data frame. The default value of @var{p} is 0.

@item @var{opt}
 In the case of an overlap, @var{opt} can be either a vector of length
@var{p} or the string 'nodelay'. If @var{opt} is a vector, then the
 first @var{p} entries in @var{y} will be filled with these values. If
@var{opt} is the string 'nodelay', then the first value of @var{y}
 corresponds to the first value of @var{x}.

 In the can of an underlap, @var{opt} must be an integer between 0 and
@code{-@var{p}}. The represents the initial underlap of the first
 column of @var{y}.

 The default value for @var{opt} the vector @code{zeros (1, @var{p})}
 in the case of an overlap, or 0 otherwise.
@end table

 In the case of a single output argument, @var{y} will be padded with
 zeros to fill the missing values in the data frame. With two output
 arguments @var{z} is the remaining data that has not been used in the
 current data frame.

 Likewise, the output @var{opt} is the overlap, or underlap that might
 be used for a future call to @code{code} to allow continuous buffering.
@end deftypefn
@c Utility clustersegment
@c -----------------------------------------
@subsection clustersegment
@cindex clustersegment
@deftypefn {Function File} {@var{clusteridx} =} clustersegment (@var{unos})
 Calculate boundary indexes of clusters of 1's.

 The function calculates the initial index and end index of the sequences of
 1's in the rows of @var{unos}. The clusters are sought in the rows of the
 array @var{unos}.

 The result is returned in a cell array of size 1-by-@var{Np}, where @var{Np}
 is the number of rows in @var{unos}. Each element of the cell has two rows.
 The first row is the initial index of a sequence of 1's and the second row
 is the end index of that sequence.

 If @var{Np} == 1 the output is a matrix with two rows.

 The function works by finding the indexes of jumps between consecutive
 values in the rows of @var{unos}.

@end deftypefn
@c Utility fracshift
@c -----------------------------------------
@subsection fracshift
@cindex fracshift
@deftypefn  {Function File} {[@var{y}, @var{h}] =} fracshift (@var{x}, @var{d})
@deftypefnx {Function File} {@var{y} =} fracshift (@var{x}, @var{d}, @var{h})
 Shift the series @var{x} by a (possibly fractional) number of samples @var{d}.
 The interpolator @var{h} is either specified or either designed with a
 Kaiser-windowed sinecard.
@xseealso{circshift}
@end deftypefn
@c Utility marcumq
@c -----------------------------------------
@subsection marcumq
@cindex marcumq
@deftypefn  {Function File} {@var{q} =} marcumq (@var{a}, @var{b})
@deftypefnx {Function File} {@var{q} =} marcumq (@var{a}, @var{b}, @var{m})
@deftypefnx {Function File} {@var{q} =} marcumq (@var{a}, @var{b}, @var{m}, @var{tol})

 Compute the generalized Marcum Q function of order @var{m} with
 noncentrality parameter @var{a} and argument @var{b}.  If the order
@var{m} is omitted it defaults to 1.  An optional relative tolerance
@var{tol} may be included, the default is @code{eps}.

 If the input arguments are commensurate vectors, this function
 will produce a table of values.

 This function computes Marcum's Q function using the infinite
 Bessel series, truncated when the relative error is less than
 the specified tolerance.  The accuracy is limited by that of
 the Bessel functions, so reducing the tolerance is probably
 not useful.

 Reference: Marcum, "Tables of Q Functions", Rand Corporation.

 Reference: R.T. Short, "Computation of Noncentral Chi-squared
 and Rice Random Variables", www.phaselockedsystems.com/publications

@end deftypefn
@c Utility primitive
@c -----------------------------------------
@subsection primitive
@cindex primitive
@deftypefn {Function File} {@var{F} =} primitive (@var{f}, @var{t}, @var{F0})
 Calculate the primitive of a function.

 The function approximates the primitive (indefinite integral) of the
 univariate function handle @var{f} with constant of integration @var{F0}.
 The output is the primitive evaluated at the points @var{t}.  The vector
@var{t} must be ordered and ascending.

 This function is a fancy way of calculating the cumulative sum,

@command{F = cumsum (f(t).*diff (t)([1 1:end]))}.

 Example:
@example
@group
 f = @@(t) sin (2 * pi * 3 * t);
 t = [0; sort(rand (100, 1))];
 F = primitive (f, t, 0);
 t_true = linspace (0, 1, 1e3).';
 F_true = (1 - cos (2 * pi * 3 * t_true)) / (2 * pi * 3);
 plot (t, F, 'o', t_true, F_true);
@end group
@end example

@xseealso{quadgk, cumsum}
@end deftypefn
@c Utility sampled2continuous
@c -----------------------------------------
@subsection sampled2continuous
@cindex sampled2continuous
@deftypefn {Function File} {@var{xt} =} sampled2continuous (@var{xn}, @var{T}, @var{t})

 Calculate the x(t) reconstructed
 from samples x[n] sampled at a rate 1/T samples
 per unit time.

 t is all the instants of time when you need x(t)
 from x[n]; this time is relative to x[0] and not
 an absolute time.

 This function can be used to calculate sampling rate
 effects on aliasing, actual signal reconstruction
 from discrete samples.
@end deftypefn
@c Utility schtrig
@c -----------------------------------------
@subsection schtrig
@cindex schtrig
@deftypefn {@var{v} =} schtrig (@var{x},@var{lvl},@var{rst}=1)
@deftypefnx {[@var{v},@var{rng}] =} schtrig (@dots{})
 Implements a multisignal Schmitt trigger with levels @var{lvl}.

 The triger works along the first dimension of the 2-dimensional array @var{x}.
 It compares each column in @var{x} to the levels in @var{lvl}, when the
 value is higher @code{max (@var{lvl})} the output @var{v} is high (i.e. 1); when the
 value is below @code{min (@var{lvl})} the output is low (i.e. 0); and when
 the value is between the two levels the output retains its value.

 The threshold levels are passed in the array @var{lvl}. If this is a scalar,
 the thresholds are symmetric around 0, i.e. @code{[-lvl lvl]}.

 The second output argument stores the ranges in which the output is high, so
 the indexes @var{rng(1,i):rng(2,i)} point to the i-th segment of 1s in @var{v}.
 See @code{clustersegment} for a detailed explanation.

 The function conserves the state of the trigger across calls (persistent variable).
 If the reset flag is active, i.e. @code{@var{rst}== true}, then the state of
 the trigger for all signals is set to the low state (i.e. 0).

 Example:
@example
 x = [0 0.5 1 1.5 2 1.5 1.5 1.2 1 0 0].';
 y = schtrig (x, [1.3 1.6]);
 disp ([x y]);
   0.0   0
   0.5   0
   1.0   0
   1.5   0
   2.0   1
   1.5   1
   1.5   1
   1.2   0
   1.0   0
   0.0   0
   0.0   0
@end example

 Run @code{demo schtrig} to see further examples.

@xseealso{clustersegment}
@end deftypefn
@c Utility upsamplefill
@c -----------------------------------------
@subsection upsamplefill
@cindex upsamplefill
@deftypefn  {Function File} {@var{y} =} upsamplefill (@var{x}, @var{v})
@deftypefnx {Function File} {@var{y} =} upsamplefill (@dots{}, @var{copy})
 Upsamples a vector interleaving given values or copies of the vector elements.

 The values in the vector @var{v} are placed between the elements of @var{x}.

 If the optional argument @var{copy} is @var{true} then @var{v} should be a
 scalar and each value in @var{x} are repeat @var{v} times.

 Example:
@example
@group
 upsamplefill (eye (2), 2, true)
@result{}  1   0
     1   0
     1   0
     0   1
     0   1
     0   1
 upsamplefill (eye (2), [-1 -1 -1])
@result{}  1   0
    -1  -1
    -1  -1
    -1  -1
     0   1
    -1  -1
    -1  -1
    -1  -1
@end group
@end example

@xseealso{upsample}
@end deftypefn
@c Utility wkeep
@c -----------------------------------------
@subsection wkeep
@cindex wkeep
@deftypefn  {Function File} {@var{y} =} wkeep (@var{x}, @var{l})
@deftypefnx {Function File} {@var{y} =} wkeep (@var{x}, @var{l}, @var{opt})
 Extract the elements of @var{x} of size @var{l} from the center, the right
 or the left.
@end deftypefn
@c Utility wrev
@c -----------------------------------------
@subsection wrev
@cindex wrev
@deftypefn {Function File} {@var{y} =} wrev (@var{x})
 Reverse the order of the element of the vector @var{x}.
@xseealso{flipud, fliplr}
@end deftypefn
@c Utility zerocrossing
@c -----------------------------------------
@subsection zerocrossing
@cindex zerocrossing
@deftypefn {Function File} {@var{x0} =} zerocrossing (@var{x}, @var{y})
 Estimates the points at which a given waveform y=y(x) crosses the
 x-axis using linear interpolation.
@xseealso{fzero, roots}
@end deftypefn
