./PaxHeaders.4544/signal-1.3.20000644000000000000000000000013012530736314012531 xustar0028 mtime=1432599756.8424109 30 atime=1432599756.854411378 30 ctime=1432599756.854411378 signal-1.3.2/0000755000000000000000000000000012530736314012774 5ustar00rootroot00000000000000signal-1.3.2/PaxHeaders.4544/src0000644000000000000000000000013212530736314013165 xustar0030 mtime=1432599756.846411059 30 atime=1432599756.854411378 30 ctime=1432599756.854411378 signal-1.3.2/src/0000755000000000000000000000000012530736314013563 5ustar00rootroot00000000000000signal-1.3.2/src/PaxHeaders.4544/cl2bp.cc0000644000000000000000000000012612530736314014556 xustar0028 mtime=1432599756.8424109 28 atime=1432599756.8424109 30 ctime=1432599756.854411378 signal-1.3.2/src/cl2bp.cc0000644000000000000000000001142012530736314015072 0ustar00rootroot00000000000000// Copyright (c) 2008-2009, Evgeni A. Nurminski // Copyright (c) 2008-2009, Pete Gonzalez // // This program is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software // Foundation; either version 3 of the License, or (at your option) any later // version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more // details. // // You should have received a copy of the GNU General Public License along with // this program; if not, see . #include #include "cl2bp_lib.h" static void cancel_handler(void *) { OCTAVE_QUIT; } // When CL2BP_LOGGING is defined, this will direct messages to the Octave pager void cl2bp_log(const char *message) { octave_stdout << message; } DEFUN_DLD (cl2bp, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{h} =} cl2bp (@var{m}, @var{w1}, @var{w2}, @var{up}, @var{lo})\n\ @deftypefnx {Loadable Function} {@var{h} =} cl2bp (@var{m}, @var{w1}, @var{w2}, @var{up}, @var{lo}, @var{gridsize})\n\ \n\ Constrained L2 bandpass FIR filter design. This is a fast implementation of\n\ the algorithm cited below. Compared to @dfn{remez}, it offers implicit\n\ specification of transition bands, a higher likelihood of convergence, and an\n\ error criterion combining features of both L2 and Chebyshev approaches.\n\ \n\ Inputs:\n\ \n\ @table @var\n\ @item m\n\ degree of cosine polynomial, i.e. the number of output coefficients will be\n\ @var{m}*2+1\n\ @item w1\n\ @itemx w2\n\ bandpass filter cutoffs in the range 0 <= @var{w1} < @var{w2} <= pi,\n\ where pi is the Nyquist frequency\n\ @item up\n\ vector of 3 upper bounds for [stopband1, passband, stopband2]\n\ @item lo\n\ vector of 3 lower bounds for [stopband1, passband, stopband2]\n\ @item gridsize\n\ search grid size; larger values may improve accuracy,\n\ but greatly increase calculation time.\n\ @end table\n\ \n\ Output:\n\ \n\ A vector of @var{m}*2+1 FIR coefficients, or an empty value if the solver\n\ failed to converge.\n\ \n\ Example:\n\ @example\n\ @code{h = cl2bp(30, 0.3*pi, 0.6*pi, [0.02, 1.02, 0.02], [-0.02, 0.98, -0.02], 2^11);}\n\ @end example\n\ \n\ Original Paper: I. W. Selesnick, M. Lang, and C. S. Burrus. A modified\n\ algorithm for constrained least square design of multiband FIR filters without\n\ specified transition bands.\n\ IEEE Trans. on Signal Processing, 46(2):497-501, February 1998.\n\ @end deftypefn\n\ @seealso{remez}\n") { octave_value_list retval; const int nargin = args.length(); if (nargin < 5 || nargin > 6) { print_usage (); return retval; } const int m = args(0).int_value(true); if (error_state) { gripe_wrong_type_arg("cl2bp", args (0)); return retval; } const double w1 = args(1).double_value(); if (error_state) { gripe_wrong_type_arg("cl2bp", args (1)); return retval; } const double w2 = args(2).double_value(); if (error_state) { gripe_wrong_type_arg("cl2bp", args (2)); return retval; } const ColumnVector up_vector(args(3).vector_value()); if (error_state) { gripe_wrong_type_arg("cl2bp", args (3)); return retval; } const ColumnVector lo_vector(args(4).vector_value()); if (error_state) { gripe_wrong_type_arg("cl2bp", args (4)); return retval; } if (up_vector.length() != 3 || lo_vector.length() != 3) { error("cl2bp: The up and lo vectors must contain 3 values"); return retval; } double up[3]; double lo[3]; for (int i=0; i<3; ++i) { up[i] = up_vector(i); lo[i] = lo_vector(i); } const int L = args(5).int_value(true); if (error_state) { gripe_wrong_type_arg("cl2bp", args (5)); return retval; } if (L > 1000000) { error("cl2bp: The \"gridsize\" parameter cannot exceed 1000000"); return retval; } MallocArray h; try { cl2bp(h, m, w1, w2, up, lo, L, 1.e-5, 20, cancel_handler); } catch (std::exception &ex) { error(ex.what()); return retval; } ColumnVector h_vector(h.get_length()); for (int i=0; i $@-t mv $@-t $@ clean: -rm -f *.o *.oct PKG_* .PHONY: all clean signal-1.3.2/src/PaxHeaders.4544/remez.cc0000644000000000000000000000013212530736314014673 xustar0030 mtime=1432599756.846411059 30 atime=1432599756.846411059 30 ctime=1432599756.854411378 signal-1.3.2/src/remez.cc0000644000000000000000000005773412530736314015234 0ustar00rootroot00000000000000// Copyright (c) 1995, 1998 Jake Janovetz // Copyright (c) 1999 Paul Kienzle // Copyright (c) 2000 Kai Habel // // This program is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software // Foundation; either version 3 of the License, or (at your option) any later // version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more // details. // // You should have received a copy of the GNU General Public License along with // this program; if not, see . /************************************************************************** * There appear to be some problems with the routine Search. See comments * therein [search for PAK:]. I haven't looked closely at the rest * of the code---it may also have some problems. *************************************************************************/ #include #include #ifndef OCTAVE_LOCAL_BUFFER #include #define OCTAVE_LOCAL_BUFFER(T, buf, size) \ std::vector buf ## _vector (size); \ T *buf = &(buf ## _vector[0]) #endif #define CONST const #define BANDPASS 1 #define DIFFERENTIATOR 2 #define HILBERT 3 #define NEGATIVE 0 #define POSITIVE 1 #define Pi 3.1415926535897932 #define Pi2 6.2831853071795865 #define GRIDDENSITY 16 #define MAXITERATIONS 40 /******************* * CreateDenseGrid *================= * Creates the dense grid of frequencies from the specified bands. * Also creates the Desired Frequency Response function (D[]) and * the Weight function (W[]) on that dense grid * * * INPUT: * ------ * int r - 1/2 the number of filter coefficients * int numtaps - Number of taps in the resulting filter * int numband - Number of bands in user specification * double bands[] - User-specified band edges [2*numband] * double des[] - Desired response per band [2*numband] * double weight[] - Weight per band [numband] * int symmetry - Symmetry of filter - used for grid check * int griddensity * * OUTPUT: * ------- * int gridsize - Number of elements in the dense frequency grid * double Grid[] - Frequencies (0 to 0.5) on the dense grid [gridsize] * double D[] - Desired response on the dense grid [gridsize] * double W[] - Weight function on the dense grid [gridsize] *******************/ void CreateDenseGrid(int r, int numtaps, int numband, const double bands[], const double des[], const double weight[], int gridsize, double Grid[], double D[], double W[], int symmetry, int griddensity) { int i, j, k, band; double delf, lowf, highf, grid0; delf = 0.5/(griddensity*r); /* * For differentiator, hilbert, * symmetry is odd and Grid[0] = max(delf, bands[0]) */ grid0 = (symmetry == NEGATIVE) && (delf > bands[0]) ? delf : bands[0]; j=0; for (band=0; band < numband; band++) { lowf = (band==0 ? grid0 : bands[2*band]); highf = bands[2*band + 1]; k = (int)((highf - lowf)/delf + 0.5); /* .5 for rounding */ if (band == 0 && symmetry == NEGATIVE) k--; for (i=0; i (0.5 - delf)) && (numtaps % 2)) { Grid[gridsize-1] = 0.5-delf; } } /******************** * InitialGuess *============== * Places Extremal Frequencies evenly throughout the dense grid. * * * INPUT: * ------ * int r - 1/2 the number of filter coefficients * int gridsize - Number of elements in the dense frequency grid * * OUTPUT: * ------- * int Ext[] - Extremal indexes to dense frequency grid [r+1] ********************/ void InitialGuess(int r, int Ext[], int gridsize) { int i; for (i=0; i<=r; i++) Ext[i] = i * (gridsize-1) / r; } /*********************** * CalcParms *=========== * * * INPUT: * ------ * int r - 1/2 the number of filter coefficients * int Ext[] - Extremal indexes to dense frequency grid [r+1] * double Grid[] - Frequencies (0 to 0.5) on the dense grid [gridsize] * double D[] - Desired response on the dense grid [gridsize] * double W[] - Weight function on the dense grid [gridsize] * * OUTPUT: * ------- * double ad[] - 'b' in Oppenheim & Schafer [r+1] * double x[] - [r+1] * double y[] - 'C' in Oppenheim & Schafer [r+1] ***********************/ void CalcParms(int r, int Ext[], double Grid[], double D[], double W[], double ad[], double x[], double y[]) { int i, j, k, ld; double sign, xi, delta, denom, numer; /* * Find x[] */ for (i=0; i<=r; i++) x[i] = cos(Pi2 * Grid[Ext[i]]); /* * Calculate ad[] - Oppenheim & Schafer eq 7.132 */ ld = (r-1)/15 + 1; /* Skips around to avoid round errors */ for (i=0; i<=r; i++) { denom = 1.0; xi = x[i]; for (j=0; j0.0) && (E[0]>E[1])) || ((E[0]<0.0) && (E[0]=E[i-1]) && (E[i]>E[i+1]) && (E[i]>0.0)) || ((E[i]<=E[i-1]) && (E[i]= 2*r) return -3; foundExt[k++] = i; } } /* * Check for extremum at 0.5 */ j = gridsize-1; if (((E[j]>0.0) && (E[j]>E[j-1])) || ((E[j]<0.0) && (E[j]= 2*r) return -3; foundExt[k++] = j; } // PAK: we sometimes get not enough extremal frequencies if (k < r+1) return -2; /* * Remove extra extremals */ extra = k - (r+1); assert(extra >= 0); while (extra > 0) { if (E[foundExt[0]] > 0.0) up = 1; /* first one is a maxima */ else up = 0; /* first one is a minima */ l=0; alt = 1; for (j=1; j 0.0)) up = 1; /* switch to a maxima */ else { alt = 0; // PAK: break now and you will delete the smallest overall // extremal. If you want to delete the smallest of the // pair of non-alternating extremals, then you must do: // // if (fabs(E[foundExt[j]]) < fabs(E[foundExt[j-1]])) l=j; // else l=j-1; break; /* Ooops, found two non-alternating */ } /* extrema. Delete smallest of them */ } /* if the loop finishes, all extrema are alternating */ /* * If there's only one extremal and all are alternating, * delete the smallest of the first/last extremals. */ if ((alt) && (extra == 1)) { if (fabs(E[foundExt[k-1]]) < fabs(E[foundExt[0]])) /* Delete last extremal */ l = k-1; // PAK: changed from l = foundExt[k-1]; else /* Delete first extremal */ l = 0; // PAK: changed from l = foundExt[0]; } for (j=l; j max) max = current; } return (((max-min)/max) < 0.0001); } /******************** * remez *======= * Calculates the optimal (in the Chebyshev/minimax sense) * FIR filter impulse response given a set of band edges, * the desired response on those bands, and the weight given to * the error in those bands. * * INPUT: * ------ * int numtaps - Number of filter coefficients * int numband - Number of bands in filter specification * double bands[] - User-specified band edges [2 * numband] * double des[] - User-specified band responses [numband] * double weight[] - User-specified error weights [numband] * int type - Type of filter * * OUTPUT: * ------- * double h[] - Impulse response of final filter [numtaps] * returns - true on success, false on failure to converge ********************/ int remez(double h[], int numtaps, int numband, const double bands[], const double des[], const double weight[], int type, int griddensity) { double *Grid, *W, *D, *E; int i, iter, gridsize, r, *Ext; double *taps, c; double *x, *y, *ad; int symmetry; if (type == BANDPASS) symmetry = POSITIVE; else symmetry = NEGATIVE; r = numtaps/2; /* number of extrema */ if ((numtaps%2) && (symmetry == POSITIVE)) r++; /* * Predict dense grid size in advance for memory allocation * .5 is so we round up, not truncate */ gridsize = 0; for (i=0; i 0.0001) W[i] = W[i]/Grid[i]; } } /* * For odd or Negative symmetry filters, alter the * D[] and W[] according to Parks McClellan */ if (symmetry == POSITIVE) { if (numtaps % 2 == 0) { for (i=0; i 6) { print_usage (); return retval; } int numtaps = NINT (args(0).double_value()) + 1; // #coeff = filter order+1 if (numtaps < 4) { error("remez: number of taps must be an integer greater than 3"); return retval; } ColumnVector o_bands(args(1).vector_value()); int numbands = o_bands.length()/2; OCTAVE_LOCAL_BUFFER(double, bands, numbands*2); if (numbands < 1 || o_bands.length()%2 == 1) { error("remez: must have an even number of band edges"); return retval; } for (i=1; i < o_bands.length(); i++) { if (o_bands(i) 1) { error("band edges must be in the range [0,1]"); return retval; } for(i=0; i < 2*numbands; i++) bands[i] = o_bands(i)/2.0; ColumnVector o_response(args(2).vector_value()); OCTAVE_LOCAL_BUFFER (double, response, numbands*2); if (o_response.length() != o_bands.length()) { error("remez: must have one response magnitude for each band edge"); return retval; } for(i=0; i < 2*numbands; i++) response[i] = o_response(i); std::string stype = std::string("bandpass"); int density = 16; OCTAVE_LOCAL_BUFFER (double, weight, numbands); for (i=0; i < numbands; i++) weight[i] = 1.0; if (nargin > 3) { if (args(3).is_string()) stype = args(3).string_value(); else if (args(3).is_real_matrix() || args(3).is_real_scalar()) { ColumnVector o_weight(args(3).vector_value()); if (o_weight.length() != numbands) { error("remez: need one weight for each band [=length(band)/2]"); return retval; } for (i=0; i < numbands; i++) weight[i] = o_weight(i); } else { error("remez: incorrect argument list"); return retval; } } if (nargin > 4) { if (args(4).is_string() && !args(3).is_string()) stype = args(4).string_value(); else if (args(4).is_real_scalar()) density = NINT(args(4).double_value()); else { error("remez: incorrect argument list"); return retval; } } if (nargin > 5) { if (args(5).is_real_scalar() && !args(4).is_real_scalar()) density = NINT(args(5).double_value()); else { error("remez: incorrect argument list"); return retval; } } int itype; if (stype == "bandpass") itype = BANDPASS; else if (stype == "differentiator") itype = DIFFERENTIATOR; else if (stype == "hilbert") itype = HILBERT; else { error("remez: unknown ftype '%s'", stype.data()); return retval; } if (density < 16) { error("remez: griddensity is too low; must be greater than 16"); return retval; } OCTAVE_LOCAL_BUFFER (double, coeff, numtaps+5); int err = remez(coeff,numtaps,numbands,bands,response,weight,itype,density); if (err == -1) warning("remez: -- failed to converge -- returned filter may be bad."); else if (err == -2) { error("remez: insufficient extremals--cannot continue"); return retval; } else if (err == -3) { error("remez: too many extremals--cannot continue"); return retval; } ColumnVector h(numtaps); while(numtaps--) h(numtaps) = coeff[numtaps]; return octave_value(h); } /* %!test %! b = [ %! 0.0415131831103279 %! 0.0581639884202646 %! -0.0281579212691008 %! -0.0535575358002337 %! -0.0617245915143180 %! 0.0507753178978075 %! 0.2079018331396460 %! 0.3327160895375440 %! 0.3327160895375440 %! 0.2079018331396460 %! 0.0507753178978075 %! -0.0617245915143180 %! -0.0535575358002337 %! -0.0281579212691008 %! 0.0581639884202646 %! 0.0415131831103279]; %! assert(remez(15,[0,0.3,0.4,1],[1,1,0,0]),b,1e-14); */ signal-1.3.2/src/PaxHeaders.4544/__ultrwin__.cc0000644000000000000000000000012612530736314016054 xustar0028 mtime=1432599756.8424109 28 atime=1432599756.8424109 30 ctime=1432599756.854411378 signal-1.3.2/src/__ultrwin__.cc0000644000000000000000000002162412530736314016377 0ustar00rootroot00000000000000// Copyright (c) 2013 Rob Sykes // // This program is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software // Foundation; either version 3 of the License, or (at your option) any later // version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more // details. // // You should have received a copy of the GNU General Public License along with // this program; if not, see . #include #include #include #include #include #if !defined M_PI #define M_PI 3.14159265358979323846 #endif #if DEBUG_ULTRWIN #define SHOW1(x) fprintf(stderr, "%c%+.3e", " 1"[(x) > .5], (x) - ((x) > .5)) #endif #define EPSILON (1./0x100000) /* For caller rounding error. */ #define BETA_MAX (12*(1+EPSILON)) #define XMU_MIN (.99*(1-EPSILON)) static double * ultraspherical_win(int n, double mu, double xmu) { double * w = NULL; int bad = n < 1 || xmu < XMU_MIN || (!mu && xmu == 1) || (n > BETA_MAX * 2 && xmu * cos(M_PI * BETA_MAX / n) > 1); if (!bad && (w = (double *)malloc(sizeof(*w)* n))) { int i, j, k, l = 0, m = (n + 1) / 2, met; double * divs = w + m - 1, c = 1 - 1 / (xmu * xmu), t, u, v[64], vp, s; for (i = 0; i < (int)(sizeof(v) / sizeof(v[0])); v[i++] = 0); if (n > 1) for (i = 0; i < m; l = j - (j <= i++)) { vp = *v, s = *v = i? (*v + v[1]) * mu * (divs[i] = 1./i) : 1; for (met = 0, j = 1, u = 1; ; ++l, v[l] = vp * (i - l) / (mu + l - 1)) { #define _ t = v[j], v[j] += vp, vp = t, t = s, s += \ v[j] * (u *= c * (n - i - j) * divs[j]), met = s && s == t, ++j, for (k = ((l-j+1) & ~7) + j; j < k && !met; _ _ _ _ _ _ _ _ (void)0); for (; j <= l && !met; _ (void)0); #undef _ if (met || !(j <= i)) break; } w[i] = s / (n - i - 1); } else w[0] = 1; u = 1 / w[i = m - 1], w[i] = 1; for (--i ; i >= 0; u *= (n - 2 - i + mu) / (n - 2 - i), w[i] *= u, --i); for (i = 0; i < m; w[n - 1 - i] = w[i], ++i); } return w; } typedef struct {double f, fp;} uspv_t; static uspv_t ultraspherical_polyval(int n, double mu, double x, double const *divs) { double fp = n > 0? 2 * x * mu : 1, fpp = 1, f; uspv_t result; int i, k; #define _ f = (2*x*(i+mu)*fp - (i+2*mu-1)*fpp) * divs[i+1], fpp=fp, fp=f, ++i, for (i = 1, k = i + ((n - i) & ~7); i < k; _ _ _ _ _ _ _ _ (void)0); for (; i < n; _ (void)0); #undef _ result.f = fp, result.fp = fpp; return result; } #define MU_EPSILON (1./0x4000) #define EQ(mu,x) (fabs((mu)-(x)) < MU_EPSILON) static uspv_t ultraspherical_polyval2( /* With non-+ve integer protection */ int n, double mu, double x, double const * divs) { int sign = (~(int)floor(mu) & ~(~2u/2))? 1:-1; /* -ve if floor(mu) <0 & odd */ uspv_t r; if (mu < MU_EPSILON && EQ(mu,(int)mu)) mu = floor(mu + .5) + MU_EPSILON * ((int)mu > mu? -1:1); r = ultraspherical_polyval(n, mu, x, divs); r.f *= sign, r.fp *= sign; return r; } static double find_zero(int n, double mu, int l, double extremum_mag, double ripple_ratio, double lower_bound, double const *divs) { double dx, x0, t, x, epsilon = 1e-10, one_over_deriv, target = 0; int i, met = 0; if (!divs) return 0; if (!l) { double r = ripple_ratio; /* FIXME: factor in weighted extremum_mag here */ x = r > 1 ? cosh(acosh(r) / n) : cos(acos(r) / n); /* invert chebpoly-1st */ x0 = x *= lower_bound / cos(M_PI * .5 / n) + epsilon; target = log(extremum_mag * ripple_ratio); } else { double cheb1 = cos(M_PI * (l - .5) / n), cheb2 = cos(M_PI * l / (n + 1)); if (mu < 1 - l && EQ((int)(mu+.5),mu+.5)) x = met = 1; else if (EQ(mu,0)) x = cheb1, met = 1; /* chebpoly-1st-kind */ else if (EQ(mu,1)) x = cheb2, met = 1; /* chebpoly-2nd-kind */ else x = (cheb1 * cheb2) / (mu * cheb1 + (1 - mu) * cheb2); x0 = x; } for (i = 0; i < 24 && !met; ++i, met = fabs(dx) < epsilon) {/*Newton-Raphson*/ uspv_t r = ultraspherical_polyval2(n, mu, x, divs); if (!(t = ((2*mu + n-1) * r.fp - n*x * r.f))) /* Fail if div by 0 */ break; one_over_deriv = (1 - x*x) / t; /* N-R slow for deriv~=1, so take log: */ if (!l) { /* d/dx(f(g(x))) = f'(g(x)).g'(x) */ one_over_deriv *= r.f; /* d/dx(log x) = 1/x */ if (r.f <= 0) /* Fail if log of non-+ve */ break; if (x + (dx = (target - log(r.f)) * one_over_deriv) <= lower_bound) dx = (lower_bound - x) * .875; x += dx; } else x += dx = -r.f * one_over_deriv; #if DEBUG_ULTRWIN fprintf(stderr, "1/deriv=%9.2e dx=%9.2e x=", one_over_deriv, dx); SHOW1(x); fprintf(stderr, "\n"); #endif } #if DEBUG_ULTRWIN fprintf(stderr, "find_zero(n=%i mu=%g l=%i target=%g r=%g x0=", n, mu, l, target, ripple_ratio); SHOW1(x0); fprintf(stderr, ") %s ", met? "converged to" : "FAILED at"); SHOW1(x); fprintf(stderr, " in %i iterations\n", i); #else static_cast(x0); #endif return met? x : 0; } static double * make_divs(int n, double **divs) { int i; if (!*divs) { *divs = (double *)malloc(n * sizeof(**divs)); if (*divs) for (i = 0; i < n; (*divs)[i] = 1./(i+1), ++i); } return *divs? *divs - 1 : 0; } #define DIVS make_divs(n, &divs) typedef enum {uswpt_Xmu, uswpt_Beta, uswpt_AttFirst, uswpt_AttLast} uswpt_t; double * ultraspherical_window(int n, double mu, double par, uswpt_t type, int even_norm, double *xmu_) { double * w = 0, xmu = 0, * divs = 0, last_extremum_pos = 0; if (n > 0 && fabs(mu) <= (8*(1+EPSILON))) switch (type) { case uswpt_Beta: xmu = mu == 1 && par == 1? 1 : par < .5 || par > BETA_MAX? 0 : find_zero(n-1, mu, 1, 0, 0, 0, DIVS) / cos(M_PI * par / n); break; case uswpt_AttFirst: if (par < 0) break; /* Falling... */ case uswpt_AttLast: if (type == uswpt_AttLast && mu >= 0 && par < 0); else if (!EQ(mu,0)) { int extremum_num = type == uswpt_AttLast? (int)((n-2)/2 +.5) : 1 + EQ(mu,-1.5); double extremum_pos = find_zero(n-2, mu+1, extremum_num, 0, 0, 0, DIVS); double extremum_mag = !extremum_pos? 0 : fabs(ultraspherical_polyval2(n-1, mu, extremum_pos, DIVS).f); double xmu_lower_bound = !extremum_mag? 0 : find_zero(n-1, mu, 1, 0, 0, 0, DIVS); /* 1st null */ xmu = !xmu_lower_bound? 0 : find_zero( n-1, mu, 0, extremum_mag, pow(10, par/20), xmu_lower_bound, DIVS); last_extremum_pos = type == uswpt_AttLast? extremum_pos : last_extremum_pos; } else xmu = cosh(acosh(pow(10, par/20))/(n-1)); /* Cheby 1st kind */ break; default: case uswpt_Xmu: xmu = par; break; } #if DEBUG_ULTRWIN fprintf(stderr, "n=%i mu=%.3f xmu=%.16g\n", n, mu, xmu); #endif if (xmu > 0) w = ultraspherical_win(n, mu, xmu); if (w && (~n & !!even_norm) && n > 2 && !(mu == 1 && xmu == 1)) { int i = n / 2 - 1, j = 1; double * d = DIVS, t = 0, s = -1, x = even_norm == 1? 0 : last_extremum_pos? last_extremum_pos : find_zero(n-2, mu+1, i, 0, 0, 0, d); x = x? M_PI/2 - acos(x/xmu) : 0; for (; i >= 0; t += w[i] * d[j] * (s=-s) * (x?cos(j*x):1), --i, j += 2); for (t = M_PI/4 / t, i = 0; t < 1 && i < n; w[i] *= t, ++i); #if DEBUG_ULTRWIN fprintf(stderr, "%snorm DFT(w.sinc πx) @ %g %.16g\n", t<1? "":"NO ", 2*x,t); #endif } free(divs); if (xmu_) *xmu_ = xmu; return w; } //---------------------------------------------------------------------------- DEFUN_DLD (__ultrwin__, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} __ultrwin__ (@var{m}, @var{mu}, @var{par}, @var{par_type}, @var{norm})\n\ Undocumented internal function.\n\ @end deftypefn") { octave_value_list retval; int nargin = args.length (); if (nargin != 5) { print_usage (); return retval; } for (octave_idx_type i = 0; i < nargin; i++) if (! args(i).is_real_scalar ()) { print_usage (); return retval; } int m = args(0).scalar_value (); double mu = args(1).scalar_value (); double par = args(2).scalar_value (); uswpt_t par_type = static_cast (args(3).scalar_value ()); int even_norm = args(4).scalar_value (); double xmu; double *w = ultraspherical_window (m, mu, par, par_type, even_norm, &xmu); if (!w) { error ("ultrwin: parameter(s) out of range"); return retval; } ColumnVector ww (m); for (octave_idx_type i = 0; i < m; i++) ww(i) = w[i]; free (w); retval(0) = ww; retval(1) = xmu; return retval; } /* ## No test needed for internal helper function. %!assert (1) */ signal-1.3.2/src/PaxHeaders.4544/__fwht__.cc0000644000000000000000000000012612530736314015320 xustar0028 mtime=1432599756.8424109 28 atime=1432599756.8424109 30 ctime=1432599756.854411378 signal-1.3.2/src/__fwht__.cc0000644000000000000000000000333512530736314015642 0ustar00rootroot00000000000000// Copyright (C) 2013 Mike Miller // // This program is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software // Foundation; either version 3 of the License, or (at your option) any later // version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more // details. // // You should have received a copy of the GNU General Public License along with // this program; if not, see . #include template static void do_fwht (T *x, octave_idx_type n) { double *xa = &x[0]; double *xb = &x[n/2]; // Perform the FWHT butterfly on the input for (octave_idx_type i = 0; i < n/2; i++) { double ya = xa[i] + xb[i]; double yb = xa[i] - xb[i]; xa[i] = ya; xb[i] = yb; } // Divide and conquer if (n > 2) { do_fwht (xa, n/2); do_fwht (xb, n/2); } } DEFUN_DLD (__fwht__, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} __fwht__ (@var{x})\n\ Undocumented internal function.\n\ @end deftypefn") { int nargin = args.length (); if (nargin != 1) print_usage (); else { NDArray x = args(0).array_value (); octave_idx_type n = x.rows (); double *data = x.fortran_vec (); for (octave_idx_type i = 0; i < x.columns (); i++) { do_fwht (&data[i*n], n); } return octave_value (x); } return octave_value (); } /* ## No test needed for internal helper function. %!assert (1) */ signal-1.3.2/src/PaxHeaders.4544/upfirdn.cc0000644000000000000000000000013212530736314015220 xustar0030 mtime=1432599756.846411059 30 atime=1432599756.846411059 30 ctime=1432599756.854411378 signal-1.3.2/src/upfirdn.cc0000644000000000000000000001006712530736314015545 0ustar00rootroot00000000000000// Copyright (C) 2008 Eric Chassande-Mottin, CNRS (France) // // This program is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software // Foundation; either version 3 of the License, or (at your option) any later // version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more // details. // // You should have received a copy of the GNU General Public License along with // this program; if not, see . #include #include #include #include #include #include #include #include template MT upfirdn (MT &x, ColumnVector &h, octave_idx_type p, octave_idx_type q) { octave_idx_type rx = x.rows (); octave_idx_type cx = x.columns (); bool isrowvector = false; if ((rx == 1) && (cx > 1)) // if row vector, transpose to column vector { x = x.transpose (); rx = x.rows (); cx = x.columns (); isrowvector = true; } octave_idx_type Lh = h.length (); const double r = p/(static_cast (q)); const octave_idx_type Ly = ceil (static_cast ((rx-1)*p + Lh) / static_cast (q)); MT y (Ly, cx, 0.0); for (octave_idx_type c = 0; c < cx; c++) { octave_idx_type m = 0; while (m < Ly) { const octave_idx_type n = floor (m/r); const octave_idx_type lm = (m * q) % p; octave_idx_type k = 0; typename MT::element_type accum; accum = 0.0; do { octave_idx_type ix = n - k; if (ix >= rx) { k ++; continue; } const octave_idx_type ih = k * p + lm; if ((ih >= Lh) | (ix < 0)) break; accum += h (ih) * x (ix, c); k++; } while (1); y (m, c) = accum; m ++; } } if (isrowvector) y = y.transpose (); return y; } DEFUN_DLD (upfirdn, args,, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{y} =} upfirdn (@var{x}, @var{h}, @var{p}, @var{q})\n\ Upsample, FIR filtering, and downsample.\n\ @end deftypefn\n") { octave_value_list retval; const int nargin = args.length (); if (nargin != 4) { print_usage (); return retval; } ColumnVector h (args (1).vector_value ()); if (error_state) { gripe_wrong_type_arg ("upfirdn", args (1)); return retval; } octave_idx_type p = args (2).idx_type_value (); if (error_state) { gripe_wrong_type_arg ("upfirdn", args (2)); return retval; } octave_idx_type q = args (3).idx_type_value (); if (error_state) { gripe_wrong_type_arg ("upfirdn", args (3)); return retval; } // Do the dispatching if (args (0).is_real_type ()) { Matrix x = args (0).matrix_value (); if (error_state) { gripe_wrong_type_arg ("upfirdn", args (0)); return retval; } Matrix y = upfirdn (x, h, p, q); retval (0) = y; } else if (args (0).is_complex_type ()) { ComplexMatrix x = args (0).complex_matrix_value (); if (error_state) { gripe_wrong_type_arg ("upfirdn", args (0)); return retval; } ComplexMatrix y = upfirdn (x, h, p, q); retval (0) = y; } else { gripe_wrong_type_arg ("upfirdn", args (0)); return retval; } return retval; } /* %!assert (isequal (upfirdn (1:100, 1, 1, 1), 1:100)) %!assert (isequal (upfirdn (1:100, 1, 1, 2), 1:2:100)) %% Test input validation %!error upfirdn () %!error upfirdn (1,2) %!error upfirdn (1,2,3) %!error upfirdn (1,2,3,4,5) */ signal-1.3.2/src/PaxHeaders.4544/sosfilt.cc0000644000000000000000000000013212530736314015234 xustar0030 mtime=1432599756.846411059 30 atime=1432599756.846411059 30 ctime=1432599756.854411378 signal-1.3.2/src/sosfilt.cc0000644000000000000000000000567612530736314015573 0ustar00rootroot00000000000000// Copyright (C) 2008 Eric Chassande-Mottin, CNRS (France) // // This program is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software // Foundation; either version 3 of the License, or (at your option) any later // version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more // details. // // You should have received a copy of the GNU General Public License along with // this program; if not, see . #include #include #include #include #include #include #include #include DEFUN_DLD (sosfilt, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{y} =} sosfilt (@var{sos}, @var{x})\n\ Second order section IIR filtering of @var{x}. The second order section\n\ filter is described by the matrix @var{sos} with:\n\ \n\ @multitable {col 1} {this is column two}\n\ @item @tab [ @var{B1} @var{A1} ]@*\n\ @item @var{sos} = @tab [ @dots{} ],@*\n\ @item @tab [ @var{BN} @var{AN} ]@*\n\ @end multitable\n\ \n\ where @code{@var{B1} = [b0 b1 b2]} and @code{@var{A1} = [1 a1 a2]} for\n\ section 1, etc. The b0 entry must be nonzero for each section.\n\ @end deftypefn\n") { octave_value_list retval; int nargin = args.length (); if (nargin != 2) { print_usage (); return retval; } Matrix sos( args(0).matrix_value() ); if (error_state) { gripe_wrong_type_arg("sosfilt",args(0)); return retval; } if (sos.columns() != 6) { error("Second-order section matrix must be a non-empty Lx6 matrix"); return retval; } Matrix x( args(1).matrix_value() ); if (error_state) { gripe_wrong_type_arg("sosfilt",args(1)); return retval; } int n=x.rows(); int m=x.columns(); bool isrowvector=false; if ((n==1)&&(m>1)) // if row vector, transpose to column vector { x=x.transpose(); n=x.rows(); m=x.columns(); isrowvector=true; } Matrix y(n,m,0.0); for (int k=0; k // Copyright (c) 2008-2009, Pete Gonzalez // // This program is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software // Foundation; either version 3 of the License, or (at your option) any later // version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more // details. // // You should have received a copy of the GNU General Public License along with // this program; if not, see . #ifndef CL2BP_H #define CL2BP_H #include #include #include //for memset //----------------------------------------------------------------------------------------------------------- // If you want to debug the cl2bp algorithm, define the CL2BP_LOGGING symbol and provide an // implementation of cl2bp_log(). #ifdef CL2BP_LOGGING extern void cl2bp_log(const char *message); #endif //----------------------------------------------------------------------------------------------------------- // This is a simple helper class that performs bounds-checking for debug builds, but reduces to an unchecked // malloc() array for release builds. template class MallocArray { int length; T *ptr; public: T& operator[](int index) { assert(index >= 0 && index < length); return ptr[index]; } T operator[](int index) const { assert(index >= 0 && index < length); return ptr[index]; } int get_length() const { return length; } void resize(int length_) { assert(length_ >= 0 && length_ <= 512*1024*1024); // verify that the array size is reasonable length = length_; ptr = (T *)realloc(ptr, length * sizeof(T)); std::memset(ptr, 0, length * sizeof(T)); } MallocArray(int length_=0) { ptr = 0; length = 0; if (length_) resize(length_); } ~MallocArray() { free(ptr); } private: MallocArray(const MallocArray&) { } // copy constructor is unimplemented and disallowed }; //----------------------------------------------------------------------------------------------------------- // Constrained L2 BandPass FIR filter design // h 2*m+1 filter coefficients (output) // m degree of cosine polynomial // w1,w2 fist and second band edges // up upper bounds // lo lower bounds // L grid size // eps stopping condition ("SN") // mit maximum number of iterations // // cl2bp() returns true if the solver converged, or false if the maximum number of iterations was reached. // If provided, the cancel_handler function pointer will be called periodically inside long-running loops, // giving an opportunity to abort (by throwing a C++ exception). The cancel_state parameter is a // user-defined pointer, e.g. a button object, boolean flag, or other means of detecting a cancel request. // // Example usage: // MallocArray coefficients; // double up[3] = { 0.02, 1.02, 0.02 }; // double lo[3] = { -0.02, 0.98, -0.02 }; // cl2bp(coefficients, 30, 0.3*M_PI, 0.6*M_PI, up, lo, 1<<11, 1.e-5, 20); // // The algorithm is described in this 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. bool cl2bp(MallocArray& h, int m, double w1, double w2, double up[3], double lo[3], int L, double eps, int mit, void (*cancel_handler)(void *)=0, void *cancel_state=0); #endif signal-1.3.2/src/PaxHeaders.4544/cl2bp_lib.cc0000644000000000000000000000012612530736314015404 xustar0028 mtime=1432599756.8424109 28 atime=1432599756.8424109 30 ctime=1432599756.854411378 signal-1.3.2/src/cl2bp_lib.cc0000644000000000000000000004200112530736314015717 0ustar00rootroot00000000000000// Copyright (c) 2008-2009, Evgeni A. Nurminski // Copyright (c) 2008-2009, Pete Gonzalez // // This program is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software // Foundation; either version 3 of the License, or (at your option) any later // version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more // details. // // You should have received a copy of the GNU General Public License along with // this program; if not, see . #ifdef _MSC_VER #define _CRT_SECURE_NO_WARNINGS // disable spurious warnings #define _USE_MATH_DEFINES // for math.h #endif #include "cl2bp_lib.h" #include #include #include #include #include #include #define BIG_NUMBER 100000 //----------------------------------------------------------------------------------------------------------- #ifdef CL2BP_LOGGING static void log_printf(const char *format, ...) { va_list argptr; va_start(argptr, format); char buf[20*1024]; if (vsnprintf(buf,20*1024-1,format,argptr) == -1) { strcpy(buf, "#ERROR#"); } va_end(argptr); cl2bp_log(buf); } #else #define log_printf(...) ((void)0) // don't log anything (for a big speed improvement) #endif //----------------------------------------------------------------------------------------------------------- static int local_max(const MallocArray& x, int n, MallocArray& ix) { int i, mx; mx = 0; MallocArray xx(n+2); xx[0] = xx[n + 1] = -BIG_NUMBER; for ( i = 1; i <= n; i++) xx[i] = x[i - 1]; for ( i = 0; i < n; i++ ) { (((xx[i] < xx[i + 1]) && (xx[i + 1] > xx[i + 2])) || ((xx[i] < xx[i + 1]) && (xx[i + 1] >= xx[i + 2])) || ((xx[i] <= xx[i + 1]) && (xx[i + 1] > xx[i + 2])) ) && ( ix[mx++] = i ); } return mx; } //----------------------------------------------------------------------------------------------------------- static int solvps(MallocArray& a, MallocArray& b, int n, void (*cancel_handler)(void *), void *cancel_state) { double t; int j, k; int a_p; int a_q; int a_r; int a_s; // In empirical tests, 2% to 6% of the execution time was spent in solvps() if (cancel_handler) cancel_handler(cancel_state); for (j = 0, a_p = 0; j < n; ++j, a_p += n+1) { for (a_q = j*n; a_q < a_p; ++a_q) a[a_p] -= a[a_q] * a[a_q]; if (a[a_p] <= 0.) return -1; a[a_p] = sqrt(a[a_p]); for (k = j + 1, a_q = a_p + n; k < n; ++k, a_q += n) { for (a_r = j*n, a_s = k*n, t = 0.; a_r < a_p;) t += a[a_r++] * a[a_s++]; a[a_q] -= t; a[a_q] /= a[a_p]; } } for (j = 0, a_p = 0; j < n; ++j, a_p += n+1) { for (k = 0, a_q = j*n; k < j;) b[j] -=b [k++] * a[a_q++]; b[j] /= a[a_p]; } for (j = n - 1, a_p = n*n - 1; j >= 0; --j, a_p -= n + 1) { for (k = j + 1, a_q = a_p + n; k < n; a_q += n) b[j] -= b[k++]* a[a_q]; b[j] /= a[a_p]; } return 0; } //----------------------------------------------------------------------------------------------------------- static void rmmult(MallocArray& rm, const MallocArray& a, const MallocArray& b, int n, int m, int l, void (*cancel_handler)(void *), void *cancel_state) { double z; int i,j,k; int b_p; // index into b int a_p; // index into a int rm_start = 0; // index into rm int rm_q; // index into rm MallocArray q0(m); for (i = 0; i < l ; ++i, ++rm_start) { // In empirical tests, 87% to 95% of the execution time was spent in rmmult() if (cancel_handler) cancel_handler(cancel_state); for (k = 0, b_p = i; k < m; b_p += l) q0[k++] = b[b_p]; for (j = 0, a_p = 0, rm_q = rm_start; j < n; ++j, rm_q += l) { for (k = 0, z = 0.; k < m;) z += a[a_p++] * q0[k++]; rm[rm_q]=z; } } } //----------------------------------------------------------------------------------------------------------- static void mattr(MallocArray& a, const MallocArray& b, int m, int n) { int i, j; int b_p; int a_p = 0; int b_start = 0; for (i = 0; i < n; ++i, ++b_start) for ( j = 0, b_p = b_start; j < m; ++j, b_p += n ) a[a_p++] = b[b_p]; } //----------------------------------------------------------------------------------------------------------- static void calcAx(MallocArray& Ax, int m, int L) { double r = M_SQRT2, pi = M_PI; int i, j; Ax.resize((L+1)*(m + 1)); for ( i = 0; i <= L; i++) for ( j = 0; j <= m; j++) Ax[i*(m+1) + j] = cos(i*j*pi/L); for ( i = 0; i < (L+1)*(m+1); i += m + 1 ) Ax[i] /= r; } //----------------------------------------------------------------------------------------------------------- #ifdef CL2BP_LOGGING static double L2error(const MallocArray& x, const MallocArray& w, int L, double w1, double w2) { double xx, ww, sumerr, pi = M_PI; int i; for ( i = 0, sumerr = 0; i < L + 1; i++ ) { ww = w[i]; xx = x[i]; sumerr += ( ww < w1*pi || ww > w2*pi ) ? xx*xx : (1 - xx)*(1 - xx); } return sumerr; } #endif // CL2BP_LOGGING //----------------------------------------------------------------------------------------------------------- static double CHerror(double *wmin, const MallocArray& x, const MallocArray& w, int L, double w1, double w2) { double xx, ww, err, errmax; int i; errmax = -1; *wmin = 0; for ( i = 0; i < L + 1; i++ ) { ww = w[i]; xx = x[i]; err = (( ww < w1 ) || (ww > w2 )) ? fabs(xx) : fabs(1 - xx); if ( err > errmax ) { errmax = err; *wmin = ww; } } return errmax; } //----------------------------------------------------------------------------------------------------------- static void Ggen(MallocArray& G, int m, const MallocArray& w, const MallocArray& kmax, int l_kmax, const MallocArray& kmin, int l_kmin) { G.resize((l_kmax + l_kmin)*(m + 1)); int nsys, i, j; double r = M_SQRT2; nsys = l_kmax + l_kmin; for ( i = 0; i < l_kmax; i++) for ( j = 0; j <= m; j++) G[i*(m+1) + j] = cos(w[kmax[i]]*j); for ( i = l_kmax; i < nsys; i++) for ( j = 0; j <= m; j++) G[i*(m+1) + j] = -cos(w[kmin[i - l_kmax]]*j); for ( i = 0; i < nsys*(m+1); i += m+1 ) G[i] /= r; } //----------------------------------------------------------------------------------------------------------- bool cl2bp(MallocArray& h, int m, double w1, double w2, double up[3], double lo[3], int L, double eps, int mit, void (*cancel_handler)(void *), void *cancel_state) { // Ensure sane values for input parameters if (m < 2 || m > 5000) throw std::invalid_argument("cl2bp: The m count must be between 2 and 5000"); if (w1 < 0 || w1 > w2 || w2 > 2*M_PI) throw std::invalid_argument("cl2bp: The cutoffs must be in the range 0 < w1 < w2 < 2*pi"); // Z is allocated as Z(2*L-1-2*m) if (L <= m) throw std::invalid_argument("cl2bp: The \"gridsize\" parameter must be larger than \"m\""); double r = M_SQRT2; double pi = M_PI; double wmin, ww, xw; int q1, q2, q3, i, iter = 0; int off, neg; int ik; int l_kmax; int l_kmin; int l_okmax; int l_okmin; double uvo = 0, lvo = 0; double err, diff_up, diff_lo; double erru, erro; int iup, ilo; int nsys, j; int imin = BIG_NUMBER; double umin; int k1 = -1, k2 = -1, ak1, ak2; double cerr; h.resize(2*m+1); bool converged = true; MallocArray x0(L+1); MallocArray x1(L+1); MallocArray xx(L+1); MallocArray xm1(L+1); MallocArray w(L+1); MallocArray u(L+1); MallocArray l(L+1); MallocArray a(L+1); MallocArray c(L+1); MallocArray kmax(L+1); MallocArray kmin(L+1); l_kmax = l_kmin = 0; MallocArray okmin(L+1); MallocArray okmax(L+1); l_okmax = l_okmin = 0; MallocArray rhs(m+2); MallocArray mu(2*(L+1)); for ( i = 0; i <= L; i++ ) w[i] = i*pi/L; MallocArray Z(2*L-1-2*m); q1 = (int)floor(L*w1/pi); q2 = (int)floor(L*(w2-w1)/pi); q3 = L + 1 - q1 - q2; off = 0; for ( i = 0; i < q1; i++) { u[i] = up[0]; l[i] = lo[0]; } off += i; for ( i = 0; i < q2; i++) { u[off + i] = up[1]; l[off + i] = lo[1]; } off += i; for ( i = 0; i < q3; i++) { u[off + i] = up[2]; l[off + i] = lo[2]; } c[0] = (w2-w1)*r; for ( i = 1; i <= m; i++) c[i] = 2*(sin(w2*i)-sin(w1*i))/i; for ( i = 0; i <= m; i++) { c[i] /= pi; a[i] = c[i]; } log_printf("\nInitial approximation. Unconstrained L2 filter coefficients.\n"); log_printf("=============================================================\n"); log_printf("\nZero order term %8.3lf\n", a[0]); for ( i = 1; i <= m; i++) { log_printf("%4d %8.3lf", i, a[i]); if (i - 8*(i/8) == 0) log_printf("\n"); } log_printf("\n"); // Precalculate Ax MallocArray Ax; calcAx(Ax, m, L); //calcA(x0, a, m, L); rmmult(x0, Ax, a, L + 1, m + 1, 1, cancel_handler, cancel_state); err = CHerror(&wmin, x0, w, L, w1, w2); log_printf("\nChebyshev err %12.4e (%11.5e) <> L2 err %12.4e\n", err, wmin/pi, L2error(x0, w, L, w1, w2)/(L+1)); for (iter = 1; ; iter++) { log_printf("\n:::::: Iteration %3d :::::::::::\n", iter); if ( (uvo > eps*2) || (lvo > eps*2) ) { log_printf("\nXXX Take care of old errors: uvo lvo %12.3e %12.3e", uvo, lvo); if( k1 >= 0 ) log_printf(" k1 %3d(%d)", k1, okmax[k1]); if( k2 >= 0 ) log_printf(" k2 %3d(%d)", k2, okmin[k2]); log_printf("\n"); if ( uvo > lvo ) { kmax[l_kmax] = okmax[k1]; l_kmax++; l_okmax--; for (i = k1; i < l_okmax; i++) okmax[i] = okmax[i + 1]; } else { kmin[l_kmin] = okmin[k2]; l_kmin++; l_okmin--; for (i = k2; i < l_okmin; i++) okmin[i] = okmin[i + 1]; } nsys = l_kmax + l_kmin; /* for (i = 0; i < l_kmax; i++) log_printf("i %3d kmax %3d mu %12.4e\n", i, kmax[i], mu[i]); log_printf("\n"); for (i = 0; i < l_kmin; i++) log_printf("i %3d kmin %3d mu %12.4e\n", i, kmin[i], mu[i + l_kmax]); log_printf("\n\n"); */ } else { //calcA(x1, a, m, L); rmmult(x1, Ax, a, L + 1, m + 1, 1, cancel_handler, cancel_state); for ( i = 0; i < l_kmax; i++) okmax[i] = kmax[i]; for ( i = 0; i < l_kmin; i++) okmin[i] = kmin[i]; l_okmax = l_kmax; l_okmin = l_kmin; l_kmax = local_max(x1, L + 1, kmax); for ( i = 0; i < L + 1; i++) xm1[i] = -x1[i]; l_kmin = local_max(xm1, L + 1, kmin); log_printf("\nSignificant deviations from the ideal filter. Levels:"); log_printf(" %8.2e %8.2e %8.2e (lo)", lo[0], lo[1], lo[2]); log_printf(" %8.2e %8.2e %8.2e (up)", up[0], up[1], up[2]); log_printf("\n"); for ( i = 0, ik = 0; i < l_kmax; i++) { j = kmax[i]; if ( x1[j] > u[j] - 10*eps ) { kmax[ik] = j; ik++; } } l_kmax = ik; log_printf("overshoots = %d\n", l_kmax); for ( i = 0; i < l_kmax; i++) { j = kmax[i]; ww = w[j]; xw = x1[j]; err = (w1 < ww && ww < w2) ? xw - 1 : xw; log_printf(" i = %3d kmax = %3d xw = %12.5e err = %10.3e u = %12.4e max = %9.2e\n", i, j, xw, err, u[j], xw - u[j]); } for ( i = 0, ik = 0; i < l_kmin; i++) { j = kmin[i]; if ( x1[j] < l[j] + 10*eps ) { kmin[ik] = j; ik++; } } l_kmin = ik; log_printf("undershoots = %d\n", l_kmin); for ( i = 0; i < l_kmin; i++) { j = kmin[i]; ww = w[j]; xw = -xm1[j]; err =(w1 < ww && ww < w2) ? xw - 1 : xw; log_printf(" i = %3d kmin = %3d xw = %12.5e err = %10.3e l = %12.4e min = %9.2e\n", i, j, xw, err, l[j], xw - l[j]); } err = erru = erro = diff_up = diff_lo = 0; iup = ilo = 0; for ( i = 0; i < l_kmax; i++) { ik = kmax[i]; diff_up = x1[ik] - u[ik]; if ( diff_up > erru ) { erru = diff_up; iup = i; } } for ( i = 0; i < l_kmin; i++) { ik = kmin[i]; diff_lo = l[ik] - x1[ik]; if ( diff_lo > erro ) { erro = diff_lo; ilo = i; } } err = erro > erru ? erro : erru; log_printf("erru = %14.6e iup = %4d kmax = %4d ", erru, iup, kmax[iup]); log_printf("erro = %14.6e ilo = %4d kmin = %4d\n", erro, ilo, kmin[ilo]); #ifndef CL2BP_LOGGING static_cast(iup); #endif if ( err < eps ) break; } nsys = l_kmax + l_kmin; MallocArray G(nsys*(m + 1)); MallocArray GT(nsys*(m + 1)); MallocArray GG(nsys*nsys); for ( i = 0; i < l_kmax; i++) for ( j = 0; j <= m; j++) G[i*(m+1) + j] = cos(w[kmax[i]]*j); for ( i = l_kmax; i < nsys; i++) for ( j = 0; j <= m; j++) G[i*(m+1) + j] = -cos(w[kmin[i - l_kmax]]*j); for ( i = 0; i < nsys*(m+1); i += m+1 ) G[i] /= r; mattr(GT, G, nsys, m + 1); rmmult(GG, G, GT, nsys, m + 1, nsys, cancel_handler, cancel_state); rmmult(rhs, G, c, nsys, m + 1, 1, cancel_handler, cancel_state); for ( i = 0; i < nsys; i++) if ( i < l_kmax ) rhs[i] -= u[kmax[i]]; else rhs[i] += l[kmin[i - l_kmax]]; for ( i = 0; i < nsys; ++i) mu[i] = rhs[i]; solvps(GG, mu, nsys, cancel_handler, cancel_state); log_printf("\nXXX KT-system with %d equations resolved.\n", nsys); for ( i = 0, neg = 0; i < nsys; i++) if ( mu[i] < 0 ) neg++; log_printf("\nTotal number of negative multipliers = %3d\n\n", neg); while (neg) { umin = BIG_NUMBER; for ( i = 0, j = 0; i < nsys; i++) { if ( mu[i] >= 0 ) continue; j++; if ( mu[i] < umin ) { imin = i; umin = mu[i]; } } if ( umin > 0 ) break; log_printf(" neg = %3d of %3d imin = %3d mu-min = %12.4e\n", j, nsys, imin, umin); for ( i = imin; i < nsys - 1; i++) { rhs[i] = rhs[i + 1]; for ( j = 0; j <= m; j++) G[i*(m + 1) + j] = G[(i + 1)*(m + 1) + j]; } if ( imin < l_kmax ) { for ( i = imin; i < l_kmax - 1; i++) kmax[i] = kmax[i + 1]; l_kmax--; } else { for ( i = imin; i < nsys - 1; i++) kmin[i - l_kmax] = kmin[i - l_kmax + 1]; l_kmin--; } --nsys; mattr(GT, G, nsys, m + 1); rmmult(GG, G, GT, nsys, m + 1, nsys, cancel_handler, cancel_state); for ( i = 0; i < nsys; ++i) mu[i] = rhs[i]; solvps(GG, mu, nsys, cancel_handler, cancel_state); } MallocArray da(m + 1); MallocArray zd(nsys); rmmult(da, GT, mu, m + 1, nsys, 1, cancel_handler, cancel_state); for ( i = 0; i <= m; i++) a[i] = c[i] - da[i]; rmmult(zd, G, a, nsys, m + 1, 1, cancel_handler, cancel_state); MallocArray zz(l_okmax + l_okmin); Ggen(G, m, w, okmax, l_okmax, okmin, l_okmin); rmmult(zz, G, a, l_okmax + l_okmin, m + 1, 1, cancel_handler, cancel_state); uvo = lvo = eps; k1 = k2 = -1; ak1 = ak2 = -1; if (l_okmax + l_okmin > 0) log_printf("\nErrors on the previous set of freqs\n\n"); for (i = 0; i < l_okmax; i++) { j = okmax[i]; cerr = zz[i] - u[j]; log_printf(" i %2d j %3d u %12.4e Ga %12.4e cerr %12.4e\n", i, j, u[j], zz[i], cerr); if ( cerr > uvo ) { uvo = cerr; k1 = i; ak1 = j; } } cerr = 0; for (i = 0; i < l_okmin; i++) { j = okmin[i]; cerr = l[j] + zz[i + l_okmax]; log_printf(" i %2d j %3d l %12.4e Ga %12.4e cerr %12.4e\n", i, j, l[j], zz[i + l_okmax], cerr); if ( cerr > lvo ) { lvo = cerr; k2 = i, ak2 = j; } } if ( l_okmax + l_okmin > 0 ) { log_printf("\n uvo = %12.4e k1 = %4d (%3d) ", uvo, k1, ak1); log_printf(" lvo = %12.4e k2 = %4d (%3d) ", lvo, k2, ak2); log_printf(" maxerr = %12.4e\n", uvo > lvo ? uvo : lvo); #ifndef CL2BP_LOGGING static_cast(ak1); #endif } log_printf("\nConstrained L2 band filter coefficients.\n"); log_printf("=====================================\n"); #ifdef CL2BP_LOGGING log_printf("\nZero order term %8.3lf\n", a[0]); for ( i = 1; i <= m; i++) { log_printf("%4d %8.3lf", i, a[i]); if (i - 8*(i/8) == 0) log_printf("\n"); } log_printf("\n"); #endif //calcA(xx, a, m, L); rmmult(xx, Ax, a, L + 1, m + 1, 1, cancel_handler, cancel_state); if ( iter >= mit ) { log_printf("Maximum iterations reached\n"); converged = false; } } for (i = 0; i < m; i++) { h[i] = a[m - i]/2; h[m + i + 1] = a[i + 1]/2; } h[m] = a[0]*r/2; return converged; } signal-1.3.2/src/PaxHeaders.4544/medfilt1.cc0000644000000000000000000000013212530736314015256 xustar0030 mtime=1432599756.846411059 30 atime=1432599756.846411059 30 ctime=1432599756.854411378 signal-1.3.2/src/medfilt1.cc0000644000000000000000000001611412530736314015602 0ustar00rootroot00000000000000/* * Copyright 2000 Paul Kienzle * This source code is freely redistributable and may be used for * any purpose. This copyright notice must be maintained. * Paul Kienzle is not responsible for the consequences of using * this software. * * Mar 2000 - Kai Habel (kahacjde@linux.zrz.tu-berlin.de) * Change: ColumnVector x=arg(i).vector_value(); * to: ColumnVector x=ColumnVector(arg(i).vector_value()); * Oct 2000 - Paul Kienzle (pkienzle@users.sf.net) * rewrite to ignore NaNs rather than replacing them with zero * extend to handle matrix arguments */ #include #include #include #include using namespace std; // The median class holds a sorted data window. This window is // intended to slide over the data, so when the window shifts // by one position, the old value from the start of the window must // be removed and the new value from the end of the window must // be added. Since removals and additions generally occur in pairs, // a hole is left in the sorted window when the value is removed so // that on average, fewer values need to be shifted to close the // hole and open a new one in the sorted position. class Median { private: double *window; // window data int max; // length of window used int hole; // position of hole, or max if no hole void close_hole() // close existing hole { // move hole to the end of the window while (hole < max-1) { window[hole] = window[hole+1]; hole++; } // shorten window (if no hole, then hole==max) if (hole == max-1) max--; } void print(); public: Median(int n) { max=hole=0; window = new double[n]; } ~Median(void) { delete [] window; } void add(double v); // add a new value void remove(double v); // remove an existing value void clear() { max=hole=0; } // clear the window double operator() (); // find the median in the window } ; // Print the sorted window, and indicate any hole void Median::print() { octave_stdout << "[ "; for (int i=0; i < max; i++) { if (i == hole) octave_stdout << "x "; else octave_stdout << window[i] << " "; } octave_stdout << " ]"; } // Remove a value from the sorted window, leaving a hole. The caller // must promise to only remove values that they have added. void Median::remove(double v) { // NaN's are not added or removed if (lo_ieee_isnan(v)) return; // octave_stdout << "Remove " << v << " from "; print(); // only one hole allowed, so close pre-existing ones close_hole(); // binary search to find the value to remove int lo = 0, hi=max-1; hole = hi/2; while (lo <= hi) { if (v > window[hole]) lo = hole+1; else if (v < window[hole]) hi = hole-1; else break; hole = (lo+hi)/2; } // Verify that it is the correct value to replace // Note that we shouldn't need this code since we are always replacing // a value that is already in the window, but for some reason // v==window[hole] occasionally doesn't work. if (v != window[hole]) { for (hole = 0; hole < max-1; hole++) if (fabs(v-window[hole]) < fabs(v-window[hole+1])) break; warning ("medfilt1: value %f not found---removing %f instead", v, window[hole]); print(); octave_stdout << endl; } // octave_stdout << " gives "; print(); octave_stdout << endl; } // Insert a new value in the sorted window, plugging any holes, or // extending the window as necessary. The caller must promise not // to add more values than median was created with, without // removing some beforehand. void Median::add(double v) { // NaN's are not added or removed if (lo_ieee_isnan(v)) return; // octave_stdout << "Add " << v << " to "; print(); // If no holes, extend the array if (hole == max) max++; // shift the hole up to the beginning as far as it can go. while (hole > 0 && window[hole-1] > v) { window[hole] = window[hole-1]; hole--; } // or shift the hole down to the end as far as it can go. while (hole < max-1 && window[hole+1] < v) { window[hole] = window[hole+1]; hole++; } // plug in the replacement value window[hole] = v; // close the hole hole = max; // octave_stdout << " gives "; print(); octave_stdout << endl; } // Compute the median value from the sorted window // Return the central value if there is one or the average of the // two central values. Return NaN if there are no values. double Median::operator()() { close_hole(); if (max % 2 == 1) return window[(max-1)/2]; else if (max == 0) return lo_ieee_nan_value(); else return (window[max/2-1]+window[max/2])/2.0; } DEFUN_DLD (medfilt1, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{y} =} medfilt1 (@var{x})\n\ @deftypefnx {Loadable Function} {@var{y} =} medfilt1 (@var{x}, @var{n})\n\ Apply a median filter of length @var{n} to the signal @var{x}. A sliding\n\ window is applied to the data, and for each step the median value in the\n\ window is returned. If @var{n} is odd then the window for y(i) is\n\ x(i-(n-1)/2:i+(n-1)/2). If @var{n} is even then the window is\n\ x(i-n/2:i+n/2-1) and the two values in the center of the sorted window are\n\ averaged. If @var{n} is not given, then 3 is used. NaNs are ignored,\n\ as are values beyond the ends, by taking the median of the remaining\n\ values.\n\ @end deftypefn") { octave_value_list retval; int nargin = args.length(); if (nargin < 1 || nargin > 3) { print_usage (); return retval; } if (args(0).is_complex_type()) { error("medfilt1 cannot process complex vectors"); return retval; } int n=3; // length of the filter (default 3) if (nargin > 1) n = NINT(args(1).double_value()); if (n < 1) { error ("medfilt1 filter length must be at least 1"); return retval; } // Create a window to hold the sorted median values Median median(n); int mid = n/2; // mid-point of the window Matrix signal(args(0).matrix_value()); int nr = signal.rows(); // number of points to process int nc = signal.columns(); // number of points to process Matrix filter(nr,nc); // filtered signal to return if (nr == 1) // row vector { int start = -n, end = 0, pos=-(n-mid)+1; while (pos < nc) { if (start >= 0) median.remove(signal(0,start)); if (end < nc) median.add(signal(0,end)); if (pos >= 0) filter(0,pos) = median(); start++, end++, pos++; } } else // column vector or matrix { for (int column=0; column < nc; column++) { median.clear(); int start = -n, end = 0, pos=-(n-mid)+1; while (pos < nr) { if (start >= 0) median.remove(signal(start,column)); if (end < nr) median.add(signal(end,column)); if (pos >= 0) filter(pos,column) = median(); start++, end++, pos++; } } } retval(0) = filter; return retval; } /* %!assert(medfilt1([1, 2, 3, 4, 5], 3), [1.5, 2, 3, 4, 4.5]); */ signal-1.3.2/PaxHeaders.4544/inst0000644000000000000000000000013012530736314013351 xustar0028 mtime=1432599756.8424109 30 atime=1432599756.854411378 30 ctime=1432599756.854411378 signal-1.3.2/inst/0000755000000000000000000000000012530736314013751 5ustar00rootroot00000000000000signal-1.3.2/inst/PaxHeaders.4544/downsample.m0000644000000000000000000000013212530736314015757 xustar0030 mtime=1432599756.802409306 30 atime=1432599756.802409306 30 ctime=1432599756.854411378 signal-1.3.2/inst/downsample.m0000644000000000000000000000250412530736314016301 0ustar00rootroot00000000000000## Author: Paul Kienzle (2007) ## This program is granted to the public domain. ## -*- texinfo -*- ## @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}. ## @seealso{decimate, interp, resample, upfirdn, upsample} ## @end deftypefn function y = downsample (x, n, phase = 0) if nargin<2 || nargin>3, print_usage; endif if phase > n - 1 warning("This is incompatible with Matlab (phase = 0:n-1). See octave-forge signal package release notes for details.") endif if isvector(x) y = x(phase + 1:n:end); else y = x(phase + 1:n:end,:); endif endfunction %!assert(downsample([1,2,3,4,5],2),[1,3,5]); %!assert(downsample([1;2;3;4;5],2),[1;3;5]); %!assert(downsample([1,2;3,4;5,6;7,8;9,10],2),[1,2;5,6;9,10]); %!assert(downsample([1,2,3,4,5],2,1),[2,4]); %!assert(downsample([1,2;3,4;5,6;7,8;9,10],2,1),[3,4;7,8]); signal-1.3.2/inst/PaxHeaders.4544/rectwin.m0000644000000000000000000000013212530736314015261 xustar0030 mtime=1432599756.830410422 30 atime=1432599756.830410422 30 ctime=1432599756.854411378 signal-1.3.2/inst/rectwin.m0000644000000000000000000000254612530736314015611 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} rectwin (@var{m}) ## Return the filter coefficients of a rectangular window of length @var{m}. ## @seealso{boxcar, hamming, hanning} ## @end deftypefn function w = rectwin (m) if (nargin != 1) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("rectwin: M must be a positive integer"); endif w = ones (m, 1); endfunction %!assert (rectwin (1), 1) %!assert (rectwin (2), ones (2, 1)) %!assert (rectwin (100), ones (100, 1)) %% Test input validation %!error rectwin () %!error rectwin (0.5) %!error rectwin (-1) %!error rectwin (ones (1, 4)) %!error rectwin (1, 2) signal-1.3.2/inst/PaxHeaders.4544/boxcar.m0000644000000000000000000000013212530736314015064 xustar0030 mtime=1432599756.794408987 30 atime=1432599756.794408987 30 ctime=1432599756.854411378 signal-1.3.2/inst/boxcar.m0000644000000000000000000000245112530736314015407 0ustar00rootroot00000000000000## Copyright (C) 2000 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} boxcar (@var{m}) ## Return the filter coefficients of a rectangular window of length @var{m}. ## @end deftypefn function w = boxcar (m) if (nargin != 1) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("boxcar: M must be a positive integer"); endif w = ones(m, 1); endfunction %!assert (boxcar (1), 1) %!assert (boxcar (2), ones (2, 1)) %!assert (boxcar (100), ones (100, 1)) %% Test input validation %!error boxcar () %!error boxcar (0.5) %!error boxcar (-1) %!error boxcar (ones (1, 4)) %!error boxcar (1, 2) signal-1.3.2/inst/PaxHeaders.4544/gaussian.m0000644000000000000000000000013212530736314015420 xustar0030 mtime=1432599756.810409625 30 atime=1432599756.810409625 30 ctime=1432599756.854411378 signal-1.3.2/inst/gaussian.m0000644000000000000000000000346312530736314015747 0ustar00rootroot00000000000000## Copyright (C) 1999 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function w = gaussian (m, a) if (nargin < 1 || nargin > 2) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("gaussian: M must be a positive integer"); elseif (nargin == 1) a = 1; endif w = exp(-0.5*(([0:m-1]'-(m-1)/2)*a).^2); endfunction %!assert (gaussian (1), 1) %% Test input validation %!error gaussian () %!error gaussian (0.5) %!error gaussian (-1) %!error gaussian (ones (1, 4)) %!error gaussian (1, 2, 3) signal-1.3.2/inst/PaxHeaders.4544/wkeep.m0000644000000000000000000000013212530736314014721 xustar0030 mtime=1432599756.838410741 30 atime=1432599756.838410741 30 ctime=1432599756.854411378 signal-1.3.2/inst/wkeep.m0000644000000000000000000000357112530736314015250 0ustar00rootroot00000000000000## Copyright (C) 2008 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function y = wkeep(x,l,opt = 'c') if (nargin < 2|| nargin > 3); print_usage; endif if(isvector(x)) if(l > length(x)) error('l must be or equal the size of x'); endif if(opt=='c') s = (length(x)-l)./2; y = x(1+floor(s):end-ceil(s)); elseif(opt=='l') y=x(1:l); elseif(opt=='r') y = x(end-l+1:end); else error('opt must be equal to c, l or r'); endif else if(length(l) == 2) s1 = (length(x)-l(1))./2; s2 = (length(x)-l(2))./2; else error('For a matrix l must be a 1x2 vector'); endif if(nargin==2) y = x(1+floor(s1):end-ceil(s1),1+floor(s2):end-ceil(s2)); else if(length(opt) == 2) firstr=opt(1); firstc=opt(2); else error('For a matrix l must be a 1x2 vector'); endif y=x(firstr:firstr+l(1)-1,firstc:firstc+l(2)-1); endif endif endfunction signal-1.3.2/inst/PaxHeaders.4544/parzenwin.m0000644000000000000000000000013212530736314015623 xustar0030 mtime=1432599756.822410103 30 atime=1432599756.822410103 30 ctime=1432599756.854411378 signal-1.3.2/inst/parzenwin.m0000644000000000000000000000307312530736314016147 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} parzenwin (@var{m}) ## Return the filter coefficients of a Parzen window of length @var{m}. ## @seealso{rectwin, bartlett} ## @end deftypefn function w = parzenwin (m) if (nargin != 1) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("parzenwin: M must be a positive integer"); endif N = m - 1; n = -(N/2):N/2; n1 = n(find(abs(n) <= N/4)); n2 = n(find(n > N/4)); n3 = n(find(n < -N/4)); w1 = 1 -6.*(abs(n1)./(m/2)).^2 + 6*(abs(n1)./(m/2)).^3; w2 = 2.*(1-abs(n2)./(m/2)).^3; w3 = 2.*(1-abs(n3)./(m/2)).^3; w = [w3 w1 w2]'; endfunction %!assert (parzenwin (1), 1) %!assert (parzenwin (2), 0.25 * ones (2, 1)) %% Test input validation %!error parzenwin () %!error parzenwin (0.5) %!error parzenwin (-1) %!error parzenwin (ones (1, 4)) %!error parzenwin (1, 2) signal-1.3.2/inst/PaxHeaders.4544/flattopwin.m0000644000000000000000000000013212530736314015775 xustar0030 mtime=1432599756.810409625 30 atime=1432599756.810409625 30 ctime=1432599756.854411378 signal-1.3.2/inst/flattopwin.m0000644000000000000000000000445412530736314016325 0ustar00rootroot00000000000000## Author: Paul Kienzle (2004) ## This program is granted to the public domain. ## -*- texinfo -*- ## @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 function w = flattopwin (m, opt) if (nargin < 1 || nargin > 2) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("flattopwin: M must be a positive integer"); endif N = m - 1; if (nargin == 2) switch (opt) case "periodic" N = m; case "symmetric" N = m - 1; otherwise error ("flattopwin: window type must be either \"periodic\" or \"symmetric\""); endswitch endif if (m == 1) w = 1; else x = 2*pi*[0:m-1]'/N; w = (1-1.93*cos(x)+1.29*cos(2*x)-0.388*cos(3*x)+0.0322*cos(4*x))/4.6402; endif endfunction %!assert (flattopwin (1), 1); %!assert (flattopwin (2), 0.0042 / 4.6402 * ones (2, 1), eps); %!assert (flattopwin (15), flipud (flattopwin (15)), 10*eps); %!assert (flattopwin (16), flipud (flattopwin (16)), 10*eps); %!assert (flattopwin (15), flattopwin (15, "symmetric")); %!assert (flattopwin (16)(1:15), flattopwin (15, "periodic")); %% Test input validation %!error flattopwin () %!error flattopwin (0.5) %!error flattopwin (-1) %!error flattopwin (ones (1, 4)) %!error flattopwin (1, 2) %!error flattopwin (1, 2, 3) %!error flattopwin (1, "invalid") signal-1.3.2/inst/PaxHeaders.4544/pburg.m0000644000000000000000000000013212530736314014725 xustar0030 mtime=1432599756.822410103 30 atime=1432599756.822410103 30 ctime=1432599756.854411378 signal-1.3.2/inst/pburg.m0000644000000000000000000001407012530736314015250 0ustar00rootroot00000000000000## Copyright (C) 2006 Peter V. Lanspeary ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## usage: ## [psd,f_out] = pburg(x,poles,freq,Fs,range,method,plot_type,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. ## x %% [vector] sampled data ## ## poles %% [integer scalar] required number of poles of the AR model ## ## 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] ## ## Fs %% [real scalar] sampling frequency (Hertz) [default=1] ## ## ## 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 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. ## ## 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. ## ## 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 ## ## RETURNED VALUES: ## If return values are not required by the caller, the spectrum ## is plotted and nothing is returned. ## psd %% [real vector] power-spectral density estimate ## f_out %% [real vector] frequency values ## ## HINTS ## This function is a wrapper for arburg and ar_psd. ## See "help arburg", "help ar_psd". function [psd,f_out]=pburg(x,poles,varargin) ## if ( nargin<2 ) error( 'pburg: need at least 2 args. Use "help pburg"' ); endif nvarargin=length(varargin); criterion=[]; ## ## Search for a "criterion" arg. If found, remove it ## from "varargin" list and feed it to arburg instead. for iarg = 1: nvarargin arrgh = varargin{iarg}; if ( ischar(arrgh) && ( strcmp(arrgh,'AKICc') ||... strcmp(arrgh,'KIC') || strcmp(arrgh,'AICc') ||... strcmp(arrgh,'AIC') || strcmp(arrgh,'FPE') ) ) criterion=arrgh; if ( nvarargin>1 ) varargin{iarg}= []; else varargin={}; endif endif endfor ## [ar_coeffs,residual]=arburg(x,poles,criterion); if ( nargout==0 ) ar_psd(ar_coeffs,residual,varargin{:}); elseif ( nargout==1 ) psd = ar_psd(ar_coeffs,residual,varargin{:}); elseif ( nargout>=2 ) [psd,f_out] = ar_psd(ar_coeffs,residual,varargin{:}); endif endfunction %!demo %! rand ("seed", 2038014164); %! a = [1.0 -1.6216505 1.1102795 -0.4621741 0.2075552 -0.018756746]; %! Fs = 25; %! n = 16384; %! signal = detrend (filter (0.70181, a, rand (1, n))); %! % frequency shift by modulating with exp(j.omega.t) %! skewed = signal .* exp (2*pi*i*2/Fs*[1:n]); %! hold on %! pburg (signal, 3, [], Fs); %! pburg (signal, 4, [], Fs, "whole"); %! pburg (signal, 5, 128, Fs, "shift", "semilogy"); %! pburg (skewed, 7, 128, Fs, "AKICc", "shift", "semilogy"); %! user_freq = [-0.2:0.02:0.2]*Fs; %! pburg (skewed, 7, user_freq, Fs, "AKICc", "semilogy"); %! hold off signal-1.3.2/inst/PaxHeaders.4544/idct2.m0000644000000000000000000000013212530736314014613 xustar0030 mtime=1432599756.814409784 30 atime=1432599756.814409784 30 ctime=1432599756.854411378 signal-1.3.2/inst/idct2.m0000644000000000000000000000271512530736314015141 0ustar00rootroot00000000000000## Copyright (C) 2001 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function y = idct2 (x, m, n) if (nargin < 1 || nargin > 3) print_usage; endif if nargin == 1 [m, n] = size (x); elseif (nargin == 2) n = m (2); m = m (1); endif if m == 1 y = idct (x.', n).'; elseif n == 1 y = idct (x, m); else y = idct (idct (x, m).', n).'; endif endfunction signal-1.3.2/inst/PaxHeaders.4544/cheby1.m0000644000000000000000000000013212530736314014761 xustar0030 mtime=1432599756.798409147 30 atime=1432599756.798409147 30 ctime=1432599756.854411378 signal-1.3.2/inst/cheby1.m0000644000000000000000000001167212530736314015311 0ustar00rootroot00000000000000## Copyright (C) 1999 Paul Kienzle ## Copyright (C) 2003 Doug Stewart ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function [a, b, c, d] = cheby1 (n, rp, w, varargin) if (nargin > 5 || nargin < 3 || nargout > 4 || nargout < 2) print_usage (); endif ## interpret the input parameters if (! (isscalar (n) && (n == fix (n)) && (n > 0))) error ("cheby1: filter order N must be a positive integer"); endif stop = false; digital = true; for i = 1:numel (varargin) switch (varargin{i}) case "s" digital = false; case "z" digital = true; case {"high", "stop"} stop = true; case {"low", "pass"} stop = false; otherwise error ("cheby1: expected [high|stop] or [s|z]"); endswitch endfor if (! ((numel (w) <= 2) && (rows (w) == 1 || columns (w) == 1))) error ("cheby1: frequency must be given as WC or [WL, WH]"); elseif ((numel (w) == 2) && (w(2) <= w(1))) error ("cheby1: W(1) must be less than W(2)"); endif if (digital && ! all ((w >= 0) & (w <= 1))) error ("cheby1: all elements of W must be in the range [0,1]"); elseif (! digital && ! all (w >= 0)) error ("cheby1: all elements of W must be in the range [0,inf]"); endif if (! (isscalar (rp) && isnumeric (rp) && (rp >= 0))) error ("cheby1: passband ripple RP must be a non-negative scalar"); endif ## Prewarp to the band edges to s plane if (digital) T = 2; # sampling frequency of 2 Hz w = 2 / T * tan (pi * w / T); endif ## Generate splane poles and zeros for the Chebyshev type 1 filter C = 1; ## default cutoff frequency epsilon = sqrt (10^(rp / 10) - 1); v0 = asinh (1 / epsilon) / n; pole = exp (1i * pi * [-(n - 1):2:(n - 1)] / (2 * n)); pole = -sinh (v0) * real (pole) + 1i * cosh (v0) * imag (pole); zero = []; ## compensate for amplitude at s=0 gain = prod (-pole); ## if n is even, the ripple starts low, but if n is odd the ripple ## starts high. We must adjust the s=0 amplitude to compensate. if (rem (n, 2) == 0) gain = gain / 10^(rp / 20); endif ## splane frequency transform [zero, pole, gain] = sftrans (zero, pole, gain, w, stop); ## Use bilinear transform to convert poles to the z plane if (digital) [zero, pole, gain] = bilinear (zero, pole, gain, T); endif ## convert to the correct output form if (nargout == 2) a = real (gain * poly (zero)); b = real (poly (pole)); elseif (nargout == 3) a = zero; b = pole; c = gain; else ## output ss results [a, b, c, d] = zp2ss (zero, pole, gain); endif endfunction %% Test input validation %!error [a, b] = cheby1 () %!error [a, b] = cheby1 (1) %!error [a, b] = cheby1 (1, 2) %!error [a, b] = cheby1 (1, 2, 3, 4, 5, 6) %!error [a, b] = cheby1 (.5, 2, .2) %!error [a, b] = cheby1 (3, 2, .2, "invalid") signal-1.3.2/inst/PaxHeaders.4544/besself.m0000644000000000000000000000013212530736314015231 xustar0030 mtime=1432599756.790408828 30 atime=1432599756.790408828 30 ctime=1432599756.854411378 signal-1.3.2/inst/besself.m0000644000000000000000000001031012530736314015545 0ustar00rootroot00000000000000## Copyright (C) 1999 Paul Kienzle ## Copyright (C) 2003 Doug Stewart ## Copyright (C) 2009 Thomas Sailer ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function [a, b, c, d] = besself (n, w, varargin) if (nargin > 4 || nargin < 2 || nargout > 4 || nargout < 2) print_usage (); endif ## interpret the input parameters if (! (isscalar (n) && (n == fix (n)) && (n > 0))) error ("besself: filter order N must be a positive integer"); endif stop = false; digital = false; for i = 1:numel (varargin) switch (varargin{i}) case "s" digital = false; case "z" digital = true; case {"high", "stop"} stop = true; case {"low", "pass"} stop = false; otherwise error ("besself: expected [high|stop] or [s|z]"); endswitch endfor ## FIXME: Band-pass and stop-band currently non-functional, remove ## this check once low-pass to band-pass transform is implemented. if (! isscalar (w)) error ("besself: band-pass and stop-band filters not yet implemented"); endif if (! ((numel (w) <= 2) && (rows (w) == 1 || columns (w) == 1))) error ("besself: frequency must be given as WC or [WL, WH]"); elseif ((numel (w) == 2) && (w(2) <= w(1))) error ("besself: W(1) must be less than W(2)"); endif if (digital && ! all ((w >= 0) & (w <= 1))) error ("besself: all elements of W must be in the range [0,1]"); elseif (! digital && ! all (w >= 0)) error ("besself: all elements of W must be in the range [0,inf]"); endif ## Prewarp to the band edges to s plane if (digital) T = 2; # sampling frequency of 2 Hz w = 2 / T * tan (pi * w / T); endif ## Generate splane poles for the prototype Bessel filter [zero, pole, gain] = besselap (n); ## splane frequency transform [zero, pole, gain] = sftrans (zero, pole, gain, w, stop); ## Use bilinear transform to convert poles to the z plane if (digital) [zero, pole, gain] = bilinear (zero, pole, gain, T); endif ## convert to the correct output form if (nargout == 2) a = real (gain * poly (zero)); b = real (poly (pole)); elseif (nargout == 3) a = zero; b = pole; c = gain; else ## output ss results [a, b, c, d] = zp2ss (zero, pole, gain); endif endfunction %% Test input validation %!error [a, b] = besself () %!error [a, b] = besself (1) %!error [a, b] = besself (1, 2, 3, 4, 5) %!error [a, b] = besself (.5, .2) %!error [a, b] = besself (3, .2, "invalid") signal-1.3.2/inst/PaxHeaders.4544/buttap.m0000644000000000000000000000013212530736314015105 xustar0030 mtime=1432599756.794408987 30 atime=1432599756.794408987 30 ctime=1432599756.854411378 signal-1.3.2/inst/buttap.m0000644000000000000000000000235712530736314015435 0ustar00rootroot00000000000000## Copyright (C) 2013 Carnë Draug ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, see . ## -*- texinfo -*- ## @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")}. ## ## @seealso{butter} ## @end deftypefn function [z, p, g] = buttap (n) if (nargin != 1) print_usage(); elseif (! isscalar (n) || ! isnumeric (n) || fix (n) != n || n <= 0) error ("buttap: N must be a positive integer") endif [z, p, g] = butter (n, 1, "s"); endfunction signal-1.3.2/inst/PaxHeaders.4544/zp2tf.m0000644000000000000000000000012612530736314014656 xustar0028 mtime=1432599756.8424109 28 atime=1432599756.8424109 30 ctime=1432599756.854411378 signal-1.3.2/inst/zp2tf.m0000644000000000000000000000267512530736314015206 0ustar00rootroot00000000000000## Copyright (C) 1996, 1998, 2000, 2002, 2004, 2005, 2007 Auburn University ## Copyright (C) 2012 Lukas F. Reichlin ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## Author: A. S. Hodel ## (With help from students Ingram, McGowan.) function [num, den] = zp2tf (varargin) if (nargin == 0) print_usage (); endif [num, den] = tfdata (zpk (varargin{:}), "vector"); endfunction signal-1.3.2/inst/PaxHeaders.4544/kaiserord.m0000644000000000000000000000013212530736314015571 xustar0030 mtime=1432599756.818409944 30 atime=1432599756.818409944 30 ctime=1432599756.854411378 signal-1.3.2/inst/kaiserord.m0000644000000000000000000001335612530736314016122 0ustar00rootroot00000000000000## Copyright (C) 2000 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## @seealso{fir1, kaiser} ## @end deftypefn ## FIXME: order is underestimated for the final test case: 2 stop bands. function [n, w, beta, ftype] = kaiserord(f, m, dev, fs) if (nargin<2 || nargin>4) print_usage; endif ## default sampling rate parameter if nargin<4, fs=2; endif ## parameter checking if length(f)!=2*length(m)-2 error("kaiserord must have one magnitude for each frequency band"); endif if any(m(1:length(m)-2)!=m(3:length(m))) error("kaiserord pass and stop bands must be strictly alternating"); endif if length(dev)!=length(m) && length(dev)!=1 error("kaiserord must have one deviation for each frequency band"); endif dev = min(dev); if dev <= 0, error("kaiserord must have dev>0"); endif ## use midpoints of the transition region for band edges w = (f(1:2:length(f))+f(2:2:length(f)))/fs; ## determine ftype if length(w) == 1 if m(1)>m(2), ftype='low'; else ftype='high'; endif elseif length(w) == 2 if m(1)>m(2), ftype='stop'; else ftype='pass'; endif else if m(1)>m(2), ftype='DC-1'; else ftype='DC-0'; endif endif ## compute beta from dev A = -20*log10(dev); if (A > 50) beta = 0.1102*(A-8.7); elseif (A >= 21) beta = 0.5842*(A-21)^0.4 + 0.07886*(A-21); else beta = 0.0; endif ## compute n from beta and dev dw = 2*pi*min(f(2:2:length(f))-f(1:2:length(f)))/fs; n = max(1,ceil((A-8)/(2.285*dw))); ## if last band is high, make sure the order of the filter is even. if ((m(1)>m(2)) == (rem(length(w),2)==0)) && rem(n,2)==1, n = n+1; endif endfunction %!demo %! Fs = 11025; %! for i=1:4 %! if i==1, %! subplot(221); bands=[1200, 1500]; mag=[1, 0]; dev=[0.1, 0.1]; %! elseif i==2 %! subplot(222); bands=[1000, 1500]; mag=[0, 1]; dev=[0.1, 0.1]; %! elseif i==3 %! subplot(223); bands=[1000, 1200, 3000, 3500]; mag=[0, 1, 0]; dev=0.1; %! elseif i==4 %! subplot(224); bands=100*[10, 13, 15, 20, 30, 33, 35, 40]; %! mag=[1, 0, 1, 0, 1]; dev=0.05; %! endif %! [n, w, beta, ftype] = kaiserord(bands, mag, dev, Fs); %! d=max(1,fix(n/10)); %! if mag(length(mag))==1 && rem(d,2)==1, d=d+1; endif %! [h, f] = freqz(fir1(n,w,ftype,kaiser(n+1,beta),'noscale'),1,[],Fs); %! hm = freqz(fir1(n-d,w,ftype,kaiser(n-d+1,beta),'noscale'),1,[],Fs); %! plot(f,abs(hm),sprintf("r;order %d;",n-d), ... %! f,abs(h), sprintf("b;order %d;",n)); %! b = [0, bands, Fs/2]; hold on; %! for i=2:2:length(b), %! hi=mag(i/2)+dev(1); lo=max(mag(i/2)-dev(1),0); %! plot([b(i-1), b(i), b(i), b(i-1), b(i-1)],[hi, hi, lo, lo, hi],"c;;"); %! endfor; hold off; %! endfor %! %! %-------------------------------------------------------------- %! % A filter meets the specifications if its frequency response %! % passes through the ends of the criteria boxes, and fails if %! % it passes through the top or the bottom. The criteria are %! % met precisely if the frequency response only passes through %! % the corners of the boxes. The blue line is the filter order %! % returned by kaiserord, and the red line is some lower filter %! % order. Confirm that the blue filter meets the criteria and %! % the red line fails. ## FIXME: extend demo to show detail at criteria box corners signal-1.3.2/inst/PaxHeaders.4544/iirlp2mb.m0000644000000000000000000000013212530736314015326 xustar0030 mtime=1432599756.814409784 30 atime=1432599756.814409784 30 ctime=1432599756.854411378 signal-1.3.2/inst/iirlp2mb.m0000644000000000000000000002751212530736314015656 0ustar00rootroot00000000000000## Copyright (C) 2011 Alan J. Greenberger ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## IIR Low Pass Filter to Multiband Filter Transformation ## ## [Num,Den,AllpassNum,AllpassDen] = iirlp2mb(B,A,Wo,Wt) ## [Num,Den,AllpassNum,AllpassDen] = iirlp2mb(B,A,Wo,Wt,Pass) ## ## Num,Den: numerator,denominator of the transformed filter ## AllpassNum,AllpassDen: numerator,denominator of allpass transform, ## B,A: numerator,denominator of prototype low pass filter ## Wo: normalized_angular_frequency/pi to be transformed ## Wt: [phi=normalized_angular_frequencies]/pi target vector ## Pass: This parameter may have values 'pass' or 'stop'. If ## not given, it defaults to the value of 'pass'. ## ## With normalized ang. freq. targets 0 < phi(1) < ... < phi(n) < pi radians ## ## for Pass == 'pass', the target multiband magnitude will be: ## -------- ---------- -----------... ## / \ / \ / . ## 0 phi(1) phi(2) phi(3) phi(4) phi(5) (phi(6)) pi ## ## for Pass == 'stop', the target multiband magnitude will be: ## ------- --------- ----------... ## \ / \ / . ## 0 phi(1) phi(2) phi(3) phi(4) (phi(5)) pi ## ## Example of use: ## [B, A] = butter(6, 0.5); ## [Num, Den] = iirlp2mb(B, A, 0.5, [.2 .4 .6 .8]); function [Num,Den,AllpassNum,AllpassDen] = iirlp2mb(varargin) usage = sprintf( "%s: Usage: [Num,Den,AllpassNum,AllpassDen]=iirlp2mb(B,A,Wo,Wt[,Pass])\n" ,mfilename()); B = varargin{1}; # numerator polynomial of prototype low pass filter A = varargin{2}; # denominator polynomial of prototype low pass filter Wo = varargin{3}; # (normalized angular frequency)/pi to be transformed Wt = varargin{4}; # vector of (norm. angular frequency)/pi transform targets # [phi(1) phi(2) ... ]/pi if(nargin < 4 || nargin > 5) error("%s",usage) endif if(nargin == 5) Pass = varargin{5}; switch(Pass) case 'pass' pass_stop = -1; case 'stop' pass_stop = 1; otherwise error("Pass must be 'pass' or 'stop'\n%s",usage) endswitch else pass_stop = -1; # Pass == 'pass' is the default endif if(Wo <= 0) error("Wo is %f <= 0\n%s",Wo,usage); endif if(Wo >= 1) error("Wo is %f >= 1\n%s",Wo,usage); endif oWt = 0; for i = 1 : length(Wt) if(Wt(i) <= 0) error("Wt(%d) is %f <= 0\n%s",i,Wt(i),usage); endif if(Wt(i) >= 1) error("Wt(%d) is %f >= 1\n%s",i,Wt(i),usage); endif if(Wt(i) <= oWt) error("Wt(%d) = %f, not monotonically increasing\n%s",i,Wt(i),usage); else oWt = Wt(i); endif endfor ## B(z) ## Inputs B,A specify the low pass IIR prototype filter G(z) = ---- . ## A(z) ## This module transforms G(z) into a multiband filter using the iterative ## algorithm from: ## [FFM] G. Feyh, J. Franchitti, and C. Mullis, "All-Pass Filter ## Interpolation and Frequency Transformation Problem", Proceedings 20th ## Asilomar Conference on Signals, Systems and Computers, Nov. 1986, pp. ## 164-168, IEEE. ## [FFM] moves the prototype filter position at normalized angular frequency ## .5*pi to the places specified in the Wt vector times pi. In this module, ## a generalization allows the position to be moved on the prototype filter ## to be specified as Wo*pi instead of being fixed at .5*pi. This is ## implemented using two successive allpass transformations. ## KK(z) ## In the first stage, find allpass J(z) = ---- such that ## K(z) ## jWo*pi -j.5*pi ## J(e ) = e (low pass to low pass transformation) ## ## PP(z) ## In the second stage, find allpass H(z) = ---- such that ## P(z) ## jWt(k)*pi -j(2k - 1)*.5*pi ## H(e ) = e (low pass to multiband transformation) ## ## ^ ## The variable PP used here corresponds to P in [FFM]. ## len = length(P(z)) == length(PP(z)), the number of polynomial coefficients ## ## len 1-i len 1-i ## P(z) = SUM P(i)z ; PP(z) = SUM PP(i)z ; PP(i) == P(len + 1 - i) ## i=1 i=1 (allpass condition) ## Note: (len - 1) == n in [FFM] eq. 3 ## ## The first stage computes the denominator of an allpass for translating ## from a prototype with position .5 to one with a position of Wo. It has the ## form: ## -1 ## K(2) - z ## ----------- ## -1 ## 1 - K(2)z ## ## From the low pass to low pass transformation in Table 7.1 p. 529 of A. ## Oppenheim and R. Schafer, Discrete-Time Signal Processing 3rd edition, ## Prentice Hall 2010, one can see that the denominator of an allpass for ## going in the opposite direction can be obtained by a sign reversal of the ## second coefficient, K(2), of the vector K (the index 2 not to be confused ## with a value of z, which is implicit). ## The first stage allpass denominator computation K = apd([pi * Wo]); ## The second stage allpass computation phi = pi * Wt; # vector of normalized angular frequencies between 0 and pi P = apd(phi); # calculate denominator of allpass for this target vector PP = revco(P); # numerator of allpass has reversed coefficients of P ## The total allpass filter from the two consecutive stages can be written as ## PP ## K(2) - --- ## P P ## ----------- * --- ## PP P ## 1 - K(2)--- ## P AllpassDen = P - (K(2) * PP); AllpassDen /= AllpassDen(1); # normalize AllpassNum = pass_stop * revco(AllpassDen); [Num,Den] = transform(B,A,AllpassNum,AllpassDen,pass_stop); endfunction function [Num,Den] = transform(B,A,PP,P,pass_stop) ## Given G(Z) = B(Z)/A(Z) and allpass H(z) = PP(z)/P(z), compute G(H(z)) ## For Pass = 'pass', transformed filter is: ## 2 nb-1 ## B1 + B2(PP/P) + B3(PP/P)^ + ... + Bnb(PP/P)^ ## ------------------------------------------------- ## 2 na-1 ## A1 + A2(PP/P) + A3(PP/P)^ + ... + Ana(PP/P)^ ## For Pass = 'stop', use powers of (-PP/P) ## na = length(A); # the number of coefficients in A nb = length(B); # the number of coefficients in B ## common low pass iir filters have na == nb but in general might not n = max(na,nb); # the greater of the number of coefficients ## n-1 ## Multiply top and bottom by P^ yields: ## ## n-1 n-2 2 n-3 nb-1 n-nb ## B1(P^ ) + B2(PP)(P^ ) + B3(PP^ )(P^ ) + ... + Bnb(PP^ )(P^ ) ## --------------------------------------------------------------------- ## n-1 n-2 2 n-3 na-1 n-na ## A1(P^ ) + A2(PP)(P^ ) + A3(PP^ )(P^ ) + ... + Ana(PP^ )(P^ ) ## Compute and store powers of P as a matrix of coefficients because we will ## need to use them in descending power order global Ppower; # to hold coefficients of powers of P, access inside ppower() np = length(P); powcols = np + (np-1)*(n-2); # number of coefficients in P^(n-1) ## initialize to "Not Available" with n-1 rows for powers 1 to (n-1) and ## the number of columns needed to hold coefficients for P^(n-1) Ppower = NA(n-1,powcols); Ptemp = P; # start with P to the 1st power for i = 1 : n-1 # i is the power for j = 1 : length(Ptemp) # j is the coefficient index for this power Ppower(i,j) = Ptemp(j); endfor Ptemp = conv(Ptemp,P); # increase power of P by one endfor ## Compute numerator and denominator of transformed filter Num = []; Den = []; for i = 1 : n ## n-i ## Regenerate P^ (p_pownmi) if((n-i) == 0) p_pownmi = [1]; else p_pownmi = ppower(n-i,powcols); endif ## i-1 ## Regenerate PP^ (pp_powim1) if(i == 1) pp_powim1 = [1]; else pp_powim1 = revco(ppower(i-1,powcols)); endif if(i <= nb) Bterm = (pass_stop^(i-1))*B(i)*conv(pp_powim1,p_pownmi); Num = polysum(Num,Bterm); endif if(i <= na) Aterm = (pass_stop^(i-1))*A(i)*conv(pp_powim1,p_pownmi); Den = polysum(Den,Aterm); endif endfor ## Scale both numerator and denominator to have Den(1) = 1 temp = Den(1); for i = 1 : length(Den) Den(i) = Den(i) / temp; endfor for i = 1 : length(Num) Num(i) = Num(i) / temp; endfor endfunction function P = apd(phi) # all pass denominator ## Given phi, a vector of normalized angular frequency transformation targets, ## return P, the denominator of an allpass H(z) lenphi = length(phi); Pkm1 = 1; # P0 initial condition from [FFM] eq. 22 for k = 1 : lenphi P = pk(Pkm1, k, phi(k)); # iterate Pkm1 = P; endfor endfunction function Pk = pk(Pkm1, k, phik) # kth iteration of P(z) ## Given Pkminus1, k, and phi(k) in radians , return Pk ## ## From [FFM] eq. 19 : k ## Pk = (z+1 )sin(phi(k)/2)Pkm1 - (-1) (z-1 )cos(phi(k)/2)PPkm1 ## Factoring out z ## -1 k -1 ## = z((1+z )sin(phi(k)/2)Pkm1 - (-1) (1-z )cos(phi(k)/2)PPkm1) ## PPk can also have z factored out. In H=PP/P, z in PPk will cancel z in Pk, ## so just leave out. Use ## -1 k -1 ## PK = (1+z )sin(phi(k)/2)Pkm1 - (-1) (1-z )cos(phi(k)/2)PPkm1 ## (expand) k ## = sin(phi(k)/2)Pkm1 - (-1) cos(phi(k)/2)PPkm1 ## ## -1 k -1 ## + z sin(phi(k)/2)Pkm1 + (-1) z cos(phi(k)/2)PPkm1 Pk = zeros(1,k+1); # there are k+1 coefficients in Pk sin_k = sin(phik/2); cos_k = cos(phik/2); for i = 1 : k Pk(i) += sin_k * Pkm1(i) - ((-1)^k * cos_k * Pkm1(k+1-i)); ## ## -1 ## Multiplication by z just shifts by one coefficient Pk(i+1) += sin_k * Pkm1(i) + ((-1)^k * cos_k * Pkm1(k+1-i)); endfor ## now normalize to Pk(1) = 1 (again will cancel with same factor in PPk) Pk1 = Pk(1); for i = 1 : k+1 Pk(i) = Pk(i) / Pk1; endfor endfunction function PP = revco(p) # reverse components of vector l = length(p); for i = 1 : l PP(l + 1 - i) = p(i); endfor endfunction function p = ppower(i,powcols) # Regenerate ith power of P from stored PPower global Ppower if(i == 0) p = 1; else p = []; for j = 1 : powcols if(isna(Ppower(i,j))) break; endif p = horzcat(p, Ppower(i,j)); endfor endif endfunction function poly = polysum(p1,p2) # add polynomials of possibly different length n1 = length(p1); n2 = length(p2); if(n1 > n2) ## pad p2 p2 = horzcat(p2, zeros(1,n1-n2)); elseif(n2 > n1) ## pad p1 p1 = horzcat(p1, zeros(1,n2-n1)); endif poly = p1 + p2; endfunction signal-1.3.2/inst/PaxHeaders.4544/triang.m0000644000000000000000000000013212530736314015072 xustar0030 mtime=1432599756.838410741 30 atime=1432599756.838410741 30 ctime=1432599756.854411378 signal-1.3.2/inst/triang.m0000644000000000000000000000467112530736314015423 0ustar00rootroot00000000000000## Copyright (C) 2000-2002 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## @seealso{bartlett} ## @end deftypefn function w = triang (m) if (nargin != 1) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("triang: M must be a positive integer"); endif w = 1 - abs ([-(m-1):2:(m-1)]' / (m+rem(m,2))); endfunction %!assert (triang (1), 1) %!assert (triang (2), [1; 1]/2) %!assert (triang (3), [1; 2; 1]/2) %!assert (triang (4), [1; 3; 3; 1]/4) %!test %! x = bartlett (5); %! assert (triang (3), x(2:4)); %% Test input validation %!error triang () %!error triang (0.5) %!error triang (-1) %!error triang (ones (1, 4)) %!error triang (1, 2) %!demo %! subplot(221); %! n=7; k=(n-1)/2; t=[-k:0.1:k]/(k+1); %! plot(t,1-abs(t),";continuous;",[-k:k]/(k+1),triang(n),"g*;discrete;"); %! axis([-1, 1, 0, 1.3]); grid("on"); %! title("comparison with continuous for odd n"); %! %! subplot(222); %! n=8; k=(n-1)/2; t=[-k:0.1:k]/(k+1/2); %! plot(t,1+1/n-abs(t),";continuous;",[-k:k]/(k+1/2),triang(n),"g*;discrete;"); %! axis([-1, 1, 0, 1.3]); grid("on"); %! title("note the higher peak for even n"); %! %! subplot(223); %! n=7; %! plot(0:n+1,bartlett(n+2),"g-*;bartlett;",triang(n),"r-+;triang;"); %! axis; grid("off"); %! title("n odd, triang(n)==bartlett(n+2)"); %! %! subplot(224); %! n=8; %! plot(0:n+1,bartlett(n+2),"g-*;bartlett;",triang(n),"r-+;triang;"); %! axis; grid("off"); %! title("n even, triang(n)!=bartlett(n+2)"); signal-1.3.2/inst/PaxHeaders.4544/data2fun.m0000644000000000000000000000013212530736314015312 xustar0030 mtime=1432599756.802409306 30 atime=1432599756.802409306 30 ctime=1432599756.854411378 signal-1.3.2/inst/data2fun.m0000644000000000000000000001115212530736314015633 0ustar00rootroot00000000000000## Copyright (c) 2011 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{fhandle}, @var{fullname}] =} data2fun (@var{ti}, @var{yi}) ## @deftypefnx {Function File} {[@dots{}] =} data2fun (@var{ti}, @var{yi},@var{property},@var{value}) ## Creates 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 property-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{tmpnam} and the file is created in the current directory. @var{value} ## must not have an extension, since .m will be appended. ## Numerical value 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 ## ## @seealso{interp1} ## @end deftypefn function [fhandle fullfname] = data2fun( t, y, varargin) ## Check input arguments interp_args = {"spline"}; given = struct("file",false); if ~isempty(varargin) ## Arguments interp_args = varargin; opt_args = fieldnames (given); [tf idx] = ismember( opt_args, varargin); for i=1:numel(opt_args) given.(opt_args{i}) = tf(i); endfor if given.file ## FIXME: check that file will be in the path. Otherwise fhabdle(0) fails. if !isempty(varargin{idx(1)+1}) [DIR fname] = fileparts(varargin{idx(1)+1}); else [DIR fname] = fileparts (tmpnam (pwd (),"agen_")); endif interp_args(idx(1)+[0 1]) = []; endif if isempty(interp_args) interp_args = {"spline"}; endif endif pp = interp1 (t, y, interp_args{end}, 'pp'); if given.file fullfname = fullfile (DIR,[fname ".m"]); save("-binary",[fullfname(1:end-2) ".mat"],"pp"); bodystr = [" persistent pp\n" ... " if isempty(pp)\n" ... " pp = load([mfilename()" ' ".mat"' "]).pp;\n"... " end\n\n" ... " z = ppval(pp, x);"]; strfunc = generate_function_str(fname, {"z"}, {"x"}, bodystr); fid = fopen ( fullfile (DIR,[fname ".m"]), "w"); fprintf (fid, "%s", strfunc); fclose (fid); disp(["Function generated: " fullfname ]); fhandle = eval(["@" fname]); else fullfname = ""; fhandle = @(t_) ppval (pp, t_); endif endfunction function str = generate_function_str(name, oargs, iargs, bodystr) striargs = cell2mat ( cellfun (@(x) [x ", "], iargs, "UniformOutput", false)); striargs = striargs(1:end-2); stroargs = cell2mat ( cellfun (@(x) [x ", "], oargs, "UniformOutput", false)); stroargs = stroargs(1:end-2); if !isempty (stroargs) str = ["function [" stroargs "] = " name "(" striargs ")\n\n" bodystr ... "\n\nendfunction"]; else str = ["function " name "(" striargs ")\n\n" bodystr ... "\n\nendfunction"]; endif endfunction %!shared t, y %! t = linspace(0,1,10); %! y = t.^2 - 2*t + 1; %!test %! fhandle = data2fun(t,y); %! assert(y,fhandle(t)); %!test %! [fhandle fname] = data2fun(t,y,"file","testdata2fun"); %! yt = testdata2fun(t); %! %! assert(y,yt); %! assert(y,fhandle(t)); %! %! delete(fname); %! delete([fname(1:end-2) ".mat"]); %!test %! [fhandle fname] = data2fun(t,y,"file",""); %! yt = testdata2fun(t); %! %! assert(y,yt); %! assert(y,fhandle(t)); %! %! delete(fname); %! delete([fname(1:end-2) ".mat"]); %!test %! [fhandle fname] = data2fun(t,y,"file","testdata2fun","interp","linear"); %! yt = testdata2fun(t); %! %! assert(y,yt); %! assert(y,fhandle(t)); %! %! delete(fname); %! delete([fname(1:end-2) ".mat"]); signal-1.3.2/inst/PaxHeaders.4544/convmtx.m0000644000000000000000000000013212530736314015304 xustar0030 mtime=1432599756.798409147 30 atime=1432599756.798409147 30 ctime=1432599756.854411378 signal-1.3.2/inst/convmtx.m0000644000000000000000000000342412530736314015630 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## @seealso{conv} function b = convmtx (a, n) if (nargin != 2) print_usage; endif [r, c] = size(a); if ((r != 1) && (c != 1)) || (r*c == 0) error("convmtx: expecting vector argument"); endif b = toeplitz([a(:); zeros(n-1,1)],[a(1); zeros(n-1,1)]); if (c > r) b = b.'; endif endfunction %!assert(convmtx([3,4,5],3),[3,4,5,0,0;0,3,4,5,0;0,0,3,4,5]) %!assert(convmtx([3;4;5],3),[3,0,0;4,3,0;5,4,3;0,5,4;0,0,5]) signal-1.3.2/inst/PaxHeaders.4544/tf2ss.m0000644000000000000000000000013212530736314014647 xustar0030 mtime=1432599756.834410581 30 atime=1432599756.834410581 30 ctime=1432599756.854411378 signal-1.3.2/inst/tf2ss.m0000644000000000000000000000351312530736314015172 0ustar00rootroot00000000000000## Copyright (C) 1994-1996, 1998, 2000, 2002, 2004, 2005, 2007 Auburn University ## Copyright (C) 2012 Lukas F. Reichlin ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## Author: R. Bruce Tenison function [a, b, c, d, e] = tf2ss (varargin) if (nargin == 0) print_usage (); endif [a, b, c, d, e] = dssdata (tf (varargin{:}), []); endfunction signal-1.3.2/inst/PaxHeaders.4544/chebwin.m0000644000000000000000000000013212530736314015225 xustar0030 mtime=1432599756.798409147 30 atime=1432599756.798409147 30 ctime=1432599756.854411378 signal-1.3.2/inst/chebwin.m0000644000000000000000000000635112530736314015553 0ustar00rootroot00000000000000## Copyright (C) 2002 André Carezia ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## ## @seealso{kaiser} ## @end deftypefn function w = chebwin (m, at) if (nargin < 1 || nargin > 2) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("chebwin: M must be a positive integer"); elseif (nargin == 1) at = 100; elseif (! (isscalar (at) && isreal (at))) error ("chebwin: AT must be a real scalar"); endif if (m == 1) w = 1; else ## beta calculation gamma = 10^(-at/20); beta = cosh(1/(m-1) * acosh(1/gamma)); ## freq. scale k = (0:m-1); x = beta*cos(pi*k/m); ## Chebyshev window (freq. domain) p = cheb(m-1, x); ## inverse Fourier transform if (rem(m,2)) w = real(fft(p)); M = (m+1)/2; w = w(1:M)/w(1); w = [w(M:-1:2) w]'; else ## half-sample delay (even order) p = p.*exp(j*pi/m * (0:m-1)); w = real(fft(p)); M = m/2+1; w = w/w(2); w = [w(M:-1:2) w(2:M)]'; endif endif w = w ./ max (w (:)); endfunction %!assert (chebwin (1), 1) %!assert (chebwin (2), ones (2, 1)) %% Test input validation %!error chebwin () %!error chebwin (0.5) %!error chebwin (-1) %!error chebwin (ones (1, 4)) %!error chebwin (1, 2, 3) signal-1.3.2/inst/PaxHeaders.4544/mexihat.m0000644000000000000000000000013212530736314015245 xustar0030 mtime=1432599756.818409944 30 atime=1432599756.818409944 30 ctime=1432599756.854411378 signal-1.3.2/inst/mexihat.m0000644000000000000000000000214212530736314015565 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{psi}, @var{x}] =} mexihat (@var{lb}, @var{ub}, @var{n}) ## Compute the Mexican hat wavelet. ## @end deftypefn function [psi,x] = mexihat(lb,ub,n) if (nargin < 3); print_usage; endif if (n <= 0) error("n must be strictly positive"); endif x = linspace(lb,ub,n); psi = (1-x.^2).*(2/(sqrt(3)*pi^0.25)) .* exp(-x.^2/2) ; endfunction signal-1.3.2/inst/PaxHeaders.4544/sampled2continuous.m0000644000000000000000000000013212530736314017444 xustar0030 mtime=1432599756.830410422 30 atime=1432599756.830410422 30 ctime=1432599756.854411378 signal-1.3.2/inst/sampled2continuous.m0000644000000000000000000000266012530736314017771 0ustar00rootroot00000000000000## Copyright (C) 2009 Muthiah Annamalai ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function xt = sampled2continuous( xn , T, t ) if ( nargin < 3 ) print_usage() endif N = length( xn ); xn = reshape( xn, N, 1 ); [TT,tt]= meshgrid(T*(0:N-1)',t); S = sinc((tt -TT)./T); xt = S*xn; return endfunction signal-1.3.2/inst/PaxHeaders.4544/dst.m0000644000000000000000000000013212530736314014400 xustar0030 mtime=1432599756.806409466 30 atime=1432599756.806409466 30 ctime=1432599756.854411378 signal-1.3.2/inst/dst.m0000644000000000000000000000266412530736314014731 0ustar00rootroot00000000000000## Author: Paul Kienzle (2006) ## This program is granted to the public domain. ## -*- texinfo -*- ## @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 ## ## @seealso{idst} ## @end deftypefn function y = dst (x, n) if (nargin < 1 || nargin > 2) print_usage; endif transpose = (rows (x) == 1); if transpose, x = x (:); endif [nr, nc] = size (x); if nargin == 1 n = nr; elseif n > nr x = [ x ; zeros(n-nr,nc) ]; elseif n < nr x (nr-n+1 : n, :) = []; endif y = fft ([ zeros(1,nc); x ; zeros(1,nc); -flipud(x) ])/-2j; y = y(2:nr+1,:); if isreal(x), y = real (y); endif ## Compare directly against the slow transform ## y2 = x; ## w = pi*[1:n]'/(n+1); ## for k = 1:n, y2(k) = sum(x(:).*sin(k*w)); endfor ## y = [y,y2]; if transpose, y = y.'; endif endfunction %!test %! x = log(linspace(0.1,1,32)); %! y = dst(x); %! assert(y(3), sum(x.*sin(3*pi*[1:32]/33)), 100*eps) signal-1.3.2/inst/PaxHeaders.4544/polystab.m0000644000000000000000000000013212530736314015443 xustar0030 mtime=1432599756.822410103 30 atime=1432599756.822410103 30 ctime=1432599756.854411378 signal-1.3.2/inst/polystab.m0000644000000000000000000000201112530736314015756 0ustar00rootroot00000000000000## Copyright (C) 2001 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## b = polystab(a) ## ## Stabilize the polynomial transfer function by replacing all roots ## outside the unit circle with their reflection inside the unit circle. function b = polystab(a) r = roots(a); v = find(abs(r)>1); r(v) = 1./conj(r(v)); b = a(1) * poly ( r ); if isreal(a), b = real(b); endif endfunction signal-1.3.2/inst/PaxHeaders.4544/barthannwin.m0000644000000000000000000000013212530736314016121 xustar0030 mtime=1432599756.790408828 30 atime=1432599756.790408828 30 ctime=1432599756.854411378 signal-1.3.2/inst/barthannwin.m0000644000000000000000000000276412530736314016453 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} barthannwin (@var{m}) ## Return the filter coefficients of a modified Bartlett-Hann window of length ## @var{m}. ## @seealso{rectwin, bartlett} ## @end deftypefn function w = barthannwin (m) if (nargin != 1) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("barthannwin: M must be a positive integer"); endif if (m == 1) w = 1; else N = m - 1; n = 0:N; w = 0.62 -0.48.*abs(n./(m-1) - 0.5)+0.38*cos(2.*pi*(n./(m-1)-0.5)); w = w'; endif endfunction %!assert (barthannwin (1), 1) %!assert (barthannwin (2), zeros (2, 1)) %% Test input validation %!error barthannwin () %!error barthannwin (0.5) %!error barthannwin (-1) %!error barthannwin (ones (1, 4)) %!error barthannwin (1, 2) signal-1.3.2/inst/PaxHeaders.4544/invfreqz.m0000644000000000000000000000013212530736314015452 xustar0030 mtime=1432599756.818409944 30 atime=1432599756.818409944 30 ctime=1432599756.854411378 signal-1.3.2/inst/invfreqz.m0000644000000000000000000000604412530736314015777 0ustar00rootroot00000000000000## Copyright (C) 1986,2003 Julius O. Smith III ## Copyright (C) 2003 Andrew Fitting ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## usage: [B,A] = invfreqz(H,F,nB,nA) ## [B,A] = invfreqz(H,F,nB,nA,W) ## [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: ## [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))); ## FIXME: check invfreq.m for todo's function [B, A, SigN] = invfreqz(H, F, nB, nA, W, iter, tol, tr, varargin) if nargin < 9 varargin = {}; if nargin < 8 tr = ''; if nargin < 7 tol = []; if nargin < 6 iter = []; if nargin < 5 W = ones(1,length(F)); endif endif endif endif endif ## now for the real work [B, A, SigN] = invfreq(H, F, nB, nA, W, iter, tol, tr, 'z', varargin{:}); endfunction %!demo %! order = 9; # order of test filter %! # going to 10 or above leads to numerical instabilities and large errors %! fc = 1/2; # sampling rate / 4 %! n = 128; # frequency grid size %! [B0, A0] = butter(order, fc); %! [H0, w] = freqz(B0, A0, n); %! Nn = (randn(size(w))+j*randn(size(w)))/sqrt(2); %! [Bh, Ah, Sig0] = invfreqz(H0, w, order, order); %! [Hh, wh] = freqz(Bh, Ah, n); %! [BLS, ALS, SigLS] = invfreqz(H0+1e-5*Nn, w, order, order, [], [], [], [], "method", "LS"); %! HLS = freqz(BLS, ALS, n); %! [BTLS, ATLS, SigTLS] = invfreqz(H0+1e-5*Nn, w, order, order, [], [], [], [], "method", "TLS"); %! HTLS = freqz(BTLS, ATLS, n); %! [BMLS, AMLS, SigMLS] = invfreqz(H0+1e-5*Nn, w, order, order, [], [], [], [], "method", "QR"); %! HMLS = freqz(BMLS, AMLS, n); %! plot(w,[abs(H0) abs(Hh)]) %! xlabel("Frequency (rad/sample)"); %! ylabel("Magnitude"); %! legend('Original','Measured'); %! err = norm(H0-Hh); %! disp(sprintf('L2 norm of frequency response error = %f',err)); signal-1.3.2/inst/PaxHeaders.4544/zp2ss.m0000644000000000000000000000012612530736314014672 xustar0028 mtime=1432599756.8424109 28 atime=1432599756.8424109 30 ctime=1432599756.854411378 signal-1.3.2/inst/zp2ss.m0000644000000000000000000000347412530736314015220 0ustar00rootroot00000000000000## Copyright (C) 1994, 1996, 2000, 2002, 2003, 2004, 2005, 2007 Auburn University ## Copyright (C) 2012 Lukas F. Reichlin ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## Author: David Clem function [a, b, c, d, e] = zp2ss (varargin) if (nargin == 0) print_usage (); endif [a, b, c, d, e] = dssdata (zpk (varargin{:}), []); endfunction signal-1.3.2/inst/PaxHeaders.4544/fracshift.m0000644000000000000000000000013212530736314015557 xustar0030 mtime=1432599756.810409625 30 atime=1432599756.810409625 30 ctime=1432599756.854411378 signal-1.3.2/inst/fracshift.m0000644000000000000000000001073612530736314016107 0ustar00rootroot00000000000000## Copyright (C) 2008 Eric Chassande-Mottin, CNRS (France) ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## @seealso{circshift} ## @end deftypefn ## Ref [1] A. V. Oppenheim, R. W. Schafer and J. R. Buck, ## Discrete-time signal processing, Signal processing series, ## Prentice-Hall, 1999 ## ## Ref [2] T.I. Laakso, V. Valimaki, M. Karjalainen and U.K. Laine ## Splitting the unit delay, IEEE Signal Processing Magazine, ## vol. 13, no. 1, pp 30--59 Jan 1996 function [y, h] = fracshift( x, d, h ) if nargchk(2,3,nargin) print_usage; endif; ## if the delay is an exact integer, use circshift if d==fix(d) y=circshift(x,d); return endif; ## filter design if required if (nargin < 4) ## properties of the interpolation filter log10_rejection = -3.0; stopband_cutoff_f = 1.0 / 2.0; roll_off_width = stopband_cutoff_f / 10; ## determine filter length ## use empirical formula from [1] Chap 7, Eq. (7.63) p 476 rejection_dB = -20.0*log10_rejection; L = ceil((rejection_dB-8.0) / (28.714 * roll_off_width)); ## ideal sinc filter t=(-L:L)'; ideal_filter=2*stopband_cutoff_f*sinc(2*stopband_cutoff_f*(t-(d-fix(d)))); ## determine parameter of Kaiser window ## use empirical formula from [1] Chap 7, Eq. (7.62) p 474 if ((rejection_dB>=21) && (rejection_dB<=50)) beta = 0.5842 * (rejection_dB-21.0)^0.4 + 0.07886 * (rejection_dB-21.0); elseif (rejection_dB>50) beta = 0.1102 * (rejection_dB-8.7); else beta = 0.0; endif ## apodize ideal (sincard) filter response m = 2*L; t = (0 : m)' - (d-fix(d)); t = 2 * beta / m * sqrt (t .* (m - t)); w = besseli (0, t) / besseli (0, beta); h = w.*ideal_filter; endif ## check if input is a row vector isrowvector=false; if ((rows(x)==1) && (columns(x)>1)) x=x(:); isrowvector=true; endif ## check if filter is a vector if ~isvector(h) error("fracshift.m: the filter h should be a vector"); endif Lx = length(x); Lh = length(h); L = ( Lh - 1 )/2.0; Ly = Lx; ## pre and postpad filter response hpad = prepad(h,Lh); offset = floor(L); hpad = postpad(hpad,Ly + offset); ## filtering xfilt = upfirdn(x,hpad,1,1); y = xfilt(offset+1:offset+Ly,:); y=circshift(y,fix(d)); if isrowvector, y=y.'; endif endfunction %!test %! N=1024; %! d=1.5; %! t=(0:N-1)-N/2; %! tt=t-d; %! err=zeros(N/2,1); %! for n = 0:N/2-1, %! phi0=2*pi*rand; %! f0=n/N; %! sigma=N/4; %! x=exp(-t'.^2/(2*sigma)).*sin(2*pi*f0*t' + phi0); %! [y,h]=fracshift(x,d); %! xx=exp(-tt'.^2/(2*sigma)).*sin(2*pi*f0*tt' + phi0); %! err(n+1)=max(abs(y-xx)); %! endfor; %! rolloff=.1; %! rejection=10^-3; %! idx_inband=1:ceil((1-rolloff)*N/2)-1; %! assert(max(err(idx_inband)) ## Copyright (C) 2000 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## ## @seealso{kaiserord} ## @end deftypefn function w = kaiser (m, beta = 0.5) if (nargin < 1 || nargin > 2) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("kaiser: M must be a positive integer"); elseif (! (isscalar (beta) && isreal (beta))) error ("kaiser: BETA must be a real scalar"); endif if (m == 1) w = 1; else N = m - 1; k = (0 : N)'; k = 2 * beta / N * sqrt (k .* (N - k)); w = besseli (0, k) / besseli (0, beta); endif endfunction %!demo %! % use demo("kaiserord"); %!assert (kaiser (1), 1) %% Test input validation %!error kaiser () %!error kaiser (0.5) %!error kaiser (-1) %!error kaiser (ones (1, 4)) %!error kaiser (1, 2, 3) signal-1.3.2/inst/PaxHeaders.4544/upsample.m0000644000000000000000000000013212530736314015434 xustar0030 mtime=1432599756.838410741 30 atime=1432599756.838410741 30 ctime=1432599756.854411378 signal-1.3.2/inst/upsample.m0000644000000000000000000000242212530736314015755 0ustar00rootroot00000000000000## Author: Paul Kienzle (2007) ## This program is granted to the public domain. ## -*- texinfo -*- ## @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. ## @seealso{decimate, downsample, interp, resample, upfirdn} ## @end deftypefn function y = upsample (x, n, phase = 0) if nargin<2 || nargin>3, print_usage; endif if phase > n - 1 warning("This is incompatible with Matlab (phase = 0:n-1). See octave-forge signal package release notes for details." ) endif [nr,nc] = size(x); if any([nr,nc]==1), y = zeros(n*nr*nc,1); y(phase + 1:n:end) = x; if nr==1, y = y.'; endif else y = zeros(n*nr,nc); y(phase + 1:n:end,:) = x; endif endfunction %!assert(upsample([1,3,5],2),[1,0,3,0,5,0]); %!assert(upsample([1;3;5],2),[1;0;3;0;5;0]); %!assert(upsample([1,2;5,6;9,10],2),[1,2;0,0;5,6;0,0;9,10;0,0]); %!assert(upsample([2,4],2,1),[0,2,0,4]); %!assert(upsample([3,4;7,8],2,1),[0,0;3,4;0,0;7,8]); signal-1.3.2/inst/PaxHeaders.4544/dct.m0000644000000000000000000000013212530736314014360 xustar0030 mtime=1432599756.802409306 30 atime=1432599756.802409306 30 ctime=1432599756.854411378 signal-1.3.2/inst/dct.m0000644000000000000000000000561112530736314014704 0ustar00rootroot00000000000000## Copyright (C) 2001 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## ## @seealso{idct, dct2, idct2, dctmtx} ## @end deftypefn ## From Discrete Cosine Transform notes by Brian Evans at UT Austin, ## http://www.ece.utexas.edu/~bevans/courses/ee381k/lectures/09_DCT/lecture9/ ## the discrete cosine transform of x at k is as follows: ## ## N-1 ## X[k] = sum 2 x[n] cos (pi (2n+1) k / 2N ) ## n=0 ## ## which can be computed using: ## ## y = [ x ; flipud (x) ] ## Y = fft(y) ## X = exp( -j pi [0:N-1] / 2N ) .* Y ## ## or for real, even length x ## ## y = [ even(x) ; flipud(odd(x)) ] ## Y = fft(y) ## X = 2 real { exp( -j pi [0:N-1] / 2N ) .* Y } ## ## Scaling the result by w(k)/2 will give us the desired output. function y = dct (x, n) if (nargin < 1 || nargin > 2) print_usage; endif realx = isreal(x); transpose = (rows (x) == 1); if transpose, x = x (:); endif [nr, nc] = size (x); if nargin == 1 n = nr; elseif n > nr x = [ x ; zeros(n-nr,nc) ]; elseif n < nr x (nr-n+1 : n, :) = []; endif if n == 1 w = 1/2; else w = [ sqrt(1/4/n); sqrt(1/2/n)*exp((-1i*pi/2/n)*[1:n-1]') ] * ones (1, nc); endif if ( realx && rem (n, 2) == 0 ) y = fft ([ x(1:2:n,:) ; x(n:-2:1,:) ]); y = 2 * real( w .* y ); else y = fft ([ x ; flipud(x) ]); y = w .* y (1:n, :); if (realx) y = real (y); endif endif if transpose, y = y.'; endif endfunction signal-1.3.2/inst/PaxHeaders.4544/sgolayfilt.m0000644000000000000000000000013212530736314015763 xustar0030 mtime=1432599756.830410422 30 atime=1432599756.830410422 30 ctime=1432599756.854411378 signal-1.3.2/inst/sgolayfilt.m0000644000000000000000000001156112530736314016310 0ustar00rootroot00000000000000## Copyright (C) 2001 Paul Kienzle ## Copyright (C) 2004 Pascal Dupuis ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## ## @seealso{sgolay} ## @end deftypefn ## FIXME: Patch filter.cc so that it accepts matrix arguments function y = sgolayfilt (x, p = 3, n, m = 0, ts = 1) if nargin < 1 || nargin > 5 print_usage; endif if (nargin >= 3) F = sgolay(p, n, m, ts); elseif (prod(size(p)) == 1) n = p+3-rem(p,2); F = sgolay(p, n); else F = p; n = size(F,1); if (size(F,1) != size(F,2)) error("sgolayfilt(x,F): F is not a Savitzsky-Golay filter set"); endif endif transpose = (size(x,1) == 1); if (transpose) x = x.'; endif; len = size(x,1); if (len < n) error("sgolayfilt: insufficient data for filter"); endif ## The first k rows of F are used to filter the first k points ## of the data set based on the first n points of the data set. ## The last k rows of F are used to filter the last k points ## of the data set based on the last n points of the dataset. ## The remaining data is filtered using the central row of F. ## As the filter coefficients are used in the reverse order of what ## seems the logical notation, reverse F(k+1, :) so that antisymmetric ## sequences are used with the right sign. k = floor(n/2); z = filter(F(k+1,n:-1:1), 1, x); y = [ F(1:k,:)*x(1:n,:) ; z(n:len,:) ; F(k+2:n,:)*x(len-n+1:len,:) ]; if (transpose) y = y.'; endif endfunction %!demo %! [b, a] = butter(5,1/3); %! x=[zeros(1,15), 10*ones(1,10), zeros(1,15)]; %! subplot(121); %! plot(sgolayfilt(x),"r;sgolay(3,5);",... %! filtfilt(ones(1,5)/5,1,x),"g;5 sample average;",... %! filtfilt(b,a,x),"c;order 5 butterworth;",... %! x,"+b;original data;"); %! axis([1 40 -2 15]); %! title("boxcar"); %! %! x=x+randn(size(x))/2; %! subplot(122); %! plot(sgolayfilt(x,3,5),"r;sgolay(3,5);",... %! filtfilt(ones(1,5)/5,1,x),"g;5 sample average;",... %! filtfilt(b,a,x),"c;order 5 butterworth;",... %! x,"+b;original data;"); %! axis([1 40 -2 15]); %! title("boxcar+noise"); %!demo %! [b, a] = butter(5,1/3); %! t = 0:0.01:1.0; % 1 second sample %! x=cos(2*pi*t*3); % 3 Hz sinusoid %! subplot(121); %! plot(t,sgolayfilt(x,3,5),"r;sgolay(3,5);",... %! t,filtfilt(ones(1,5)/5,1,x),"g;5 sample average;",... %! t,filtfilt(b,a,x),"c;order 5 butterworth;",... %! t,x,"+b;original data;"); %! axis([0 1 -1.5 2.5]); %! title("sinusoid"); %! %! x=x+0.2*randn(size(x)); % signal+noise %! subplot(122); %! plot(t,sgolayfilt(x',3,5),"r;sgolay(3,5);",... %! t,filtfilt(ones(1,5)/5,1,x),"g;5 sample average;",... %! t,filtfilt(b,a,x),"c;order 5 butterworth;",... %! t,x,"+b;original data;"); %! axis([0 1 -1.5 2.5]); %! title("sinusoid+noise"); signal-1.3.2/inst/PaxHeaders.4544/buttord.m0000644000000000000000000000013212530736314015271 xustar0030 mtime=1432599756.794408987 30 atime=1432599756.794408987 30 ctime=1432599756.854411378 signal-1.3.2/inst/buttord.m0000644000000000000000000001014212530736314015610 0ustar00rootroot00000000000000## Copyright (C) 1999 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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}, @var{wc}] =} 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} can be given as inputs to @code{butter}. ## ## 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. ## ## Theory: |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. For high pass filters, subtracting the band edges ## from Fs/2, performing the test, and swapping the resulting Wc back ## works beautifully. For bandpass and bandstop filters this process ## significantly overdesigns. Artificially dividing N by 2 in this case ## helps a lot, but it still overdesigns. ## ## @seealso{butter, cheb1ord, cheb2ord, ellipord} ## @end deftypefn function [n, Wc] = buttord(Wp, Ws, Rp, Rs) if (nargin != 4) print_usage (); else validate_filter_bands ("buttord", Wp, Ws); endif if (numel (Wp) == 2) warning ("buttord: seems to overdesign bandpass and bandreject filters"); endif T = 2; ## if high pass, reverse the sense of the test stop = find(Wp > Ws); Wp(stop) = 1-Wp(stop); # stop will be at most length 1, so no need to Ws(stop) = 1-Ws(stop); # subtract from ones(1,length(stop)) ## warp the target frequencies according to the bilinear transform Ws = (2/T)*tan(pi*Ws./T); Wp = (2/T)*tan(pi*Wp./T); ## compute minimum n which satisfies all band edge conditions ## the factor 1/length(Wp) is an artificial correction for the ## band pass/stop case, which otherwise significantly overdesigns. qs = log(10^(Rs/10) - 1); qp = log(10^(Rp/10) - 1); n = ceil(max(0.5*(qs - qp)./log(Ws./Wp))/length(Wp)); ## compute -3dB cutoff given Wp, Rp and n Wc = exp(log(Wp) - qp/2/n); ## unwarp the returned frequency Wc = atan(T/2*Wc)*T/pi; ## if high pass, reverse the sense of the test Wc(stop) = 1-Wc(stop); endfunction %% Test input validation %!error buttord () %!error buttord (.1) %!error buttord (.1, .2) %!error buttord (.1, .2, 3) %!error buttord (.1, .2, 3, 4, 5) %!error buttord ([.1 .1], [.2 .2], 3, 4) %!error buttord ([.1 .2], [.5 .6], 3, 4) %!error buttord ([.1 .5], [.2 .6], 3, 4) signal-1.3.2/inst/PaxHeaders.4544/pwelch.m0000644000000000000000000000013212530736314015070 xustar0030 mtime=1432599756.826410262 30 atime=1432599756.826410262 30 ctime=1432599756.854411378 signal-1.3.2/inst/pwelch.m0000644000000000000000000011333112530736314015413 0ustar00rootroot00000000000000## Copyright (C) 2006 Peter V. Lanspeary ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## USAGE: ## [spectra,freq] = pwelch(x,window,overlap,Nfft,Fs, ## range,plot_type,detrend,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". ## ## x %% [non-empty vector] system-input time-series data ## y %% [non-empty vector] system-output time-series data ## ## 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. ## ## overlap %% [real scalar] segment overlap expressed as a multiple of ## %% window or segment length. 0 <= overlap < 1, ## %% The default is overlap=0.5 . ## ## 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. ## ## Fs %% [real scalar] sampling frequency (Hertz); default=1.0 ## ## 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. ## ## 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. ## ## 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'. ## ## 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. ## ## 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. ## ## 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. ## ## 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. ## ## RETURNED VALUES: ## If return values are not required by the caller, the results are ## plotted and nothing is returned. ## ## 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. ## ## 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. ## ## freq %% [real column vector] frequency values ## ## HINTS ## 1) EMPTY ARGS: ## if you don't want to use an optional argument you can leave it empty ## by writing its value as []. ## 2) 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). ## 3) 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. ## 4) 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. ## 5) 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. ## 6) 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. ## ## 7) 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. ## prev_compat=pwelch([]); ## [Pxx,f]=pwelch(x,window,overlap,Nfft,Fs,conf,...); ## 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: ## 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. ## ## Matlab R12: For compatibility with Matlab R12 to 2006a pwelch: ## 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. ## ## To adopt defaults of the Matlab R14 "spectrum.welch" spectrum object ## associated "psd" method. ## 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. ## ## ## 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. ## [3] Paul Kienzle (1999-2001): "pwelch", http://octave.sourceforge.net/ function varargout = pwelch(x,varargin) ## ## COMPATIBILITY LEVEL ## Argument positions and defaults depend on compatibility level selected ## by calling pwelch without arguments or with a single string argument. ## native: compatib=1; prev_compat=pwelch(); prev_compat=pwelch([]); ## matlab R11: compatib=2; prev_compat=pwelch('R11-'); ## matlab R12: compatib=3; prev_compat=pwelch('R12+'); ## spectrum.welch defaults: compatib=4; prev_compat=pwelch('psd'); ## In each case, the returned value is the PREVIOUS compatibility string. ## compat_str = {[]; 'R11-'; 'R12+'; 'psd'}; persistent compatib; if ( isempty(compatib) || compatib<=0 || compatib>4 ) ## legal values are 1, 2, 3, 4 compatib = 1; endif if ( nargin <= 0 ) error( 'pwelch: Need at least 1 arg. Use "help pwelch".' ); elseif ( nargin==1 && (ischar(x) || isempty(x)) ) varargout{1} = compat_str{compatib}; if ( isempty(x) ) # native compatib = 1; elseif ( strcmp(x,'R11-') ) compatib = 2; elseif ( strcmp(x,'R12+') ) compatib = 3; elseif ( strcmp(x,'psd') ) compatib = 4; else error( 'pwelch: compatibility arg must be empty, R11-, R12+ or psd' ); endif ## return ## ## Check fixed argument elseif ( isempty(x) || ~isvector(x) ) error( 'pwelch: arg 1 (x) must be vector.' ); else ## force x to be COLUMN vector if ( size(x,1)==1 ) x=x(:); endif ## ## Look through all args to check if cross PSD, transfer function or ## coherence is required. If yes, the second arg is data vector "y". arg2_is_y = 0; x_len = length(x); nvarargin = length(varargin); for iarg=1:nvarargin arg = varargin{iarg}; if ( ~isempty(arg) && ischar(arg) && ... ( strcmp(arg,'cross') || strcmp(arg,'trans') || ... strcmp(arg,'coher') || strcmp(arg,'ypower') )) ## OK. Need "y". Grab it from 2nd arg. arg = varargin{1}; if ( nargin<2 || isempty(arg) || ~isvector(arg) || length(arg)~=x_len ) error( 'pwelch: arg 2 (y) must be vector, same length as x.' ); endif ## force COLUMN vector y = varargin{1}(:); arg2_is_y = 1; break; endif endfor ## ## COMPATIBILITY ## To select default argument values, "compatib" is used as an array index. ## Index values are 1=native, 2=R11, 3=R12, 4=spectrum.welch ## ## argument positions: ## arg_posn = varargin index of window, overlap, Nfft, Fs and conf ## args respectively, a value of zero ==>> arg does not exist arg_posn = [1 2 3 4 5; # native 3 4 1 2 5; # Matlab R11- pwelch 1 2 3 4 0; # Matlab R12+ pwelch 1 2 3 4 5]; # spectrum.welch defaults arg_posn = arg_posn(compatib,:) + arg2_is_y; ## ## SPECIFY SOME DEFAULT VALUES for (not all) optional arguments ## Use compatib as array index. ## Fs = sampling frequency Fs = [ 1.0 2*pi 2*pi 2*pi ]; Fs = Fs(compatib); ## plot_type: 1='plot'|'squared'; 5='db'|'dB' plot_type = [ 1 5 5 5 ]; plot_type = plot_type(compatib); ## rm_mean: 3='long-mean'; 0='no-strip'|'none' rm_mean = [ 3 0 0 0 ]; rm_mean = rm_mean(compatib); ## use max_overlap=x_len-1 because seg_len is not available yet ## units of overlap are different for each version: ## fraction, samples, or percent max_overlap = [ 0.95 x_len-1 x_len-1 95]; max_overlap = max_overlap(compatib); ## default confidence interval ## if there are more than 2 return values and if there is a "conf" arg conf = 0.95 * (nargout>2) * (arg_posn(5)>0); ## is_win = 0; # =0 means valid window arg is not provided yet Nfft = []; # default depends on segment length overlap = []; # WARNING: units can be #samples, fraction or percentage range = ~isreal(x) || ( arg2_is_y && ~isreal(y) ); is_sloppy = 0; n_results = 0; do_power = 0; do_cross = 0; do_trans = 0; do_coher = 0; do_ypower = 0; ## ## DECODE AND CHECK OPTIONAL ARGUMENTS end_numeric_args = 0; for iarg = 1+arg2_is_y:nvarargin arg = varargin{iarg}; if ( ischar(arg) ) ## first string arg ==> no more numeric args ## non-string args cannot follow a string arg end_numeric_args = 1; ## ## decode control-string arguments if ( strcmp(arg,'sloppy') ) is_sloppy = ~is_win || is_win==1; elseif ( strcmp(arg,'plot') || strcmp(arg,'squared') ) plot_type = 1; elseif ( strcmp(arg,'semilogx') ) plot_type = 2; elseif ( strcmp(arg,'semilogy') ) plot_type = 3; elseif ( strcmp(arg,'loglog') ) plot_type = 4; elseif ( strcmp(arg,'db') || strcmp(arg,'dB') ) plot_type = 5; elseif ( strcmp(arg,'half') || strcmp(arg,'onesided') ) range = 0; elseif ( strcmp(arg,'whole') || strcmp(arg,'twosided') ) range = 1; elseif ( strcmp(arg,'shift') || strcmp(arg,'centerdc') ) range = 2; elseif ( strcmp(arg,'long-mean') ) rm_mean = 3; elseif ( strcmp(arg,'linear') ) rm_mean = 2; elseif ( strcmp(arg,'short') || strcmp(arg,'mean') ) rm_mean = 1; elseif ( strcmp(arg,'no-strip') || strcmp(arg,'none') ) rm_mean = 0; elseif ( strcmp(arg, 'power' ) ) if ( ~do_power ) n_results = n_results+1; do_power = n_results; endif elseif ( strcmp(arg, 'cross' ) ) if ( ~do_cross ) n_results = n_results+1; do_cross = n_results; endif elseif ( strcmp(arg, 'trans' ) ) if ( ~do_trans ) n_results = n_results+1; do_trans = n_results; endif elseif ( strcmp(arg, 'coher' ) ) if ( ~do_coher ) n_results = n_results+1; do_coher = n_results; endif elseif ( strcmp(arg, 'ypower' ) ) if ( ~do_ypower ) n_results = n_results+1; do_ypower = n_results; endif else error( 'pwelch: string arg %d illegal value: %s', iarg+1, arg ); endif ## end of processing string args ## elseif ( end_numeric_args ) if ( ~isempty(arg) ) ## found non-string arg after a string arg ... oops error( 'pwelch: control arg must be string' ); endif ## ## first 4 optional arguments are numeric -- in fixed order ## ## deal with "Fs" and "conf" first because empty arg is a special default ## -- "Fs" arg -- sampling frequency elseif ( iarg == arg_posn(4) ) if ( isempty(arg) ) Fs = 1; elseif ( ~isscalar(arg) || ~isreal(arg) || arg<0 ) error( 'pwelch: arg %d (Fs) must be real scalar >0', iarg+1 ); else Fs = arg; endif ## ## -- "conf" arg -- confidence level ## guard against the "it cannot happen" iarg==0 elseif ( arg_posn(5) && iarg == arg_posn(5) ) if ( isempty(arg) ) conf = 0.95; elseif ( ~isscalar(arg) || ~isreal(arg) || arg < 0.0 || arg >= 1.0 ) error( 'pwelch: arg %d (conf) must be real scalar, >=0, <1',iarg+1 ); else conf = arg; endif ## ## skip all empty args from this point onward elseif ( isempty(arg) ) 1; ## ## -- "window" arg -- window function elseif ( iarg == arg_posn(1) ) if ( isscalar(arg) ) is_win = 1; elseif ( isvector(arg) ) is_win = length(arg); if ( size(arg,2)>1 ) # vector must be COLUMN vector arg = arg(:); endif else is_win = 0; endif if ( ~is_win ) error( 'pwelch: arg %d (window) must be scalar or vector', iarg+1 ); elseif ( is_win==1 && ( ~isreal(arg) || fix(arg)~=arg || arg<=3 ) ) error( 'pwelch: arg %d (window) must be integer >3', iarg+1 ); elseif ( is_win>1 && ( ~isreal(arg) || any(arg<0) ) ) error( 'pwelch: arg %d (window) vector must be real and >=0',iarg+1); endif window = arg; is_sloppy = 0; ## ## -- "overlap" arg -- segment overlap elseif ( iarg == arg_posn(2) ) if (~isscalar(arg) || ~isreal(arg) || arg<0 || arg>max_overlap ) error( 'pwelch: arg %d (overlap) must be real from 0 to %f', ... iarg+1, max_overlap ); endif overlap = arg; ## ## -- "Nfft" arg -- FFT length elseif ( iarg == arg_posn(3) ) if ( ~isscalar(arg) || ~isreal(arg) || fix(arg)~=arg || arg<0 ) error( 'pwelch: arg %d (Nfft) must be integer >=0', iarg+1 ); endif Nfft = arg; ## else error( 'pwelch: arg %d must be string', iarg+1 ); endif endfor if ( conf>0 && (n_results && ~do_power ) ) error('pwelch: can give confidence interval for x power spectrum only' ); endif ## ## end DECODE AND CHECK OPTIONAL ARGUMENTS. ## ## SETUP REMAINING PARAMETERS ## default action is to calculate power spectrum only if ( ~n_results ) n_results = 1; do_power = 1; endif need_Pxx = do_power || do_trans || do_coher; need_Pxy = do_cross || do_trans || do_coher; need_Pyy = do_coher || do_ypower; log_two = log(2); nearly_one = 0.99999999999; ## ## compatibility-options ## provides exact compatibility with Matlab R11 or R12 ## ## Matlab R11 compatibility if ( compatib==2 ) if ( isempty(Nfft) ) Nfft = min( 256, x_len ); endif if ( is_win > 1 ) seg_len = min( length(window), Nfft ); window = window(1:seg_len); else if ( is_win ) ## window arg is scalar seg_len = window; else seg_len = Nfft; endif ## make Hann window (don't depend on sigproc) xx = seg_len - 1; window = 0.5 - 0.5 * cos( (2*pi/xx)*[0:xx].' ); endif ## ## Matlab R12 compatibility elseif ( compatib==3 ) if ( is_win > 1 ) ## window arg provides window function seg_len = length(window); else ## window arg does not provide window function; use Hamming if ( is_win ) ## window arg is scalar seg_len = window; else ## window arg not available; use R12 default, 8 windows ## ignore overlap arg; use overlap=50% -- only choice that makes sense ## this is the magic formula for 8 segments with 50% overlap seg_len = fix( (x_len-3)*2/9 ); endif ## make Hamming window (don't depend on sigproc) xx = seg_len - 1; window = 0.54 - 0.46 * cos( (2*pi/xx)*[0:xx].' ); endif if ( isempty(Nfft) ) Nfft = max( 256, 2^ceil(log(seg_len)*nearly_one/log_two) ); endif ## ## Matlab R14 psd(spectrum.welch) defaults elseif ( compatib==4 ) if ( is_win > 1 ) ## window arg provides window function seg_len = length(window); else ## window arg does not provide window function; use Hamming if ( is_win ) ## window arg is scalar seg_len = window; else ## window arg not available; use default seg_len = 64 seg_len = 64; endif ## make Hamming window (don't depend on sigproc) xx = seg_len - 1; window = 0.54 - 0.46 * cos( (2*pi/xx)*[0:xx].' ); endif ## Now we know segment length, ## so we can set default overlap as number of samples if ( ~isempty(overlap) ) overlap = fix(seg_len * overlap / 100 ); endif if ( isempty(Nfft) ) Nfft = max( 256, 2^ceil(log(seg_len)*nearly_one/log_two) ); endif ## ## default compatibility level else # if ( compatib==1 ) ## calculate/adjust segment length, window function if ( is_win > 1 ) ## window arg provides window function seg_len = length(window); else ## window arg does not provide window function; use Hamming if ( is_win ) # window arg is scalar seg_len = window; else ## window arg not available; use default length: ## = sqrt(length(x)) rounded up to nearest integer power of 2 if ( isempty(overlap) ) overlap=0.5; endif seg_len = 2 ^ ceil( log(sqrt(x_len/(1-overlap)))*nearly_one/log_two ); endif ## make Hamming window (don't depend on sigproc) xx = seg_len - 1; window = 0.54 - 0.46 * cos( (2*pi/xx)*[0:xx].' ); endif ## Now we know segment length, ## so we can set default overlap as number of samples if ( ~isempty(overlap) ) overlap = fix(seg_len * overlap); endif ## ## calculate FFT length if ( isempty(Nfft) ) Nfft = seg_len; endif if ( is_sloppy ) Nfft = 2 ^ ceil( log(Nfft) * nearly_one / log_two ); endif endif ## end of compatibility options ## ## minimum FFT length is seg_len Nfft = max( Nfft, seg_len ); ## Mean square of window is required for normalizing PSD amplitude. win_meansq = (window.' * window) / seg_len; ## ## Set default or check overlap. if ( isempty(overlap) ) overlap = fix(seg_len /2); elseif ( overlap >= seg_len ) error( 'pwelch: arg (overlap=%d) too big. Must be 0 ) Vxx = xx; else Vxx = []; endif n_ffts = 0; for start_seg = [1:seg_len-overlap:x_len-seg_len+1] end_seg = start_seg+seg_len-1; ## Don't truncate/remove the zero padding in xx and yy if ( need_Pxx || need_Pxy ) if ( rm_mean==1 ) # remove mean from segment xx(1:seg_len) = window .* ( ... x(start_seg:end_seg) - sum(x(start_seg:end_seg)) / seg_len); elseif ( rm_mean == 2 ) # remove linear trend from segment xx(1:seg_len) = window .* detrend( x(start_seg:end_seg) ); else # rm_mean==0 or 3 xx(1:seg_len) = window .* x(start_seg:end_seg); endif fft_x = fft(xx); endif if ( need_Pxy || need_Pyy ) if ( rm_mean==1 ) # remove mean from segment yy(1:seg_len) = window .* ( ... y(start_seg:end_seg) - sum(y(start_seg:end_seg)) / seg_len); elseif ( rm_mean == 2 ) # remove linear trend from segment yy(1:seg_len) = window .* detrend( y(start_seg:end_seg) ); else # rm_mean==0 or 3 yy(1:seg_len) = window .* y(start_seg:end_seg); endif fft_y = fft(yy); endif if ( need_Pxx ) ## force Pxx to be real; pgram = periodogram pgram = real(fft_x .* conj(fft_x)); Pxx = Pxx + pgram; ## sum of squared periodograms is required for confidence interval if ( conf>0 ) Vxx = Vxx + pgram .^2; endif endif if ( need_Pxy ) ## Pxy (cross power spectrum) is complex. Do not force to be real. Pxy = Pxy + fft_y .* conj(fft_x); endif if ( need_Pyy ) ## force Pyy to be real Pyy = Pyy + real(fft_y .* conj(fft_y)); endif n_ffts = n_ffts +1; endfor ## ## Calculate confidence interval ## -- incorrectly assumes that the periodogram has Gaussian probability ## distribution (actually, it has a single-sided (e.g. exponential) ## distribution. ## Sample variance of periodograms is (Vxx-Pxx.^2/n_ffts)/(n_ffts-1). ## This method of calculating variance is more susceptible to round-off ## error, but is quicker, and for double-precision arithmetic and the ## inherently noisy periodogram (variance==mean^2), it should be OK. if ( conf>0 && need_Pxx ) if ( n_ffts<2 ) Vxx = zeros(Nfft,1); else ## Should use student distribution here (for unknown variance), but tinv ## is not a core Matlab function (is in statistics toolbox. Grrr) Vxx = (erfinv(conf)*sqrt(2*n_ffts/(n_ffts-1))) * sqrt(Vxx-Pxx.^2/n_ffts); endif endif ## ## Convert two-sided spectra to one-sided spectra (if range == 0). ## For one-sided spectra, contributions from negative frequencies are added ## to the positive side of the spectrum -- but not at zero or Nyquist ## (half sampling) frequencies. This keeps power equal in time and spectral ## domains, as required by Parseval theorem. ## if ( range == 0 ) if ( ~ rem(Nfft,2) ) # one-sided, Nfft is even psd_len = Nfft/2+1; if ( need_Pxx ) Pxx = Pxx(1:psd_len) + [0; Pxx(Nfft:-1:psd_len+1); 0]; if ( conf>0 ) Vxx = Vxx(1:psd_len) + [0; Vxx(Nfft:-1:psd_len+1); 0]; endif endif if ( need_Pxy ) Pxy = Pxy(1:psd_len) + conj([0; Pxy(Nfft:-1:psd_len+1); 0]); endif if ( need_Pyy ) Pyy = Pyy(1:psd_len) + [0; Pyy(Nfft:-1:psd_len+1); 0]; endif else # one-sided, Nfft is odd psd_len = (Nfft+1)/2; if ( need_Pxx ) Pxx = Pxx(1:psd_len) + [0; Pxx(Nfft:-1:psd_len+1)]; if ( conf>0 ) Vxx = Vxx(1:psd_len) + [0; Vxx(Nfft:-1:psd_len+1)]; endif endif if ( need_Pxy ) Pxy = Pxy(1:psd_len) + conj([0; Pxy(Nfft:-1:psd_len+1)]); endif if ( need_Pyy ) Pyy = Pyy(1:psd_len) + [0; Pyy(Nfft:-1:psd_len+1)]; endif endif else # two-sided (and shifted) psd_len = Nfft; endif ## end MAIN CALCULATIONS ## ## SCALING AND OUTPUT ## Put all results in matrix, one row per spectrum ## Pxx, Pxy, Pyy are sums of periodograms, so "n_ffts" ## in the scale factor converts them into averages spectra = zeros(psd_len,n_results); spect_type = zeros(n_results,1); scale = n_ffts * seg_len * Fs * win_meansq; if ( do_power ) spectra(:,do_power) = Pxx / scale; spect_type(do_power) = 1; if ( conf>0 ) Vxx = [Pxx-Vxx Pxx+Vxx]/scale; endif endif if ( do_cross ) spectra(:,do_cross) = Pxy / scale; spect_type(do_cross) = 2; endif if ( do_trans ) spectra(:,do_trans) = Pxy ./ Pxx; spect_type(do_trans) = 3; endif if ( do_coher ) ## force coherence to be real spectra(:,do_coher) = real(Pxy .* conj(Pxy)) ./ Pxx ./ Pyy; spect_type(do_coher) = 4; endif if ( do_ypower ) spectra(:,do_ypower) = Pyy / scale; spect_type(do_ypower) = 5; endif freq = [0:psd_len-1].' * ( Fs / Nfft ); ## ## range='shift': Shift zero-frequency to the middle if ( range == 2 ) len2 = fix((Nfft+1)/2); spectra = [ spectra(len2+1:Nfft,:); spectra(1:len2,:)]; freq = [ freq(len2+1:Nfft)-Fs; freq(1:len2)]; if ( conf>0 ) Vxx = [ Vxx(len2+1:Nfft,:); Vxx(1:len2,:)]; endif endif ## ## RETURN RESULTS or PLOT if ( nargout>=2 && conf>0 ) varargout{2} = Vxx; endif if ( nargout>=(2+(conf>0)) ) ## frequency is 2nd or 3rd return value, ## depends on if 2nd is confidence interval varargout{2+(conf>0)} = freq; endif if ( nargout>=1 ) varargout{1} = spectra; else ## ## Plot the spectra if there are no return variables. plot_title=['power spectrum x '; 'cross spectrum '; 'transfer function'; 'coherence '; 'power spectrum y ' ]; for ii = 1: n_results if ( conf>0 && spect_type(ii)==1 ) Vxxxx = Vxx; else Vxxxx = []; endif if ( n_results > 1 ) figure(); endif if ( plot_type == 1 ) plot(freq,[abs(spectra(:,ii)) Vxxxx]); elseif ( plot_type == 2 ) semilogx(freq,[abs(spectra(:,ii)) Vxxxx]); elseif ( plot_type == 3 ) semilogy(freq,[abs(spectra(:,ii)) Vxxxx]); elseif ( plot_type == 4 ) loglog(freq,[abs(spectra(:,ii)) Vxxxx]); elseif ( plot_type == 5 ) # db ylabel( 'amplitude (dB)' ); plot(freq,[10*log10(abs(spectra(:,ii))) 10*log10(abs(Vxxxx))]); endif title( char(plot_title(spect_type(ii),:)) ); ylabel( 'amplitude' ); ## Plot phase of cross spectrum and transfer function if ( spect_type(ii)==2 || spect_type(ii)==3 ) figure(); if ( plot_type==2 || plot_type==4 ) semilogx(freq,180/pi*angle(spectra(:,ii))); else plot(freq,180/pi*angle(spectra(:,ii))); endif title( char(plot_title(spect_type(ii),:)) ); ylabel( 'phase' ); endif endfor endif endif endfunction %!demo %! fflush(stdout); %! rand('seed',2038014164); %! a = [ 1.0 -1.6216505 1.1102795 -0.4621741 0.2075552 -0.018756746 ]; %! white = rand(1,16384); %! signal = detrend(filter(0.70181,a,white)); %! # frequency shift by modulating with exp(j.omega.t) %! skewed = signal.*exp(2*pi*i*2/25*[1:16384]); %! Fs = 25; # sampling frequency %! hold off %! pwelch([]); %! pwelch(signal); %! hold on %! pwelch(skewed); %! pwelch(signal,'shift','semilogy'); %! hold off %! figure(); %! pwelch(skewed,[],[],[],Fs,'shift','semilogy'); %! pwelch(skewed,[],[],[],Fs,0.95,'shift','semilogy'); %! pwelch('R12+'); %! pwelch(signal,'squared'); %! figure(); %! pwelch([]); %! pwelch(signal,3640,[],4096,2*pi,[],'no-strip'); %! figure(); %! pwelch(signal,[],[],[],2*pi,0.95,'no-strip'); %! pwelch(signal,64,[],[],2*pi,'no-strip'); %! hold on %! pwelch(signal,64,[],256,2*pi,'no-strip'); %! figure(); %! pwelch('psd'); %! pwelch(signal,'squared'); %! hold off %! pwelch({}); %! pwelch(white,signal,'trans','coher','short') signal-1.3.2/inst/PaxHeaders.4544/window.m0000644000000000000000000000013212530736314015115 xustar0030 mtime=1432599756.838410741 30 atime=1432599756.838410741 30 ctime=1432599756.854411378 signal-1.3.2/inst/window.m0000644000000000000000000000316212530736314015440 0ustar00rootroot00000000000000## Copyright (C) 2008 David Bateman ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function wout = window (f, m, varargin) if (nargin == 0) error ("window: UI tool not supported"); elseif (nargin < 2) print_usage (); else w = feval (f, m, varargin{:}); if (nargout > 0) wout = w; endif endif endfunction %!assert (window (@bartlett, 16), window ("bartlett", 16)) %!assert (window (@hamming, 16), window ("hamming", 16)) %!assert (window (@hanning, 16), window ("hanning", 16)) %!assert (window (@triang, 16), window ("triang", 16)) %% Test input validation %!error window () %!error window (1) %!error window ("hanning") signal-1.3.2/inst/PaxHeaders.4544/rceps.m0000644000000000000000000000013212530736314014722 xustar0030 mtime=1432599756.826410262 30 atime=1432599756.826410262 30 ctime=1432599756.854411378 signal-1.3.2/inst/rceps.m0000644000000000000000000001065112530736314015246 0ustar00rootroot00000000000000## Copyright (C) 1999 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{y}, @var{xm}] =} rceps (@var{x}) ## Produce the cepstrum of the signal x, and if desired, the minimum ## phase reconstruction of the signal x. If x is a matrix, do so ## for each column of the matrix. ## ## 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 in x ## [y, xm] = rceps (x .* hanning (1024)); # cepstrum and min phase reconstruction ## @end group ## @end example ## ## Reference ## Programs for digital signal processing. IEEE Press. ## New York: John Wiley & Sons. 1979. ## @end deftypefn function [y, ym] = rceps(x) if (nargin != 1) print_usage; endif f = abs(fft(x)); if (any (f == 0)) error ("rceps: the spectrum of x contains zeros, unable to compute real cepstrum"); endif y = real(ifft(log(f))); if nargout == 2 n=length(x); if rows(x)==1 if rem(n,2)==1 ym = [y(1), 2*y(2:n/2+1), zeros(1,n/2)]; else ym = [y(1), 2*y(2:n/2), y(n/2+1), zeros(1,n/2-1)]; endif else if rem(n,2)==1 ym = [y(1,:); 2*y(2:n/2+1,:); zeros(n/2,columns(y))]; else ym = [y(1,:); 2*y(2:n/2,:); y(n/2+1,:); zeros(n/2-1,columns(y))]; endif endif ym = real(ifft(exp(fft(ym)))); endif endfunction %!error rceps %!error rceps(1,2) # too many arguments %!test %! ## accepts matrices %! x=randn(32,3); %! [y, xm] = rceps(x); %! ## check the mag-phase response of the reproduction %! hx = fft(x); %! hxm = fft(xm); %! assert(abs(hx), abs(hxm), 200*eps); # good magnitude response match %! ## FIXME: test for minimum phase? Stop using random datasets! %! #assert(arg(hx) != arg(hxm)); # phase mismatch %!test %! ## accepts column and row vectors %! x=randn(256,1); %! [y, xm] = rceps(x); %! [yt, xmt] = rceps(x.'); %! tol = 1e-14; %! assert(yt.', y, tol); %! assert(xmt.', xm, tol); %% Test that an odd-length input produces an odd-length output %!test %! x = randn(33, 4); %! [y, xm] = rceps(x); %! assert(size(y) == size(x)); %! assert(size(xm) == size(x)); %!demo %! f0=70; Fs=10000; # 100 Hz fundamental, 10kHz sampling rate %! a=real(poly(0.985*exp(1i*pi*[0.1, -0.1, 0.3, -0.3]))); # two formants %! s=0.05*randn(1024,1); # Noise excitation signal %! s(floor(1:Fs/f0:length(s))) = 1; # Impulse glottal wave %! x=filter(1,a,s); # Speech signal in x %! [y, xm] = rceps(x); # cepstrum and minimum phase x %! [hx, w] = freqz(x,1,[],Fs); hxm = freqz(xm); %! figure(1); %! subplot(311); %! len = 1000 * fix (min (length (x), length (xm)) / 1000); %! plot([0:len-1]*1000/Fs,x(1:len),'b;signal;'); %! hold on; plot([0:len-1]*1000/Fs,xm(1:len),'g;reconstruction;'); %! ylabel("amplitude"); xlabel("time (ms)"); %! hold off; %! subplot(312); %! axis("ticy"); %! plot(w,log(abs(hx)), ";magnitude;", ... %! w,log(abs(hxm)),";reconstruction;"); %! xlabel("frequency (Hz)"); %! subplot(313); %! axis("on"); %! plot(w,unwrap(arg(hx))/(2*pi), ";phase;",... %! w,unwrap(arg(hxm))/(2*pi),";reconstruction;"); %! xlabel("frequency (Hz)"); %! len = 1000 * fix (length (y) / 1000); %! figure(2); plot([0:len-1]*1000/Fs,y(1:len),';cepstrum;'); %! ylabel("amplitude"); xlabel("quefrency (ms)"); %! %------------------------------------------------------------- %! % confirm the magnitude spectrum is identical in the signal %! % and the reconstruction and that there are peaks in the %! % cepstrum at 14 ms intervals corresponding to an F0 of 70 Hz. signal-1.3.2/inst/PaxHeaders.4544/mscohere.m0000644000000000000000000000013212530736314015413 xustar0030 mtime=1432599756.822410103 30 atime=1432599756.822410103 30 ctime=1432599756.854411378 signal-1.3.2/inst/mscohere.m0000644000000000000000000000452512530736314015742 0ustar00rootroot00000000000000## Copyright (C) 2006 Peter V. Lanspeary ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## @seealso{pwelch} ## @end deftypefn function varargout = mscohere(varargin) ## ## Check fixed argument if (nargin < 2 || nargin > 7) print_usage (); endif nvarargin = length(varargin); ## remove any pwelch RESULT args and add 'cross' for iarg=1:nvarargin arg = varargin{iarg}; if ( ~isempty(arg) && ischar(arg) && ( strcmp(arg,'power') || ... strcmp(arg,'cross') || strcmp(arg,'trans') || ... strcmp(arg,'coher') || strcmp(arg,'ypower') )) varargin{iarg} = []; endif endfor varargin{nvarargin+1} = 'coher'; ## if ( nargout==0 ) pwelch(varargin{:}); elseif ( nargout==1 ) Pxx = pwelch(varargin{:}); varargout{1} = Pxx; elseif ( nargout>=2 ) [Pxx,f] = pwelch(varargin{:}); varargout{1} = Pxx; varargout{2} = f; endif endfunction signal-1.3.2/inst/PaxHeaders.4544/cheb.m0000644000000000000000000000013212530736314014507 xustar0030 mtime=1432599756.794408987 30 atime=1432599756.794408987 30 ctime=1432599756.854411378 signal-1.3.2/inst/cheb.m0000644000000000000000000000324412530736314015033 0ustar00rootroot00000000000000## Copyright (C) 2002 André Carezia ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function T = cheb (n, x) if (nargin != 2) print_usage; elseif !(isscalar (n) && (n == round(n)) && (n >= 0)) error ("cheb: n has to be a positive integer"); endif if (max(size(x)) == 0) T = []; endif ## avoid resizing latencies T = zeros(size(x)); ind = abs (x) <= 1; if (max(size(ind))) T(ind) = cos(n*acos(x(ind))); endif ind = abs (x) > 1; if (max(size(ind))) T(ind) = cosh(n*acosh(x(ind))); endif T = real(T); endfunction signal-1.3.2/inst/PaxHeaders.4544/movingrms.m0000644000000000000000000000013212530736314015627 xustar0030 mtime=1432599756.822410103 30 atime=1432599756.822410103 30 ctime=1432599756.854411378 signal-1.3.2/inst/movingrms.m0000644000000000000000000000562312530736314016156 0ustar00rootroot00000000000000## Copyright (c) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, see . ## -*- texinfo -*- ## @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. ## ## @seealso{sigmoid_train} ## @end deftypefn function [rmsx w]= movingrms (x,width, risetime, Fs=1) [N nc] = size (x); if width*Fs > N/2 idx = [1 N]; w = ones(N,1); else idx = round ((N + width*Fs*[-1 1])/2); w = sigmoid_train ((1:N)', idx, risetime*Fs); endif fw = fft (w.^2); fx = fft (x.^2); rmsx = real(ifft (fx.*fw)/(N-1)); rmsx (rmsx < eps*max(rmsx(:))) = 0; rmsx = circshift (sqrt (rmsx), round(mean(idx))); ##w = circshift (w, -idx(1)); endfunction %!demo %! N = 128; %! t = linspace(0,1,N)'; %! x = sigmoid_train (t,[0.4 inf],1e-2).*(2*rand(size(t))-1); %! %! Fs = 1/diff(t(1:2)); %! width = 0.05; %! rc = 5e-3; %! [wx w] = movingrms (zscore (x),width,rc,Fs); %! %! close all %! figure () %! %! area (t,wx,'facecolor',[0.85 0.85 1],'edgecolor','b','linewidth',2); %! hold on; %! h = plot (t,x,'r-;Data;',t,w,'g-;Window;'); %! set (h, 'linewidth', 2); %! hold off %! %! # --------------------------------------------------------------------------- %! # The shaded plot shows the local RMS of the Data: white noise with onset at %! # aprox. t== 0.4. %! # The observation window is also shown. %!demo %! N = 128; %! t = linspace(0,1,N)'; %! x = exp(-((t-0.5)/0.1).^2) + 0.1*rand(N,1); %! %! Fs = 1/diff(t(1:2)); %! width = 0.1; %! rc = 2e-3; %! [wx w] = movingrms (zscore (x),width,rc,Fs); %! %! close all %! figure () %! %! area (t,wx,'facecolor',[0.85 0.85 1],'edgecolor','b','linewidth',2); %! hold on; %! h = plot (t,x,'r-;Data;',t,w,'g-;Window;'); %! set (h, 'linewidth', 2); %! hold off %! %! # --------------------------------------------------------------------------- %! # The shaded plot shows the local RMS of the Data: Gausian with centered at %! # aprox. t== 0.5. %! # The observation window is also shown. signal-1.3.2/inst/PaxHeaders.4544/xcorr.m0000644000000000000000000000013212530736314014743 xustar0030 mtime=1432599756.838410741 30 atime=1432599756.838410741 30 ctime=1432599756.854411378 signal-1.3.2/inst/xcorr.m0000644000000000000000000002567112530736314015277 0ustar00rootroot00000000000000## Copyright (C) 1999-2001 Paul Kienzle ## Copyright (C) 2004 ## Copyright (C) 2008,2010 Peter Lanspeary ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## 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,:)}. ## ## @seealso{xcov} ## @end deftypefn ## The cross-correlation estimate is calculated by a "spectral" method ## in which the FFT of the first vector is multiplied element-by-element ## with the FFT of second vector. The computational effort depends on ## the length N of the vectors and is independent of the number of lags ## requested. If you only need a few lags, the "direct sum" method may ## be faster: ## ## Ref: Stearns, SD and David, RA (1988). Signal Processing Algorithms. ## New Jersey: Prentice-Hall. ## unbiased: ## ( hankel(x(1:k),[x(k:N); zeros(k-1,1)]) * y ) ./ [N:-1:N-k+1](:) ## biased: ## ( hankel(x(1:k),[x(k:N); zeros(k-1,1)]) * y ) ./ N ## ## If length(x) == length(y) + k, then you can use the simpler ## ( hankel(x(1:k),x(k:N-k)) * y ) ./ N function [R, lags] = xcorr (X, Y, maxlag, scale) if (nargin < 1 || nargin > 4) print_usage; endif ## assign arguments that are missing from the list ## or reassign (right shift) them according to data type if nargin==1 Y=[]; maxlag=[]; scale=[]; elseif nargin==2 maxlag=[]; scale=[]; if ischar(Y), scale=Y; Y=[]; elseif isscalar(Y), maxlag=Y; Y=[]; endif elseif nargin==3 scale=[]; if ischar(maxlag), scale=maxlag; maxlag=[]; endif if isscalar(Y), maxlag=Y; Y=[]; endif endif ## assign defaults to missing arguments if isvector(X) ## if isempty(Y), Y=X; endif ## this line disables code for autocorr'n N = max(length(X),length(Y)); else N = rows(X); endif if isempty(maxlag), maxlag=N-1; endif if isempty(scale), scale='none'; endif ## check argument values if isempty(X) || isscalar(X) || ischar(Y) || ! ismatrix(X) error("xcorr: X must be a vector or matrix"); endif if isscalar(Y) || ischar(Y) || (!isempty(Y) && !isvector(Y)) error("xcorr: Y must be a vector"); endif if !isempty(Y) && !isvector(X) error("xcorr: X must be a vector if Y is specified"); endif if !isscalar(maxlag) || !isreal(maxlag) || maxlag<0 || fix(maxlag)!=maxlag error("xcorr: maxlag must be a single non-negative integer"); endif ## ## sanity check on number of requested lags ## Correlations for lags in excess of +/-(N-1) ## (a) are not calculated by the FFT algorithm, ## (b) are all zero; so provide them by padding ## the results (with zeros) before returning. if (maxlag > N-1) pad_result = maxlag - (N - 1); maxlag = N - 1; %error("xcorr: maxlag must be less than length(X)"); else pad_result = 0; endif if isvector(X) && isvector(Y) && length(X) != length(Y) && ... !strcmp(scale,'none') error("xcorr: scale must be 'none' if length(X) != length(Y)") endif P = columns(X); M = 2^nextpow2(N + maxlag); if !isvector(X) ## For matrix X, correlate each column "i" with all other "j" columns R = zeros(2*maxlag+1,P^2); ## do FFTs of padded column vectors pre = fft (postpad (prepad (X, N+maxlag), M) ); post = conj (fft (postpad (X, M))); ## do autocorrelations (each column with itself) ## -- if result R is reshaped to 3D matrix (i.e. R=reshape(R,M,P,P)) ## the autocorrelations are on leading diagonal columns of R, ## where i==j in R(:,i,j) cor = ifft (post .* pre); R(:, 1:P+1:P^2) = cor (1:2*maxlag+1,:); ## do the cross correlations ## -- these are the off-diagonal column of the reshaped 3D result ## matrix -- i!=j in R(:,i,j) for i=1:P-1 j = i+1:P; cor = ifft( pre(:,i*ones(length(j),1)) .* post(:,j) ); R(:,(i-1)*P+j) = cor(1:2*maxlag+1,:); R(:,(j-1)*P+i) = conj( flipud( cor(1:2*maxlag+1,:) ) ); endfor elseif isempty(Y) ## compute autocorrelation of a single vector post = fft( postpad(X(:),M) ); cor = ifft( post .* conj(post) ); R = [ conj(cor(maxlag+1:-1:2)) ; cor(1:maxlag+1) ]; else ## compute cross-correlation of X and Y ## If one of X & Y is a row vector, the other can be a column vector. pre = fft( postpad( prepad( X(:), length(X)+maxlag ), M) ); post = fft( postpad( Y(:), M ) ); cor = ifft( pre .* conj(post) ); R = cor(1:2*maxlag+1); endif ## if inputs are real, outputs should be real, so ignore the ## insignificant complex portion left over from the FFT if isreal(X) && (isempty(Y) || isreal(Y)) R=real(R); endif ## correct for bias if strcmp(scale, 'biased') R = R ./ N; elseif strcmp(scale, 'unbiased') R = R ./ ( [ N-maxlag:N-1, N, N-1:-1:N-maxlag ]' * ones(1,columns(R)) ); elseif strcmp(scale, 'coeff') ## R = R ./ R(maxlag+1) works only for autocorrelation ## For cross correlation coeff, divide by rms(X)*rms(Y). if !isvector(X) ## for matrix (more than 1 column) X rms = sqrt( sumsq(X) ); R = R ./ ( ones(rows(R),1) * reshape(rms.'*rms,1,[]) ); elseif isempty(Y) ## for autocorrelation, R(zero-lag) is the mean square. R = R / R(maxlag+1); else ## for vectors X and Y R = R / sqrt( sumsq(X)*sumsq(Y) ); endif elseif !strcmp(scale, 'none') error("xcorr: scale must be 'biased', 'unbiased', 'coeff' or 'none'"); endif ## Pad result if necessary ## (most likely is not required, use "if" to avoid unnecessary code) ## At this point, lag varies with the first index in R; ## so pad **before** the transpose. if pad_result R_pad = zeros(pad_result,columns(R)); R = [R_pad; R; R_pad]; endif ## Correct the shape (transpose) so it is the same as the first input vector if isvector(X) && P > 1 R = R.'; endif ## return the lag indices if desired if nargout == 2 maxlag += pad_result; lags = [-maxlag:maxlag]; endif endfunction ##------------ Use brute force to compute the correlation ------- ##if !isvector(X) ## ## For matrix X, compute cross-correlation of all columns ## R = zeros(2*maxlag+1,P^2); ## for i=1:P ## for j=i:P ## idx = (i-1)*P+j; ## R(maxlag+1,idx) = X(:,i)' * X(:,j); ## for k = 1:maxlag ## R(maxlag+1-k,idx) = X(k+1:N,i)' * X(1:N-k,j); ## R(maxlag+1+k,idx) = X(1:N-k,i)' * X(k+1:N,j); ## endfor ## if (i!=j), R(:,(j-1)*P+i) = conj(flipud(R(:,idx))); endif ## endfor ## endfor ##elseif isempty(Y) ## ## reshape X so that dot product comes out right ## X = reshape(X, 1, N); ## ## ## compute autocorrelation for 0:maxlag ## R = zeros (2*maxlag + 1, 1); ## for k=0:maxlag ## R(maxlag+1+k) = X(1:N-k) * X(k+1:N)'; ## endfor ## ## ## use symmetry for -maxlag:-1 ## R(1:maxlag) = conj(R(2*maxlag+1:-1:maxlag+2)); ##else ## ## reshape and pad so X and Y are the same length ## X = reshape(postpad(X,N), 1, N); ## Y = reshape(postpad(Y,N), 1, N)'; ## ## ## compute cross-correlation ## R = zeros (2*maxlag + 1, 1); ## R(maxlag+1) = X*Y; ## for k=1:maxlag ## R(maxlag+1-k) = X(k+1:N) * Y(1:N-k); ## R(maxlag+1+k) = X(1:N-k) * Y(k+1:N); ## endfor ##endif ##-------------------------------------------------------------- signal-1.3.2/inst/PaxHeaders.4544/xcov.m0000644000000000000000000000012612530736314014570 xustar0028 mtime=1432599756.8424109 28 atime=1432599756.8424109 30 ctime=1432599756.854411378 signal-1.3.2/inst/xcov.m0000644000000000000000000000464212530736314015114 0ustar00rootroot00000000000000## Copyright (C) 1999, 2001 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## ## @seealso{xcorr} ## @end deftypefn function [retval, lags] = xcov (X, Y, maxlag, scale) if (nargin < 1 || nargin > 4) print_usage; endif if nargin==1 Y=[]; maxlag=[]; scale=[]; elseif nargin==2 maxlag=[]; scale=[]; if ischar(Y), scale=Y; Y=[]; elseif isscalar(Y), maxlag=Y; Y=[]; endif elseif nargin==3 scale=[]; if ischar(maxlag), scale=maxlag; maxlag=[]; endif if isscalar(Y), maxlag=Y; Y=[]; endif endif ## FIXME: should let center(Y) deal with [] ## [retval, lags] = xcorr(center(X), center(Y), maxlag, scale); if (!isempty(Y)) [retval, lags] = xcorr(center(X), center(Y), maxlag, scale); else [retval, lags] = xcorr(center(X), maxlag, scale); endif endfunction signal-1.3.2/inst/PaxHeaders.4544/buffer.m0000644000000000000000000000013212530736314015057 xustar0030 mtime=1432599756.794408987 30 atime=1432599756.794408987 30 ctime=1432599756.854411378 signal-1.3.2/inst/buffer.m0000644000000000000000000001762712530736314015415 0ustar00rootroot00000000000000## Copyright (C) 2008 David Bateman ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function [y, z, opt] = buffer (x, n, p, opt) if (nargin < 2 || nargin > 4) print_usage (); endif if (!isscalar (n) || n != floor (n)) error ("buffer: n must be an integer"); endif if (nargin < 3) p = 0; elseif (!isscalar (p) || p != floor (p) || p >= n) error ("buffer: p must be an integer less than n"); endif if (nargin < 4) if (p < 0) opt = 0; else opt = zeros (1, p); endif endif if (rows (x) == 1) isrowvec = true; else isrowvec = false; endif if (p < 0) if (isscalar (opt) && opt == floor (opt) && opt >= 0 && opt <= -p) lopt = opt; else error ("buffer: expecting fourth argument to be and integer between 0 and -p"); endif else lopt = 0; endif x = x (:); l = length (x); m = ceil ((l - lopt) / (n - p)); y = zeros (n - p, m); y (1 : l - lopt) = x (lopt + 1 : end); if (p < 0) y (end + p + 1 : end, :) = []; elseif (p > 0) if (ischar (opt)) if (strcmp (opt, "nodelay")) y = [y ; zeros(p, m)]; if (p > n / 2) is = n - p + 1; in = n - p; ie = is + in - 1; off = 1; while (in > 0) y (is : ie, 1 : end - off) = y (1 : in, 1 + off : end); off++; is = ie + 1; ie = ie + in; if (ie > n) ie = n; endif in = ie - is + 1; endwhile [i, j] = ind2sub([n-p, m], l); if (all ([i, j] == [n-p, m])) off --; endif y (:, end - off + 2 : end) = []; else y (end - p + 1 : end, 1 : end - 1) = y (1 : p, 2 : end); if (sub2ind([n-p, m], p, m) >= l) y (:, end) = []; endif endif else error ("buffer: unexpected string argument"); endif elseif (isvector (opt)) if (length (opt) == p) lopt = p; y = [zeros(p, m); y]; in = p; off = 1; while (in > 0) y (1 : in, off) = opt(off:end); off++; in = in - n + p; endwhile if (p > n / 2) in = n - p; ie = p; is = p - in + 1; off = 1; while (ie > 0) y (is : ie, 1 + off : end) = ... y (end - in + 1 : end, 1 : end - off); off++; ie = is - 1; is = is - in; if (is < 1) is = 1; endif in = ie - is + 1; endwhile else y (1 : p, 2 : end) = y (end - p + 1 : end, 1 : end - 1); endif else error ("buffer: opt vector must be of length p"); endif else error ("buffer: unrecognized fourth argument"); endif endif if (nargout > 1) if (p >= 0) [i, j] = ind2sub (size(y), l + lopt + p * (size (y, 2) - 1)); if (any ([i, j] != size (y))) z = y (1 + p : i, end); y (:, end) = []; else z = zeros (0, 1); endif else [i, j] = ind2sub (size (y) + [-p, 0], l - lopt); if (i < size (y, 1)) z = y (1: i, end); y (:, end) = []; else z = zeros (0, 1); endif endif if (isrowvec) z = z.'; endif if (p < 0) opt = max(0, size (y, 2) * (n - p) + opt - l); elseif (p > 0) opt = y(end-p+1:end)(:); else opt = []; endif endif endfunction %!error (buffer(1:10, 4.1)) %!assert (buffer(1:10, 4), reshape([1:10,0,0],[4,3])) %!assert (buffer(1:10, 4, 1), reshape([0:3,3:6,6:9,9,10,0,0],[4,4])) %!assert (buffer(1:10, 4, 2), reshape ([0,0:2,1:4,3:6,5:8,7:10],[4,5])) %!assert (buffer(1:10, 4, 3), [0,0,0:7;0,0:8;0:9;1:10]) %!error (buffer(1:10, 4, 3.1)) %!error (buffer(1:10, 4, 4)) %!assert (buffer(1:10, 4, -1), reshape([1:4,6:9],[4,2])) %!assert (buffer(1:10, 4, -2), reshape([1:4,7:10],[4,2])) %!assert (buffer(1:10, 4, -3), reshape([1:4,8:10,0],[4,2])) %!assert (buffer(1:10, 4, 1, 11), reshape([11,1:3,3:6,6:9,9,10,0,0],[4,4])) %!error (buffer(1:10, 4, 1, [10,11])) %!assert (buffer(1:10, 4, 1, 'nodelay'), reshape([1:4,4:7,7:10],[4,3])) %!error (buffer(1:10, 4, 1, 'badstring')) %!assert (buffer(1:10, 4, 2,'nodelay'), reshape ([1:4,3:6,5:8,7:10],[4,4])) %!assert (buffer(1:10, 4, 3, [11,12,13]),[11,12,13,1:7;12,13,1:8;13,1:9;1:10]) %!assert (buffer(1:10, 4, 3, 'nodelay'),[1:8;2:9;3:10;4:10,0]) %!assert (buffer(1:11,4,-2,1),reshape([2:5,8:11],4,2)) %!test %! [y, z] = buffer(1:12,4); %! assert (y, reshape(1:12,4,3)); %! assert (z, zeros (1,0)); %!test %! [y, z] = buffer(1:11,4); %! assert (y, reshape(1:8,4,2)); %! assert (z, [9, 10, 11]); %!test %! [y, z] = buffer([1:12]',4); %! assert (y, reshape(1:12,4,3)); %! assert (z, zeros (0,1)); %!test %! [y, z] = buffer([1:11]',4); %! assert (y, reshape(1:8,4,2)); %! assert (z, [9; 10; 11]); %!test %! [y,z,opt] = buffer(1:15,4,-2,1); %! assert (y, reshape([2:5,8:11],4,2)); %! assert (z, [14, 15]); %! assert (opt, 0); %!test %! [y,z,opt] = buffer(1:11,4,-2,1); %! assert (y, reshape([2:5,8:11],4,2)); %! assert (z, zeros (1,0)); %! assert (opt, 2); %!test %! [y,z,opt] = buffer([1:15]',4,-2,1); %! assert (y, reshape([2:5,8:11],4,2)); %! assert (z, [14; 15]); %! assert (opt, 0); %!test %! [y,z,opt] = buffer([1:11]',4,-2,1); %! assert (y, reshape([2:5,8:11],4,2)); %! assert (z, zeros (0, 1)); %! assert (opt, 2); %!test %! [y,z,opt] = buffer([1:11],5,2,[-1,0]); %! assert (y, reshape ([-1:3,2:6,5:9],[5,3])); %! assert (z, [10, 11]); %! assert (opt, [8; 9]); %!test %! [y,z,opt] = buffer([1:11]',5,2,[-1,0]); %! assert (y, reshape ([-1:3,2:6,5:9],[5,3])); %! assert (z, [10; 11]); %! assert (opt, [8; 9]); signal-1.3.2/inst/PaxHeaders.4544/sos2tf.m0000644000000000000000000000013212530736314015026 xustar0030 mtime=1432599756.834410581 30 atime=1432599756.834410581 30 ctime=1432599756.854411378 signal-1.3.2/inst/sos2tf.m0000644000000000000000000000505412530736314015353 0ustar00rootroot00000000000000## Copyright (C) 2005 Julius O. Smith III ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 direct form @math{H(z) = B(z)/A(z)}. ## ## 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}.' = [1 a1 a2]} for ## section 1, etc. The b0 entry must be nonzero for each section. ## 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 digital filter @math{H(z) = B(z)/A(z)}. ## See @code{filter} for further details. ## ## @seealso{tf2sos, zp2sos, sos2pz, zp2tf, tf2zp} ## @end deftypefn function [B,A] = sos2tf(sos, g = 1) if (nargin < 1 || nargin > 2) print_usage; endif [N,M] = size(sos); if M~=6 error('sos2tf: sos matrix should be N by 6'); endif A = 1; B = 1; for i=1:N B = conv(B, sos(i,1:3)); A = conv(A, sos(i,4:6)); endfor nB = length(B); while nB && B(nB)==0 B=B(1:nB-1); nB=length(B); endwhile nA = length(A); while nA && A(nA)==0 A=A(1:nA-1); nA=length(A); endwhile B = B * g; endfunction %!test %! B=[1 1]; %! A=[1 0.5]; %! [sos,g] = tf2sos(B,A); %! [Bh,Ah] = sos2tf(sos,g); %! assert({Bh,Ah},{B,A},10*eps); %!test %! B=[1 0 0 0 0 1]; %! A=[1 0 0 0 0 0.9]; %! [sos,g] = tf2sos(B,A); %! [Bh,Ah] = sos2tf(sos,g); %! assert({Bh,Ah},{B,A},100*eps); signal-1.3.2/inst/PaxHeaders.4544/chirp.m0000644000000000000000000000013212530736314014713 xustar0030 mtime=1432599756.798409147 30 atime=1432599756.798409147 30 ctime=1432599756.854411378 signal-1.3.2/inst/chirp.m0000644000000000000000000000733712530736314015246 0ustar00rootroot00000000000000## Copyright (C) 1999-2000 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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{form}) ## @deftypefnx {Function File} {} chirp (@var{t}, @var{f0}, @var{t1}, @var{f1}, @var{form}, @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 form ## 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 ## ## Example ## specgram(chirp([0:0.001:5])); # linear, 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); ## ## If you want a different sweep shape f(t), use the following: ## y = cos(2*pi*integral(f(t)) + 2*pi*f0*t + phase); ## @end deftypefn function y = chirp(t, f0, t1, f1, form, phase) if nargin < 1 || nargin > 6 print_usage; endif if nargin < 2, f0 = []; endif if nargin < 3, t1 = []; endif if nargin < 4, f1 = []; endif if nargin < 5, form = []; endif if nargin < 6, phase = []; endif if isempty(f0), f0 = 0; endif if isempty(t1), t1 = 1; endif if isempty(f1), f1 = 100; endif if isempty(form), form = "linear"; endif if isempty(phase), phase = 0; endif phase = 2*pi*phase/360; if strcmp(form, "linear") a = pi*(f1 - f0)/t1; b = 2*pi*f0; y = cos(a*t.^2 + b*t + phase); elseif strcmp(form, "quadratic") a = (2/3*pi*(f1-f0)/t1/t1); b = 2*pi*f0; y = cos(a*t.^3 + b*t + phase); elseif strcmp(form, "logarithmic") a = 2*pi*t1/log(f1-f0); b = 2*pi*f0; x = (f1-f0)^(1/t1); y = cos(a*x.^t + b*t + phase); else error("chirp doesn't understand '%s'",form); endif endfunction %!demo %! specgram(chirp([0:0.001:5]), 256, 1000); # linear, 0-100Hz in 1 sec %! %------------------------------------------------------------ %! % Shows linear sweep of 100 Hz/sec starting at zero for 5 sec %! % since the sample rate is 1000 Hz, this should be a diagonal %! % from bottom left to top right. %!demo %! specgram(chirp([-2:0.001:15], 400, 10, 100, 'quadratic')); %! %------------------------------------------------------------ %! % Shows a quadratic chirp of 400 Hz at t=0 and 100 Hz at t=10 %! % Time goes from -2 to 15 seconds. %!demo %! specgram(chirp([0:1/8000:5], 200, 2, 500, "logarithmic"), 256, 8000); %! %------------------------------------------------------------ %! % Shows a logarithmic chirp of 200 Hz at t=0 and 500 Hz at t=2 %! % Time goes from 0 to 5 seconds at 8000 Hz. signal-1.3.2/inst/PaxHeaders.4544/ifwht.m0000644000000000000000000000013212530736314014727 xustar0030 mtime=1432599756.814409784 30 atime=1432599756.814409784 30 ctime=1432599756.854411378 signal-1.3.2/inst/ifwht.m0000644000000000000000000000473512530736314015261 0ustar00rootroot00000000000000## Copyright (C) 2013 Mike Miller ## ## This program is free software: you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation, either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## ## @seealso{fwht} ## @end deftypefn ## Author: Mike Miller function y = ifwht (x, n, order) if (nargin < 1 || nargin > 3) print_usage (); elseif (nargin == 1) n = order = []; elseif (nargin == 2) order = []; endif y = __fwht_opts__ ("ifwht", x, n, order); endfunction %!assert (isempty (ifwht ([]))); %!assert (ifwht (zeros (16)), zeros (16)); %!assert (ifwht ([1; (zeros (15, 1))]), ones (16, 1)); %!assert (ifwht (zeros (17, 1)), zeros (32, 1)); %!assert (ifwht ([0 0 0 0 0 0 0 1]), [1 -1 1 -1 1 -1 1 -1]); %% Test input validation %!error ifwht (); %!error ifwht (1, 2, 3, 4); %!error ifwht (0, 0); %!error ifwht (0, 5); %!error ifwht (0, [], "invalid"); signal-1.3.2/inst/PaxHeaders.4544/residued.m0000644000000000000000000000013212530736314015412 xustar0030 mtime=1432599756.830410422 30 atime=1432599756.830410422 30 ctime=1432599756.854411378 signal-1.3.2/inst/residued.m0000644000000000000000000001233512530736314015737 0ustar00rootroot00000000000000## Copyright (C) 2005 Julius O. Smith III ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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} ## ## @seealso{residue, residued} ## @end deftypefn function [r, p, f, m] = residued(b, a, toler) ## RESIDUED - return residues, poles, and FIR part of B(z)/A(z) ## ## Let nb = length(b), na = length(a), and N=na-1 = no. of poles. ## If nb ## Copyright (C) 2000 Laurent S. Mazet ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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}, @var{wc}] =} 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} can be given as inputs to @code{cheby1}. ## ## 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. ## ## @seealso{buttord, cheby1, cheb2ord, ellipord} ## @end deftypefn function [n, Wc] = cheb1ord(Wp, Ws, Rp, Rs) if nargin != 4 print_usage; else validate_filter_bands ("cheb1ord", Wp, Ws); endif T = 2; ## returned frequency is the same as the input frequency Wc = Wp; ## warp the target frequencies according to the bilinear transform Ws = (2/T)*tan(pi*Ws./T); Wp = (2/T)*tan(pi*Wp./T); if (Wp(1) < Ws(1)) ## low pass if (length(Wp) == 1) Wa = Ws/Wp; else ## FIXME: Implement band reject filter type error ("cheb1ord: band reject is not yet implemented"); endif; else ## if high pass, reverse the sense of the test if (length(Wp) == 1) Wa = Wp/Ws; else ## band pass Wa=(Ws.^2 - Wp(1)*Wp(2))./(Ws*(Wp(1)-Wp(2))); endif; endif; Wa = min(abs(Wa)); ## compute minimum n which satisfies all band edge conditions stop_atten = 10^(abs(Rs)/10); pass_atten = 10^(abs(Rp)/10); n = ceil(acosh(sqrt((stop_atten-1)/(pass_atten-1)))/acosh(Wa)); endfunction %!demo %! Fs = 10000; %! [n, Wc] = cheb1ord (1000/(Fs/2), 1200/(Fs/2), 0.5, 29); %! %! subplot (221); %! plot ([0, 1000, 1000, 0, 0], [0, 0, -0.5, -0.5, 0], ";;"); %! hold on; %! axis ([ 0, 1500, -1, 0]); %! title("Pass band Wp=1000 Rp=0.5"); %! xlabel("Frequency (Hz)"); %! ylabel("Attenuation (dB)"); %! grid; %! [b, a] = cheby1 (n, 0.5, Wc); %! [h, w] = freqz (b, a, [], Fs); %! plot (w, 20*log10(abs(h)), ";;"); %! hold off; %! %! subplot (222); %! plot ([1200, Fs/2, Fs/2, 1200, 1200], [-29, -29, -500, -500, -29], ";;"); %! hold on; %! axis ([ 0, Fs/2, -250, 0]); %! title("Stop band Ws=1200 Rs=29"); %! xlabel("Frequency (Hz)"); %! ylabel("Attenuation (dB)"); %! grid; %! [b, a] = cheby1 (n, 0.5, Wc); %! [h, w] = freqz (b, a, [], Fs); %! plot (w, 20*log10(abs(h)), ";;"); %! hold off; %! %! subplot (223); %! plot ([0, 1000, 1000, 0, 0], [0, 0, -0.5, -0.5, 0], ";;"); %! hold on; %! axis ([ 990, 1010, -0.6, -0.4]); %! title("Pass band detail Wp=1000 Rp=0.5"); %! xlabel("Frequency (Hz)"); %! ylabel("Attenuation (dB)"); %! grid; %! [b, a] = cheby1 (n, 0.5, Wc); %! [h, w] = freqz (b, a, [990:1010], Fs); %! plot (w, 20*log10(abs(h)), ";filter n;"); %! [b, a] = cheby1 (n-1, 0.5, Wc); %! [h, w] = freqz (b, a, [990:1010], Fs); %! plot (w, 20*log10(abs(h)), ";filter n-1;"); %! [b, a] = cheby1 (n+1, 0.5, Wc); %! [h, w] = freqz (b, a, [990:1010], Fs); %! plot (w, 20*log10(abs(h)), ";filter n+1;"); %! hold off; %! %! subplot (224); %! plot ([1200, Fs/2, Fs/2, 1200, 1200], [-29, -29, -500, -500, -29], ";;"); %! hold on; %! axis ([ 1190, 1210, -40, -20]); %! title("Stop band detail Wp=1200 Rp=29"); %! xlabel("Frequency (Hz)"); %! ylabel("Attenuation (dB)"); %! grid; %! [b, a] = cheby1 (n, 0.5, Wc); %! [h, w] = freqz (b, a, [1190:1210], Fs); %! plot (w, 20*log10(abs(h)), ";filter n;"); %! [b, a] = cheby1 (n-1, 0.5, Wc); %! [h, w] = freqz (b, a, [1190:1210], Fs); %! plot (w, 20*log10(abs(h)), ";filter n-1;"); %! [b, a] = cheby1 (n+1, 0.5, Wc); %! [h, w] = freqz (b, a, [1190:1210], Fs); %! plot (w, 20*log10(abs(h)), ";filter n+1;"); %! hold off; %% Test case from demo %!assert (cheb1ord (0.2, 0.24, 0.5, 29), 8) %% Test input validation %!error cheb1ord () %!error cheb1ord (.1) %!error cheb1ord (.1, .2) %!error cheb1ord (.1, .2, 3) %!error cheb1ord (.1, .2, 3, 4, 5) %!error cheb1ord ([.1 .1], [.2 .2], 3, 4) %!error cheb1ord ([.1 .2], [.5 .6], 3, 4) %!error cheb1ord ([.1 .5], [.2 .6], 3, 4) signal-1.3.2/inst/PaxHeaders.4544/xcorr2.m0000644000000000000000000000012612530736314015030 xustar0028 mtime=1432599756.8424109 28 atime=1432599756.8424109 30 ctime=1432599756.854411378 signal-1.3.2/inst/xcorr2.m0000644000000000000000000001127112530736314015350 0ustar00rootroot00000000000000## Copyright (C) 2000 Dave Cogdell ## Copyright (C) 2000 Paul Kienzle ## Copyright (C) 2012 Carnë Draug ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## ## @seealso{conv2, corr2, xcorr} ## @end deftypefn function c = xcorr2 (a, b, biasflag = "none") if (nargin < 1 || nargin > 3) print_usage; elseif (nargin == 2 && ischar (b)) biasflag = b; b = a; elseif (nargin == 1) ## we have to set this case here instead of the function line, because if ## someone calls the function with zero argument, since a is never set, we ## will fail with "`a' undefined" error rather that print_usage b = a; endif if (ndims (a) != 2 || ndims (b) != 2) error ("xcorr2: input matrices must must have only 2 dimensions"); endif ## compute correlation [ma,na] = size(a); [mb,nb] = size(b); c = conv2 (a, conj (b (mb:-1:1, nb:-1:1))); ## bias routines by Dave Cogdell (cogdelld@asme.org) ## optimized by Paul Kienzle (pkienzle@users.sf.net) ## coeff routine by Carnë Draug (carandraug+dev@gmail.com) switch lower (biasflag) case {"none"} ## do nothing, it's all done case {"biased"} c = c / ( min ([ma, mb]) * min ([na, nb]) ); case {"unbiased"} lo = min ([na,nb]); hi = max ([na, nb]); row = [ 1:(lo-1), lo*ones(1,hi-lo+1), (lo-1):-1:1 ]; lo = min ([ma,mb]); hi = max ([ma, mb]); col = [ 1:(lo-1), lo*ones(1,hi-lo+1), (lo-1):-1:1 ]'; bias = col*row; c = c./bias; case {"coeff"} a = double (a); b = double (b); a = conv2 (a.^2, ones (size (b))); b = sumsq (b(:)); c(:,:) = c(:,:) ./ sqrt (a(:,:) * b); otherwise error ("xcorr2: invalid type of scale %s", biasflag); endswitch endfunction %!test # basic usage %! a = magic (5); %! b = [6 13 22; 10 18 23; 8 15 23]; %! c = [391 807 519 391 473 289 120 %! 920 1318 1045 909 1133 702 278 %! 995 1476 1338 1534 2040 1161 426 %! 828 1045 1501 2047 2108 1101 340 %! 571 1219 2074 2155 1896 821 234 %! 473 1006 1643 1457 946 347 108 %! 242 539 850 477 374 129 54]; %! assert (xcorr2 (a, b), c); %!shared a, b, c, row_shift, col_shift %! row_shift = 18; %! col_shift = 20; %! a = randi (255, 30, 30); %! b = a(row_shift-10:row_shift, col_shift-7:col_shift); %! c = xcorr2 (a, b, "coeff"); %!assert (nthargout ([1 2], @find, c == max (c(:))), {row_shift, col_shift}); # should return exact coordinates %! m = rand (size (b)) > 0.5; %! b(m) = b(m) * 0.95; %! b(!m) = b(!m) * 1.05; %! c = xcorr2 (a, b, "coeff"); %!assert (nthargout ([1 2], @find, c == max (c(:))), {row_shift, col_shift}); # even with some small noise, should return exact coordinates %!test # coeff of autocorrelation must be same as negative of correlation by additive inverse %! a = 10 * randn (100, 100); %! auto = xcorr2 (a, "coeff"); %! add_in = xcorr2 (a, -a, "coeff"); %! assert ([min(auto(:)), max(auto(:))], -[max(add_in(:)), min(add_in(:))]); signal-1.3.2/inst/PaxHeaders.4544/besselap.m0000644000000000000000000000013212530736314015404 xustar0030 mtime=1432599756.790408828 30 atime=1432599756.790408828 30 ctime=1432599756.854411378 signal-1.3.2/inst/besselap.m0000644000000000000000000000310512530736314015724 0ustar00rootroot00000000000000## Copyright (C) 2009 Thomas Sailer ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function [zero, pole, gain] = besselap (n) if (nargin>1 || nargin<1) print_usage; endif ## interpret the input parameters if (!(length(n)==1 && n == round(n) && n > 0)) error ("besselap: filter order n must be a positive integer"); endif p0=1; p1=[1 1]; for nn=2:n; px=(2*nn-1)*p1; py=[p0 0 0]; px=prepad(px,max(length(px),length(py)),0); py=prepad(py,length(px)); p0=p1; p1=px+py; endfor; ## p1 now contains the reverse bessel polynomial for n ## scale it by replacing s->s/w0 so that the gain becomes 1 p1=p1.*p1(length(p1)).^((length(p1)-1:-1:0)/(length(p1)-1)); zero=[]; pole=roots(p1); gain=1; endfunction signal-1.3.2/inst/PaxHeaders.4544/idct.m0000644000000000000000000000013212530736314014531 xustar0030 mtime=1432599756.814409784 30 atime=1432599756.814409784 30 ctime=1432599756.854411378 signal-1.3.2/inst/idct.m0000644000000000000000000000475712530736314015067 0ustar00rootroot00000000000000## Copyright (C) 2001 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## ## @seealso{dct, dct2, idct2, dctmtx} ## @end deftypefn function y = idct (x, n) if (nargin < 1 || nargin > 2) print_usage; endif realx = isreal(x); transpose = (rows (x) == 1); if transpose, x = x (:); endif [nr, nc] = size (x); if nargin == 1 n = nr; elseif n > nr x = [ x ; zeros(n-nr,nc) ]; elseif n < nr x (n-nr+1 : n, :) = []; endif if ( realx && rem (n, 2) == 0 ) w = [ sqrt(n/4); sqrt(n/2)*exp((1i*pi/2/n)*[1:n-1]') ] * ones (1, nc); y = ifft (w .* x); y([1:2:n, n:-2:1], :) = 2*real(y); elseif n == 1 y = x; else ## reverse the steps of dct using inverse operations ## 1. undo post-fft scaling w = [ sqrt(4*n); sqrt(2*n)*exp((1i*pi/2/n)*[1:n-1]') ] * ones (1, nc); y = x.*w; ## 2. reconstruct fft result and invert it w = exp(-1i*pi*[n-1:-1:1]'/n) * ones(1,nc); y = ifft ( [ y ; zeros(1,nc); y(n:-1:2,:).*w ] ); ## 3. keep only the original data; toss the reversed copy y = y(1:n, :); if (realx) y = real (y); endif endif if transpose, y = y.'; endif endfunction signal-1.3.2/inst/PaxHeaders.4544/cheb1ap.m0000644000000000000000000000013212530736314015111 xustar0030 mtime=1432599756.794408987 30 atime=1432599756.794408987 30 ctime=1432599756.854411378 signal-1.3.2/inst/cheb1ap.m0000644000000000000000000000260412530736314015434 0ustar00rootroot00000000000000## Copyright (C) 2013 Carnë Draug ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, see . ## -*- texinfo -*- ## @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")}. ## ## @seealso{cheby1} ## @end deftypefn function [z, p, g] = cheb1ap (n, Rp) if (nargin != 2) print_usage(); elseif (! isscalar (n) || ! isnumeric (n) || fix (n) != n || n <= 0) error ("cheb1ap: N must be a positive integer") elseif (! isscalar (Rp) || ! isnumeric (Rp) || Rp < 0) error ("cheb1ap: RP must be a non-negative scalar") endif [z, p, g] = cheby1 (n, Rp, 1, "s"); endfunction signal-1.3.2/inst/PaxHeaders.4544/gauspuls.m0000644000000000000000000000013212530736314015451 xustar0030 mtime=1432599756.810409625 30 atime=1432599756.810409625 30 ctime=1432599756.854411378 signal-1.3.2/inst/gauspuls.m0000644000000000000000000000226512530736314015777 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} gauspuls (@var{t},@var{fc},@var{bw}) ## Return the Gaussian modulated sinusoidal pulse. ## @end deftypefn function y = gauspuls(t, fc = 1e3, bw = 0.5) if nargin<1, print_usage; endif if fc < 0 , error("fc must be positive"); endif if bw <= 0, error("bw must be strictly positive"); endif fv = -(bw.^2.*fc.^2)/(8.*log(10.^(-6/20))); tv = 1/(4.*pi.^2.*fv); y = exp(-t.*t/(2.*tv)).*cos(2.*pi.*fc.*t); endfunction signal-1.3.2/inst/PaxHeaders.4544/fir1.m0000644000000000000000000000013212530736314014447 xustar0030 mtime=1432599756.806409466 30 atime=1432599756.806409466 30 ctime=1432599756.854411378 signal-1.3.2/inst/fir1.m0000644000000000000000000001552112530736314014774 0ustar00rootroot00000000000000## Copyright (C) 2000 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## @seealso{filter, fir2} ## @end deftypefn ## FIXME: Consider using exact expression (in terms of sinc) for the ## impulse response rather than relying on fir2. ## FIXME: Find reference to the requirement that order be even for ## filters that end high. Figure out what to do with the ## window in these cases function b = fir1(n, w, varargin) if nargin < 2 || nargin > 5 print_usage; endif ## Assign default window, filter type and scale. ## If single band edge, the first band defaults to a pass band to ## create a lowpass filter. If multiple band edges, the first band ## defaults to a stop band so that the two band case defaults to a ## band pass filter. Ick. window = []; scale = 1; ftype = (length(w)==1); ## sort arglist, normalize any string for i=1:length(varargin) arg = varargin{i}; if ischar(arg), arg=lower(arg);endif if isempty(arg) continue; endif # octave bug---can't switch on [] switch arg case {'low','stop','dc-1'}, ftype = 1; case {'high','pass','bandpass','dc-0'}, ftype = 0; case {'scale'}, scale = 1; case {'noscale'}, scale = 0; otherwise window = arg; endswitch endfor ## build response function according to fir2 requirements bands = length(w)+1; f = zeros(1,2*bands); f(1) = 0; f(2*bands)=1; f(2:2:2*bands-1) = w; f(3:2:2*bands-1) = w; m = zeros(1,2*bands); m(1:2:2*bands) = rem([1:bands]-(1-ftype),2); m(2:2:2*bands) = m(1:2:2*bands); ## Increment the order if the final band is a pass band. Something ## about having a nyquist frequency of zero causing problems. if rem(n,2)==1 && m(2*bands)==1, warning("n must be even for highpass and bandstop filters. Incrementing."); n = n+1; if isvector(window) && isreal(window) && !ischar(window) ## Extend the window using interpolation M = length(window); if M == 1, window = [window; window]; elseif M < 4 window = interp1(linspace(0,1,M),window,linspace(0,1,M+1),'linear'); else window = interp1(linspace(0,1,M),window,linspace(0,1,M+1),'spline'); endif endif endif ## compute the filter b = fir2(n, f, m, [], 2, window); ## normalize filter magnitude if scale == 1 ## find the middle of the first band edge ## find the frequency of the normalizing gain if m(1) == 1 ## if the first band is a passband, use DC gain w_o = 0; elseif f(4) == 1 ## for a highpass filter, ## use the gain at half the sample frequency w_o = 1; else ## otherwise, use the gain at the center ## frequency of the first passband w_o = f(3) + (f(4)-f(3))/2; endif ## compute |h(w_o)|^-1 renorm = 1/abs(polyval(b, exp(-1i*pi*w_o))); ## normalize the filter b = renorm*b; endif endfunction %!demo %! freqz(fir1(40,0.3)); %!demo %! freqz(fir1(15,[0.2, 0.5], 'stop')); # note the zero-crossing at 0.1 %!demo %! freqz(fir1(15,[0.2, 0.5], 'stop', 'noscale')); %!assert(fir1(2, .5, 'low', @hanning, 'scale'), [0 1 0]); %!assert(fir1(2, .5, 'low', "hanning", 'scale'), [0 1 0]); %!assert(fir1(2, .5, 'low', hanning(3), 'scale'), [0 1 0]); %!assert(fir1(10,.5,'noscale'), fir1(10,.5,'low','hamming','noscale')); %!assert(fir1(10,.5,'high'), fir1(10,.5,'high','hamming','scale')); %!assert(fir1(10,.5,'boxcar'), fir1(10,.5,'low','boxcar','scale')); %!assert(fir1(10,.5,'hanning','scale'), fir1(10,.5,'scale','hanning','low')); %!assert(fir1(10,.5,'haNNing','NOscale'), fir1(10,.5,'noscale','Hanning','LOW')); %!assert(fir1(10,.5,'boxcar',[]), fir1(10,.5,'boxcar')); %% Test expected magnitudes of passbands, stopbands, and cutoff frequencies %!test %! b = fir1 (30, 0.3); %! h = abs (freqz (b, 1, [0, 0.3, 1], 2)); %! assert (h(1), 1, 1e-3) %! assert (all (h(2:3) <= [1/sqrt(2), 3e-3])) %!test %! b = fir1 (30, 0.7, "high"); %! h = abs (freqz (b, 1, [0, 0.7, 1], 2)); %! assert (h(3), 1, 1e-3) %! assert (all (h(1:2) <= [3e-3, 1/sqrt(2)])) %!test %! b = fir1 (30, [0.3, 0.7]); %! h = abs (freqz (b, 1, [0, 0.3, 0.5, 0.7, 1], 2)); %! assert (h(3), 1, 1e-3) %! assert (all (h([1:2, 4:5]) <= [3e-3, 1/sqrt(2), 1/sqrt(2), 3e-3])) %!test %! b = fir1 (50, [0.3, 0.7], "stop"); %! h = abs (freqz (b, 1, [0, 0.3, 0.5, 0.7, 1], 2)); %! assert (h(1), 1, 1e-3) %! assert (h(5), 1, 1e-3) %! assert (all (h(2:4) <= [1/sqrt(2), 3e-3, 1/sqrt(2)])) signal-1.3.2/inst/PaxHeaders.4544/dwt.m0000644000000000000000000000013212530736314014404 xustar0030 mtime=1432599756.806409466 30 atime=1432599756.806409466 30 ctime=1432599756.854411378 signal-1.3.2/inst/dwt.m0000644000000000000000000000355112530736314014731 0ustar00rootroot00000000000000## Copyright (C) 2013 Lukas F. Reichlin ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . ## -*- texinfo -*- ## @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 ## Author: Lukas Reichlin ## Created: April 2013 ## Version: 0.1 function [u, v] = dwt (x, varargin) if (nargin == 2) wname = varargin{1}; [Hp, Gp] = wfilters (wname, "d"); elseif (nargin == 3) Hp = varargin{1}; Gp = varargin{2}; else print_usage (); endif tmp = wconv (1, x, Hp, "valid"); u = tmp(1:2:end); tmp = wconv (1, x, Gp, "valid"); v = tmp(1:2:end); endfunction signal-1.3.2/inst/PaxHeaders.4544/ss2tf.m0000644000000000000000000000013212530736314014647 xustar0030 mtime=1432599756.834410581 30 atime=1432599756.834410581 30 ctime=1432599756.854411378 signal-1.3.2/inst/ss2tf.m0000644000000000000000000000327112530736314015173 0ustar00rootroot00000000000000## Copyright (C) 1994, 1996, 2000, 2004, 2005, 2007 Auburn University ## Copyright (C) 2012 Lukas F. Reichlin ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{num}, @var{den}] =} ss2tf (@var{a}, @var{b}, @var{c}, @var{d}) ## 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 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 ## Author: R. Bruce Tenison function [num, den] = ss2tf (varargin) if (nargin == 0) print_usage (); endif [num, den] = tfdata (ss (varargin{:}), "vector"); endfunction signal-1.3.2/inst/PaxHeaders.4544/shanwavf.m0000644000000000000000000000013212530736314015423 xustar0030 mtime=1432599756.830410422 30 atime=1432599756.830410422 30 ctime=1432599756.854411378 signal-1.3.2/inst/shanwavf.m0000644000000000000000000000235512530736314015751 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function [psi,x] = shanwavf (lb,ub,n,fb,fc) if (nargin < 5) print_usage; elseif (n <= 0 || floor(n) ~= n) error("n must be an integer strictly positive"); elseif (fc <= 0 || fb <= 0) error("fc and fb must be strictly positive"); endif x = linspace(lb,ub,n); psi = (fb.^0.5).*(sinc(fb.*x).*exp(2.*i.*pi.*fc.*x)); endfunction signal-1.3.2/inst/PaxHeaders.4544/marcumq.m0000644000000000000000000000013212530736314015253 xustar0030 mtime=1432599756.818409944 30 atime=1432599756.818409944 30 ctime=1432599756.854411378 signal-1.3.2/inst/marcumq.m0000644000000000000000000004467012530736314015607 0ustar00rootroot00000000000000## Copyright (C) 2012 Robert T. Short ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function q = marcumq (a, b, m = 1, tol = eps) if ((nargin < 2) || (nargin > 4)) print_usage (); endif if (any (a < 0)) error ("marcumq: A must be a non-negative value"); endif if (any (b < 0)) error ("marcumq: B must be a non-negative value"); endif if (any (m < 0) || any (fix (m) != m)) error ("marcumq: M must be a positive integer"); endif [a, b, m] = tablify (a, b, m); q = arrayfun (@mq, a, b, m, tol); endfunction ## Subfunction to compute the actual Marcum Q function. function q = mq (a, b, m, tol) ## Special cases. if (b == 0) q = 1; N = 0; return; endif if (a == 0) k = 0:(m - 1); q = exp (-b^2 / 2) * sum (b.^(2 * k) ./ (2.^k .* factorial (k))); N = 0; return; endif ## The basic iteration. If a 1); if (any (ridx)) rdim = nrows(ridx)(1); else rdim = 1; endif ncols = cellfun (@columns, varargin(! empty)); cidx = (ncols > 1); if (any (cidx)) cdim = ncols(cidx)(1); else cdim = 1; endif if (any (nrows(ridx) != rdim) || any (ncols(cidx) != cdim)) error ("tablify: incommensurate sizes"); endif varargout = varargin; varargout(! ridx) = cellindexmat (varargout(! ridx), ones (rdim, 1), ":"); varargout(! cidx) = cellindexmat (varargout(! cidx), ":", ones (1, cdim)); endfunction %% Tests for number and validity of arguments. %!error marcumq (1) %!error marcumq (-1, 1, 1, 1, 1) %!error marcumq (-1, 1) %!error marcumq (1, -1) %!error marcumq (1, 1, -1) %!error marcumq (1, 1, 1.1) ## Notes on tests and accuracy. ## ----------------------------------- ## The numbers used as the reference (Q) in the tables below are ## from J.I. Marcum, "Table of Q Functions", Rand Technical Report ## RM-339, 1950/1/1. ## ## There is one discrepancy in the tables. Marcum has ## Q(14.00,17.10) = 0.001078 ## while we compute ## Q(14.00,17.10) = 0.0010785053 = 0.001079 ## This is obviously a non-problem. ## ## As further tests, I created several different versions of the ## Q function computation, including a Bessel series expansion and ## numerical integration. All of them agree to with 10^(-16). %!test %! a = [0.00; 0.05; 1.00; 2.00; 3.00; 4.00; 5.00; 6.00; 7.00; 8.00; 9.00; 10.00; %! 11.00; 12.00; 13.00; 14.00; 15.00; 16.00; 17.00; 18.00; 19.00; 20.00; %! 21.00; 22.00; 23.00; 24.00]; %! b = [0.000000, 0.100000, 1.100000, 2.100000, 3.100000, 4.100000]; %! Q = [1.000000, 0.995012, 0.546074, 0.110251, 0.008189, 0.000224; %! 1.000000, 0.995019, 0.546487, 0.110554, 0.008238, 0.000226; %! 1.000000, 0.996971, 0.685377, 0.233113, 0.034727, 0.002092; %! 1.000000, 0.999322, 0.898073, 0.561704, 0.185328, 0.027068; %! 1.000000, 0.999944, 0.985457, 0.865241, 0.526735, 0.169515; %! 1.000000, 0.999998, 0.999136, 0.980933, 0.851679, 0.509876; %! 1.000000, 1.000000, 0.999979, 0.998864, 0.978683, 0.844038; %! 1.000000, 1.000000, 1.000000, 0.999973, 0.998715, 0.977300; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.999969, 0.998618; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999966; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000]; %! q = marcumq (a, b); %! assert (q, Q, 1e-6); %!test %! a = [0.00; 0.05; 1.00; 2.00; 3.00; 4.00; 5.00; 6.00; 7.00; 8.00; 9.00; 10.00; %! 11.00; 12.00; 13.00; 14.00; 15.00; 16.00; 17.00; 18.00; 19.00; 20.00; %! 21.00; 22.00; 23.00; 24.00]; %! b = [5.100000, 6.100000, 7.100000, 8.100000, 9.100000, 10.10000]; %! Q = [0.000002, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000; %! 0.000002, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000; %! 0.000049, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000; %! 0.001606, 0.000037, 0.000000, 0.000000, 0.000000, 0.000000; %! 0.024285, 0.001420, 0.000032, 0.000000, 0.000000, 0.000000; %! 0.161412, 0.022812, 0.001319, 0.000030, 0.000000, 0.000000; %! 0.499869, 0.156458, 0.021893, 0.001256, 0.000028, 0.000000; %! 0.839108, 0.493229, 0.153110, 0.021264, 0.001212, 0.000027; %! 0.976358, 0.835657, 0.488497, 0.150693, 0.020806, 0.001180; %! 0.998549, 0.975673, 0.833104, 0.484953, 0.148867, 0.020458; %! 0.999965, 0.998498, 0.975152, 0.831138, 0.482198, 0.147437; %! 1.000000, 0.999963, 0.998458, 0.974742, 0.829576, 0.479995; %! 1.000000, 1.000000, 0.999962, 0.998426, 0.974411, 0.828307; %! 1.000000, 1.000000, 1.000000, 0.999961, 0.998400, 0.974138; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.999960, 0.998378; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999960; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000]; %! q = marcumq (a, b); %! assert (q, Q, 1e-6); %!test %! a = [0.00; 0.05; 1.00; 2.00; 3.00; 4.00; 5.00; 6.00; 7.00; 8.00; 9.00; 10.00; %! 11.00; 12.00; 13.00; 14.00; 15.00; 16.00; 17.00; 18.00; 19.00; 20.00; %! 21.00; 22.00; 23.00; 24.00]; %! b = [11.10000, 12.10000, 13.10000, 14.10000, 15.10000, 16.10000]; %! Q = [0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000; %! 0.000026, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000; %! 0.001155, 0.000026, 0.000000, 0.000000, 0.000000, 0.000000; %! 0.020183, 0.001136, 0.000025, 0.000000, 0.000000, 0.000000; %! 0.146287, 0.019961, 0.001120, 0.000025, 0.000000, 0.000000; %! 0.478193, 0.145342, 0.019778, 0.001107, 0.000024, 0.000000; %! 0.827253, 0.476692, 0.144551, 0.019625, 0.001096, 0.000024; %! 0.973909, 0.826366, 0.475422, 0.143881, 0.019494, 0.001087; %! 0.998359, 0.973714, 0.825607, 0.474333, 0.143304, 0.019381; %! 0.999959, 0.998343, 0.973546, 0.824952, 0.473389, 0.142803; %! 1.000000, 0.999959, 0.998330, 0.973400, 0.824380, 0.472564; %! 1.000000, 1.000000, 0.999958, 0.998318, 0.973271, 0.823876; %! 1.000000, 1.000000, 1.000000, 0.999958, 0.998307, 0.973158; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.999957, 0.998297; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999957; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000]; %! q = marcumq (a, b); %! assert (q, Q, 1e-6); %!test %! a = [0.00; 0.05; 1.00; 2.00; 3.00; 4.00; 5.00; 6.00; 7.00; 8.00; 9.00; 10.00; %! 11.00; 12.00; 13.00; 14.00; 15.00; 16.00; 17.00; 18.00; 19.00; 20.00; %! 21.00; 22.00; 23.00; 24.00]; %! b = [17.10000, 18.10000, 19.10000]; %! Q = [0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000; %! 0.000000, 0.000000, 0.000000; %! 0.000024, 0.000000, 0.000000; %! 0.001078, 0.000024, 0.000000; %! 0.019283, 0.001071, 0.000023; %! 0.142364, 0.019197, 0.001065; %! 0.471835, 0.141976, 0.019121; %! 0.823429, 0.471188, 0.141630; %! 0.973056, 0.823030, 0.470608; %! 0.998289, 0.972965, 0.822671; %! 0.999957, 0.998281, 0.972883; %! 1.000000, 0.999957, 0.998274; %! 1.000000, 1.000000, 0.999956; %! 1.000000, 1.000000, 1.000000]; %! q = marcumq (a, b); %! assert (q, Q, 1e-6); ## The tests for M>1 were generating from Marcum's tables by ## using the formula ## Q_M(a,b) = Q(a,b) + exp(-(a-b)^2/2)*sum_{k=1}^{M-1}(b/a)^k*exp(-ab)*I_k(ab) %!test %! M = 2; %! a = [0.00; 0.05; 1.00; 2.00; 3.00; 4.00; 5.00; 6.00; 7.00; 8.00; 9.00; 10.00; %! 11.00; 12.00; 13.00; 14.00; 15.00; 16.00; 17.00; 18.00; 19.00; 20.00; %! 21.00; 22.00; 23.00; 24.00]; %! b = [ 0.00, 0.10, 2.10, 7.10, 12.10, 17.10]; %! Q = [1.000000, 0.999987, 0.353353, 0.000000, 0.000000, 0.000000; %! 1.000000, 0.999988, 0.353687, 0.000000, 0.000000, 0.000000; %! 1.000000, 0.999992, 0.478229, 0.000000, 0.000000, 0.000000; %! 1.000000, 0.999999, 0.745094, 0.000001, 0.000000, 0.000000; %! 1.000000, 1.000000, 0.934771, 0.000077, 0.000000, 0.000000; %! 1.000000, 1.000000, 0.992266, 0.002393, 0.000000, 0.000000; %! 1.000000, 1.000000, 0.999607, 0.032264, 0.000000, 0.000000; %! 1.000000, 1.000000, 0.999992, 0.192257, 0.000000, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.545174, 0.000000, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.864230, 0.000040, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.981589, 0.001555, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.998957, 0.024784, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.999976, 0.166055, 0.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.509823, 0.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.846066, 0.000032; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.978062, 0.001335; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.998699, 0.022409; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.999970, 0.156421; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.495223; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.837820; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.976328; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.998564; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999966; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000]; %! q = marcumq (a, b, M); %! assert (q, Q, 1e-6); %!test %! M = 5; %! a = [0.00; 0.05; 1.00; 2.00; 3.00; 4.00; 5.00; 6.00; 7.00; 8.00; 9.00; 10.00; %! 11.00; 12.00; 13.00; 14.00; 15.00; 16.00; 17.00; 18.00; 19.00; 20.00; %! 21.00; 22.00; 23.00; 24.00]; %! b = [ 0.00, 0.10, 2.10, 7.10, 12.10, 17.10]; %! Q = [1.000000, 1.000000, 0.926962, 0.000000, 0.000000, 0.000000; %! 1.000000, 1.000000, 0.927021, 0.000000, 0.000000, 0.000000; %! 1.000000, 1.000000, 0.947475, 0.000001, 0.000000, 0.000000; %! 1.000000, 1.000000, 0.980857, 0.000033, 0.000000, 0.000000; %! 1.000000, 1.000000, 0.996633, 0.000800, 0.000000, 0.000000; %! 1.000000, 1.000000, 0.999729, 0.011720, 0.000000, 0.000000; %! 1.000000, 1.000000, 0.999990, 0.088999, 0.000000, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.341096, 0.000000, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.705475, 0.000002, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.933009, 0.000134, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.993118, 0.003793, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.999702, 0.045408, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.999995, 0.238953, 0.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.607903, 0.000001; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.896007, 0.000073; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.987642, 0.002480; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.999389, 0.034450; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.999988, 0.203879; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.565165; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.876284; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.984209; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999165; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999983; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000]; %! q = marcumq (a, b, M); %! assert (q, Q, 1e-6); %!test %! M = 10; %! a = [0.00; 0.05; 1.00; 2.00; 3.00; 4.00; 5.00; 6.00; 7.00; 8.00; 9.00; 10.00; %! 11.00; 12.00; 13.00; 14.00; 15.00; 16.00; 17.00; 18.00; 19.00; 20.00; %! 21.00; 22.00; 23.00; 24.00]; %! b = [ 0.00, 0.10, 2.10, 7.10, 12.10, 17.10]; %! Q = [1.000000, 1.000000, 0.999898, 0.000193, 0.000000, 0.000000; %! 1.000000, 1.000000, 0.999897, 0.000194, 0.000000, 0.000000; %! 1.000000, 1.000000, 0.999931, 0.000416, 0.000000, 0.000000; %! 1.000000, 1.000000, 0.999980, 0.002377, 0.000000, 0.000000; %! 1.000000, 1.000000, 0.999997, 0.016409, 0.000000, 0.000000; %! 1.000000, 1.000000, 0.999999, 0.088005, 0.000000, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.302521, 0.000000, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.638401, 0.000000, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.894322, 0.000022, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.984732, 0.000840, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.998997, 0.014160, 0.000000; %! 1.000000, 1.000000, 1.000000, 0.999972, 0.107999, 0.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.391181, 0.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.754631, 0.000004; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.951354, 0.000266; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.995732, 0.006444; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.999843, 0.065902; %! 1.000000, 1.000000, 1.000000, 1.000000, 0.999998, 0.299616; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.676336; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.925312; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.992390; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999679; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 0.999995; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000; %! 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000]; %! q = marcumq (a, b, M); %! assert (q, Q, 1e-6); signal-1.3.2/inst/PaxHeaders.4544/aryule.m0000644000000000000000000000013212530736314015107 xustar0030 mtime=1432599756.790408828 30 atime=1432599756.790408828 30 ctime=1432599756.854411378 signal-1.3.2/inst/aryule.m0000644000000000000000000000465112530736314015436 0ustar00rootroot00000000000000## Copyright (C) 1999 Paul Kienzle ## Copyright (C) 2006 Peter Lanspeary ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function [a, v, k] = aryule (x, p) if ( nargin~=2 ) print_usage; elseif ( ~isvector(x) || length(x)<3 ) error( 'aryule: arg 1 (x) must be vector of length >2' ); elseif ( ~isscalar(p) || fix(p)~=p || p > length(x)-2 ) error( 'aryule: arg 2 (p) must be an integer >0 and ## Copyright (C) 2003 Andrew Fitting ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## Usage: [B,A] = invfreqs(H,F,nB,nA) ## [B,A] = invfreqs(H,F,nB,nA,W) ## [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: ## 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)); ## FIXME: check invfreq.m for todo's function [B, A, SigN] = invfreqs(H,F,nB,nA,W,iter,tol,tr, varargin) if nargin < 9 varargin = {}; if nargin < 8 tr = ''; if nargin < 7 tol = []; if nargin < 6 iter = []; if nargin < 5 W = ones(1,length(F)); endif endif endif endif endif ## now for the real work [B, A, SigN] = invfreq(H, F,nB, nA, W, iter, tol, tr, 's', varargin{:}); endfunction %!demo %! B = [1/2 1]; %! B = [1 0 0]; %! A = [1 1]; %! ##A = [1 36 630 6930 51975 270270 945945 2027025 2027025]/2027025; %! A = [1 21 210 1260 4725 10395 10395]/10395; %! A = [1 6 15 15]/15; %! w = linspace(0, 8, 128); %! H0 = freqs(B, A, w); %! Nn = (randn(size(w))+j*randn(size(w)))/sqrt(2); %! order = length(A) - 1; %! [Bh, Ah, Sig0] = invfreqs(H0, w, [length(B)-1 2], length(A)-1); %! Hh = freqs(Bh,Ah,w); %! [BLS, ALS, SigLS] = invfreqs(H0+1e-5*Nn, w, [2 2], order, [], [], [], [], "method", "LS"); %! HLS = freqs(BLS, ALS, w); %! [BTLS, ATLS, SigTLS] = invfreqs(H0+1e-5*Nn, w, [2 2], order, [], [], [], [], "method", "TLS"); %! HTLS = freqs(BTLS, ATLS, w); %! [BMLS, AMLS, SigMLS] = invfreqs(H0+1e-5*Nn, w, [2 2], order, [], [], [], [], "method", "QR"); %! HMLS = freqs(BMLS, AMLS, w); %! plot(w,[abs(H0); abs(Hh)]) %! xlabel("Frequency (rad/sec)"); %! ylabel("Magnitude"); %! legend('Original','Measured'); %! err = norm(H0-Hh); %! disp(sprintf('L2 norm of frequency response error = %f',err)); signal-1.3.2/inst/PaxHeaders.4544/idst.m0000644000000000000000000000013212530736314014551 xustar0030 mtime=1432599756.814409784 30 atime=1432599756.814409784 30 ctime=1432599756.854411378 signal-1.3.2/inst/idst.m0000644000000000000000000000147012530736314015074 0ustar00rootroot00000000000000## Author: Paul Kienzle (2006) ## This program is granted to the public domain. ## -*- texinfo -*- ## @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. ## @seealso{dst} ## @end deftypefn function x = idst (y, n) if (nargin < 1 || nargin > 2) print_usage; endif if nargin == 1, n = size(y,1); if n==1, n = size(y,2); endif endif x = dst(y, n) * 2/(n+1); endfunction %!test %! x = log(gausswin(32)); %! assert(x, idst(dst(x)), 100*eps) signal-1.3.2/inst/PaxHeaders.4544/tf2sos.m0000644000000000000000000000013212530736314015026 xustar0030 mtime=1432599756.834410581 30 atime=1432599756.834410581 30 ctime=1432599756.854411378 signal-1.3.2/inst/tf2sos.m0000644000000000000000000000472112530736314015353 0ustar00rootroot00000000000000## Copyright (C) 2005 Julius O. Smith III ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## ## @seealso{sos2tf, zp2sos, sos2pz, zp2tf, tf2zp} ## @end deftypefn function [sos,g] = tf2sos (B, A) [z,p,k] = tf2zp(B(:)',A(:)'); if (nargout < 2) sos = zp2sos(z,p,k); else [sos,g] = zp2sos(z,p,k); endif endfunction %!test %! B=[1 0 0 0 0 1]; A=[1 0 0 0 0 .9]; %! [sos,g] = tf2sos(B,A); %! [Bh,Ah] = sos2tf(sos,g); %! assert({Bh,Ah},{B,A},100*eps); signal-1.3.2/inst/PaxHeaders.4544/levinson.m0000644000000000000000000000013212530736314015443 xustar0030 mtime=1432599756.818409944 30 atime=1432599756.818409944 30 ctime=1432599756.854411378 signal-1.3.2/inst/levinson.m0000644000000000000000000000641012530736314015765 0ustar00rootroot00000000000000## Copyright (C) 1999 Paul Kienzle ## Copyright (C) 2006 Peter V. Lanspeary, ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## Based on: ## yulewalker.m ## Copyright (C) 1995 Friedrich Leisch ## GPL license ## FIXME: Matlab doesn't return reflection coefficients and ## errors in addition to the polynomial a. ## FIXME: What is the difference between aryule, levinson, ## ac2poly, ac2ar, lpc, etc.? function [a, v, ref] = levinson (acf, p) if ( nargin<1 ) print_usage; elseif( ~isvector(acf) || length(acf)<2 ) error( "levinson: arg 1 (acf) must be vector of length >1\n"); elseif ( nargin>1 && ( ~isscalar(p) || fix(p)~=p ) ) error( "levinson: arg 2 (p) must be integer >0\n"); else if ((nargin == 1)||(p>=length(acf))) p = length(acf) - 1; endif if( columns(acf)>1 ) acf=acf(:); endif # force a column vector if nargout < 3 && p < 100 ## direct solution [O(p^3), but no loops so slightly faster for small p] ## Kay & Marple Eqn (2.39) R = toeplitz(acf(1:p), conj(acf(1:p))); a = R \ -acf(2:p+1); a = [ 1, a.' ]; v = real( a*conj(acf(1:p+1)) ); else ## durbin-levinson [O(p^2), so significantly faster for large p] ## Kay & Marple Eqns (2.42-2.46) ref = zeros(p,1); g = -acf(2)/acf(1); a = [ g ]; v = real( ( 1 - g*conj(g)) * acf(1) ); ref(1) = g; for t = 2 : p g = -(acf(t+1) + a * acf(t:-1:2)) / v; a = [ a+g*conj(a(t-1:-1:1)), g ]; v = v * ( 1 - real(g*conj(g)) ) ; ref(t) = g; endfor a = [1, a]; endif endif endfunction signal-1.3.2/inst/PaxHeaders.4544/resample.m0000644000000000000000000000013212530736314015416 xustar0030 mtime=1432599756.830410422 30 atime=1432599756.830410422 30 ctime=1432599756.854411378 signal-1.3.2/inst/resample.m0000644000000000000000000001233312530736314015741 0ustar00rootroot00000000000000## Copyright (C) 2008 Eric Chassande-Mottin, CNRS (France) ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function [y, h] = resample( x, p, q, h ) if nargchk(3,4,nargin) print_usage; elseif any([p q]<=0) || any([p q]~=floor([p q])), error("resample.m: p and q must be positive integers"); endif ## simplify decimation and interpolation factors great_common_divisor=gcd(p,q); if (great_common_divisor>1) p = double (p) / double (great_common_divisor); q = double (q) / double (great_common_divisor); else p = double (p); q = double (q); endif ## filter design if required if (nargin < 4) ## properties of the antialiasing filter log10_rejection = -3.0; stopband_cutoff_f = 1 / (2 * max (p, q)); roll_off_width = stopband_cutoff_f / 10.0; ## determine filter length ## use empirical formula from [2] Chap 7, Eq. (7.63) p 476 rejection_dB = -20.0*log10_rejection; L = ceil((rejection_dB-8.0) / (28.714 * roll_off_width)); ## ideal sinc filter t=(-L:L)'; ideal_filter=2*p*stopband_cutoff_f*sinc(2*stopband_cutoff_f*t); ## determine parameter of Kaiser window ## use empirical formula from [2] Chap 7, Eq. (7.62) p 474 if ((rejection_dB>=21) && (rejection_dB<=50)) beta = 0.5842 * (rejection_dB-21.0)^0.4 + 0.07886 * (rejection_dB-21.0); elseif (rejection_dB>50) beta = 0.1102 * (rejection_dB-8.7); else beta = 0.0; endif ## apodize ideal filter response h=kaiser(2*L+1,beta).*ideal_filter; endif ## check if input is a row vector isrowvector=false; if ((rows(x)==1) && (columns(x)>1)) x=x(:); isrowvector=true; endif ## check if filter is a vector if ~isvector(h) error("resample.m: the filter h should be a vector"); endif Lx = rows(x); Lh = length(h); L = ( Lh - 1 )/2.0; Ly = ceil(Lx*p/q); ## pre and postpad filter response nz_pre = floor(q-mod(L,q)); hpad = prepad(h,Lh+nz_pre); offset = floor((L+nz_pre)/q); nz_post = 0; while ceil( ( (Lx-1)*p + nz_pre + Lh + nz_post )/q ) - offset < Ly nz_post++; endwhile hpad = postpad(hpad,Lh + nz_pre + nz_post); ## filtering xfilt = upfirdn(x,hpad,p,q); y = xfilt(offset+1:offset+Ly,:); if isrowvector, y=y.'; endif endfunction %!test %! N=512; %! p=3; q=5; %! r=p/q; %! NN=ceil(r*N); %! t=0:N-1; %! tt=0:NN-1; %! err=zeros(N/2,1); %! for n = 0:N/2-1, %! phi0=2*pi*rand; %! f0=n/N; %! x=sin(2*pi*f0*t' + phi0); %! [y,h]=resample(x,p,q); %! xx=sin(2*pi*f0/r*tt' + phi0); %! t0=ceil((length(h)-1)/2/q); %! idx=t0+1:NN-t0; %! err(n+1)=max(abs(y(idx)-xx(idx))); %! endfor; %! rolloff=.1; %! rejection=10^-3; %! idx_inband=1:ceil((1-rolloff/2)*r*N/2)-1; %! assert(max(err(idx_inband)) ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## ## @seealso{decimate, resample} ## @end deftypefn function y = interp(x, q, n = 4, Wc = 0.5) if nargin < 1 || nargin > 4, print_usage; endif if q != fix(q), error("decimate only works with integer q."); endif if rows(x)>1 y = zeros(length(x)*q+q*n+1,1); else y = zeros(1,length(x)*q+q*n+1); endif y(1:q:length(x)*q) = x; b = fir1(2*q*n+1, Wc/q); y=q*fftfilt(b, y); y(1:q*n+1) = []; # adjust for zero filter delay endfunction %!demo %! ## 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 %! plot(t(1:121)*1000,y(1:121),"r-+;Interpolated;"); hold on; %! stem(t(1:4:121)*1000,x(1:4:121),"ob;Original;"); hold off; %! %! % graph shows interpolated signal following through the %! % sample points of the original signal. signal-1.3.2/inst/PaxHeaders.4544/invfreq.m0000644000000000000000000000013212530736314015260 xustar0030 mtime=1432599756.818409944 30 atime=1432599756.818409944 30 ctime=1432599756.854411378 signal-1.3.2/inst/invfreq.m0000644000000000000000000002107112530736314015602 0ustar00rootroot00000000000000## Copyright (C) 1986, 2000, 2003 Julius O. Smith III ## Copyright (C) 2007 Rolf Schirmacher ## Copyright (C) 2003 Andrew Fitting ## Copyright (C) 2010 Pascal Dupuis ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## usage: [B,A] = invfreq(H,F,nB,nA) ## [B,A] = invfreq(H,F,nB,nA,W) ## [B,A] = invfreq(H,F,nB,nA,W,[],[],plane) ## [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: ## [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))); ## ## 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 ## FIXME: implement Steiglitz-McBride iterations ## FIXME: improve numerical stability for high order filters (matlab is a bit better) ## FIXME: modify to accept more argument configurations function [B, A, SigN] = invfreq(H, F, nB, nA, W, iter, tol, tr, plane, varargin) if length(nB) > 1, zB = nB(2); nB = nB(1); else zB = 0; endif n = max(nA, nB); m = n+1; mA = nA+1; mB = nB+1; nF = length(F); if nF ~= length(H), disp('invfreqz: length of H and F must be the same'); endif if nargin < 5 || isempty(W), W = ones(1, nF); endif if nargin < 6, iter = []; endif if nargin < 7 tol = []; endif if nargin < 8 || isempty(tr), tr = ''; endif if nargin < 9, plane = 'z'; endif if nargin < 10, varargin = {}; endif if iter~=[], disp('no implementation for iter yet'),endif if tol ~=[], disp('no implementation for tol yet'),endif if (plane ~= 'z' && plane ~= 's'), disp('invfreqz: Error in plane argument'), endif [reg, prop ] = parseparams(varargin); ## should we normalize freqs to avoid matrices with rank deficiency ? norm = false; ## by default, use Ordinary Least Square to solve normal equations method = 'LS'; if length(prop) > 0 indi = 1; while indi <= length(prop) switch prop{indi} case 'norm' if indi < length(prop) && ~ischar(prop{indi+1}), norm = logical(prop{indi+1}); prop(indi:indi+1) = []; continue else norm = true; prop(indi) = []; continue endif case 'method' if indi < length(prop) && ischar(prop{indi+1}), method = prop{indi+1}; prop(indi:indi+1) = []; continue else error('invfreq.m: incorrect/missing method argument'); endif otherwise # FIXME: just skip it for now disp(sprintf("Ignoring unknown argument %s", varargin{indi})); indi = indi + 1; endswitch endwhile endif Ruu = zeros(mB, mB); Ryy = zeros(nA, nA); Ryu = zeros(nA, mB); Pu = zeros(mB, 1); Py = zeros(nA,1); if strcmp(tr,'trace') disp(' ') disp('Computing nonuniformly sampled, equation-error, rational filter.'); disp(['plane = ',plane]); disp(' ') endif s = sqrt(-1)*F; switch plane case 'z' if max(F) > pi || min(F) < 0 disp('hey, you frequency is outside the range 0 to pi, making my own') F = linspace(0, pi, length(H)); s = sqrt(-1)*F; endif s = exp(-s); case 's' if max(F) > 1e6 && n > 5, if ~norm, disp('Be careful, there are risks of generating singular matrices'); disp('Call invfreqs as (..., "norm", true) to avoid it'); else Fmax = max(F); s = sqrt(-1)*F/Fmax; endif endif endswitch for k=1:nF, Zk = (s(k).^[0:n]).'; Hk = H(k); aHks = Hk*conj(Hk); Rk = (W(k)*Zk)*Zk'; rRk = real(Rk); Ruu = Ruu + rRk(1:mB, 1:mB); Ryy = Ryy + aHks*rRk(2:mA, 2:mA); Ryu = Ryu + real(Hk*Rk(2:mA, 1:mB)); Pu = Pu + W(k)*real(conj(Hk)*Zk(1:mB)); Py = Py + (W(k)*aHks)*real(Zk(2:mA)); endfor Rr = ones(length(s), mB+nA); Zk = s; for k = 1:min(nA, nB), Rr(:, 1+k) = Zk; Rr(:, mB+k) = -Zk.*H; Zk = Zk.*s; endfor for k = 1+min(nA, nB):max(nA, nB)-1, if k <= nB, Rr(:, 1+k) = Zk; endif if k <= nA, Rr(:, mB+k) = -Zk.*H; endif Zk = Zk.*s; endfor k = k+1; if k <= nB, Rr(:, 1+k) = Zk; endif if k <= nA, Rr(:, mB+k) = -Zk.*H; endif ## complex to real equation system -- this ensures real solution Rr = Rr(:, 1+zB:end); Rr = [real(Rr); imag(Rr)]; Pr = [real(H(:)); imag(H(:))]; ## normal equations -- keep for ref ## Rn= [Ruu(1+zB:mB, 1+zB:mB), -Ryu(:, 1+zB:mB)'; -Ryu(:, 1+zB:mB), Ryy]; ## Pn= [Pu(1+zB:mB); -Py]; switch method case {'ls' 'LS'} ## avoid scaling errors with Theta = R\P; ## [Q, R] = qr([Rn Pn]); Theta = R(1:end, 1:end-1)\R(1:end, end); [Q, R] = qr([Rr Pr], 0); Theta = R(1:end-1, 1:end-1)\R(1:end-1, end); ## SigN = R(end, end-1); SigN = R(end, end); case {'tls' 'TLS'} ## [U, S, V] = svd([Rn Pn]); ## SigN = S(end, end-1); ## Theta = -V(1:end-1, end)/V(end, end); [U, S, V] = svd([Rr Pr], 0); SigN = S(end, end); Theta = -V(1:end-1, end)/V(end, end); case {'mls' 'MLS' 'qr' 'QR'} ## [Q, R] = qr([Rn Pn], 0); ## solve the noised part -- DO NOT USE ECONOMY SIZE ! ## [U, S, V] = svd(R(nA+1:end, nA+1:end)); ## SigN = S(end, end-1); ## Theta = -V(1:end-1, end)/V(end, end); ## unnoised part -- remove B contribution and back-substitute ## Theta = [R(1:nA, 1:nA)\(R(1:nA, end) - R(1:nA, nA+1:end-1)*Theta) ## Theta]; ## solve the noised part -- economy size OK as #rows > #columns [Q, R] = qr([Rr Pr], 0); eB = mB-zB; sA = eB+1; [U, S, V] = svd(R(sA:end, sA:end)); ## noised (A) coefficients Theta = -V(1:end-1, end)/V(end, end); ## unnoised (B) part -- remove A contribution and back-substitute Theta = [R(1:eB, 1:eB)\(R(1:eB, end) - R(1:eB, sA:end-1)*Theta) Theta]; SigN = S(end, end); otherwise error("invfreq: unknown method %s", method); endswitch B = [zeros(zB, 1); Theta(1:mB-zB)].'; A = [1; Theta(mB-zB+(1:nA))].'; if strcmp(plane,'s') B = B(mB:-1:1); A = A(mA:-1:1); if norm, # Frequencies were normalized -- unscale coefficients Zk = Fmax.^[n:-1:0].'; for k = nB:-1:1+zB, B(k) = B(k)/Zk(k); endfor for k = nA:-1:1, A(k) = A(k)/Zk(k); endfor endif endif endfunction %!demo %! order = 6; # order of test filter %! fc = 1/2; # sampling rate / 4 %! n = 128; # frequency grid size %! [B, A] = butter(order,fc); %! [H, w] = freqz(B,A,n); %! [Bh, Ah] = invfreq(H,w,order,order); %! [Hh, wh] = freqz(Bh,Ah,n); %! plot(w,[abs(H), abs(Hh)]) %! xlabel("Frequency (rad/sample)"); %! ylabel("Magnitude"); %! legend('Original','Measured'); %! err = norm(H-Hh); %! disp(sprintf('L2 norm of frequency response error = %f',err)); signal-1.3.2/inst/PaxHeaders.4544/sigmoid_train.m0000644000000000000000000000013212530736314016436 xustar0030 mtime=1432599756.834410581 30 atime=1432599756.834410581 30 ctime=1432599756.854411378 signal-1.3.2/inst/sigmoid_train.m0000644000000000000000000000757512530736314016775 0ustar00rootroot00000000000000## Copyright (c) 2011-2013 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} 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}. ## ## Run @code{demo sigmoid_train} to some examples of the use of this function. ## ## @end deftypefn function envelope = sigmoid_train (t, range, timeconstant) ## number of sigmoids nRanges = size (range, 1); ## Parse time constants if isscalar (timeconstant) ## All bumps have the same time constant and are symmetric timeconstant = timeconstant * ones (nRanges,2); elseif any( size(timeconstant) != [1 1]) ## All bumps have different time constant but are symmetric if length(timeconstant) ~= nRanges error('signalError','Length of time constant must equal number of ranges.') endif if isrow (timeconstant) timeconstant = timeconstant'; endif timeconstant = repmat (timeconstant,1,2); endif ## Make sure t is horizontal flag_transposed = false; if iscolumn (t) t = t.'; flag_transposed = true; endif [ncol nrow] = size (t); ## Compute arguments of each sigmoid T = repmat (t, nRanges, 1); RC1 = repmat (timeconstant(:,1), 1, nrow); RC2 = repmat (timeconstant(:,2), 1, nrow); a_up = (repmat (range(:,1), 1 ,nrow) - T)./RC1; a_dw = (repmat (range(:,2), 1 ,nrow) - T)./RC2; ## Evaluate the sigmoids and mix them Y = 1 ./ ( 1 + exp (a_up) ) .* (1 - 1 ./ ( 1 + exp (a_dw) ) ); envelope = max(Y,[],1); if flag_transposed envelope = envelope.'; endif endfunction %!demo %! # Vectorized %! t = linspace (0, 2, 500); %! range = [0.1 0.4; 0.6 0.8; 1 2]; %! rc = [1e-2 1e-2; 1e-3 1e-3; 2e-2 2e-2]; %! y = sigmoid_train (t, range, rc); %! %! close all %! for i=1:3 %! patch ([range(i,[2 2]) range(i,[1 1])], [0 1 1 0],... %! 'facecolor', [1 0.8 0.8],'edgecolor','none'); %! endfor %! hold on; plot (t, y, 'b;Sigmoid train;','linewidth',2); hold off %! xlabel('time'); ylabel('S(t)') %! title ('Vectorized use of sigmoid train') %! axis tight %! %! #------------------------------------------------------------------------- %! # The colored regions show the limits defined in range. %!demo %! # On demand %! t = linspace(0,2,200).'; %! ran = [0.5 1; 1.5 1.7]; %! rc = 3e-2; %! dxdt = @(x_,t_) [ x_(2); sigmoid_train(t_, ran, rc) ]; %! y = lsode(dxdt,[0 0],t); %! %! close all %! for i=1:2 %! patch ([ran(i,[2 2]) ran(i,[1 1])], [0 1 1 0],... %! 'facecolor', [1 0.8 0.8],'edgecolor','none'); %! endfor %! hold on; plot (t, y(:,2), 'b;Speed;','linewidth',2); hold off %! xlabel('time'); ylabel('V(t)') %! title ('On demand use of sigmoid train') %! axis tight %! %! #------------------------------------------------------------------------- %! # The colored regions show periods when the force is active. signal-1.3.2/inst/PaxHeaders.4544/rectpuls.m0000644000000000000000000000013212530736314015447 xustar0030 mtime=1432599756.830410422 30 atime=1432599756.830410422 30 ctime=1432599756.854411378 signal-1.3.2/inst/rectpuls.m0000644000000000000000000000421112530736314015766 0ustar00rootroot00000000000000## Copyright (C) 2000 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 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 ## auplot(pulstran(0:1/fs:4/f0, 0:1/f0:4/f0, 'rectpuls', w), fs); ## @end group ## @end example ## ## @seealso{pulstran} ## @end deftypefn function y = rectpuls(t, w = 1) if nargin<1 || nargin>2, print_usage; endif y = zeros(size(t)); idx = find(t>=-w/2 & t < w/2); try wfi = warning("off", "Octave:fortran-indexing"); catch wfi = 0; end_try_catch unwind_protect y(idx) = ones(size(idx)); unwind_protect_cleanup warning(wfi); end_unwind_protect endfunction %!assert(rectpuls(0:1/100:0.3,.1), rectpuls([0:1/100:0.3]',.1)'); %!assert(isempty(rectpuls([],.1))); %!demo %! fs = 11025; # arbitrary sample rate %! f0 = 100; # pulse train sample rate %! w = 0.3/f0; # pulse width 1/10th the distance between pulses %! x = pulstran(0:1/fs:4/f0, 0:1/f0:4/f0, 'rectpuls', w); %! plot([0:length(x)-1]*1000/fs, x); %! ylabel("amplitude"); xlabel("time (ms)"); %! title("graph shows 3 ms pulses at 0,10,20,30 and 40 ms"); signal-1.3.2/inst/PaxHeaders.4544/blackmanharris.m0000644000000000000000000000013212530736314016567 xustar0030 mtime=1432599756.790408828 30 atime=1432599756.790408828 30 ctime=1432599756.854411378 signal-1.3.2/inst/blackmanharris.m0000644000000000000000000000513512530736314017114 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## ## @seealso{rectwin, bartlett} ## @end deftypefn function w = blackmanharris (m, opt) if (nargin < 1 || nargin > 2) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("blackmanharris: M must be a positive integer"); endif N = m - 1; if (nargin == 2) switch (opt) case "periodic" N = m; case "symmetric" N = m - 1; otherwise error ("blackmanharris: window type must be either \"periodic\" or \"symmetric\""); endswitch endif if (m == 1) w = 1; else a0 = 0.35875; a1 = 0.48829; a2 = 0.14128; a3 = 0.01168; n = [0:m-1]'; w = a0 - a1.*cos(2.*pi.*n./N) + a2.*cos(4.*pi.*n./N) - a3.*cos(6.*pi.*n./N); endif endfunction %!assert (blackmanharris (1), 1); %!assert (blackmanharris (2), 0.00006 * ones (2, 1), eps); %!assert (blackmanharris (15), flipud (blackmanharris (15)), 10*eps); %!assert (blackmanharris (16), flipud (blackmanharris (16)), 10*eps); %!assert (blackmanharris (15), blackmanharris (15, "symmetric")); %!assert (blackmanharris (16)(1:15), blackmanharris (15, "periodic")); %% Test input validation %!error blackmanharris () %!error blackmanharris (0.5) %!error blackmanharris (-1) %!error blackmanharris (ones (1, 4)) %!error blackmanharris (1, 2) %!error blackmanharris (1, "invalid") signal-1.3.2/inst/PaxHeaders.4544/diric.m0000644000000000000000000000013212530736314014700 xustar0030 mtime=1432599756.802409306 30 atime=1432599756.802409306 30 ctime=1432599756.854411378 signal-1.3.2/inst/diric.m0000644000000000000000000000221612530736314015222 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} diric (@var{x},@var{n}) ## Compute the dirichlet function. ## @seealso{sinc, gauspuls, sawtooth} ## @end deftypefn function y = diric(x,n) if (nargin < 2) print_usage; elseif (n <= 0 || floor(n) ~= n) error("n must be an integer strictly positive"); endif y = sin(n.*x./2)./(n.*sin(x./2)); y(mod(x,2*pi)==0) = (-1).^((n-1).*x(mod(x,2*pi)==0)./(2.*pi)); endfunction signal-1.3.2/inst/PaxHeaders.4544/butter.m0000644000000000000000000000013212530736314015113 xustar0030 mtime=1432599756.794408987 30 atime=1432599756.794408987 30 ctime=1432599756.854411378 signal-1.3.2/inst/butter.m0000644000000000000000000001557012530736314015444 0ustar00rootroot00000000000000## Copyright (C) 1999 Paul Kienzle ## Copyright (C) 2003 Doug Stewart ## Copyright (C) 2011 Alexander Klein ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{b}, @var{a}] =} butter (@var{n}, @var{w}) ## @deftypefnx {Function File} {[@var{b}, @var{a}] =} butter (@var{n}, @var{w}, "high") ## @deftypefnx {Function File} {[@var{b}, @var{a}] =} butter (@var{n}, [@var{wl}, @var{wh}]) ## @deftypefnx {Function File} {[@var{b}, @var{a}] =} butter (@var{n}, [@var{wl}, @var{wh}], "stop") ## @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. ## ## [b,a] = butter(n, Wc) ## low pass filter with cutoff pi*Wc radians ## ## [b,a] = butter(n, Wc, 'high') ## high pass filter with cutoff pi*Wc radians ## ## [b,a] = butter(n, [Wl, Wh]) ## band pass filter with edges pi*Wl and pi*Wh radians ## ## [b,a] = butter(n, [Wl, Wh], 'stop') ## band reject filter with edges pi*Wl and pi*Wh radians ## ## [z,p,g] = butter(...) ## return filter as zero-pole-gain rather than coefficients of the ## numerator and denominator polynomials. ## ## [...] = butter(...,'s') ## return a Laplace space filter, W can be larger than 1. ## ## [a,b,c,d] = butter(...) ## return state-space matrices ## ## References: ## ## Proakis & Manolakis (1992). Digital Signal Processing. New York: ## Macmillan Publishing Company. ## @end deftypefn function [a, b, c, d] = butter (n, w, varargin) if (nargin > 4 || nargin < 2 || nargout > 4 || nargout < 2) print_usage (); endif ## interpret the input parameters if (! (isscalar (n) && (n == fix (n)) && (n > 0))) error ("butter: filter order N must be a positive integer"); endif stop = false; digital = true; for i = 1:numel (varargin) switch (varargin{i}) case "s" digital = false; case "z" digital = true; case {"high", "stop"} stop = true; case {"low", "pass"} stop = false; otherwise error ("butter: expected [high|stop] or [s|z]"); endswitch endfor if (! ((numel (w) <= 2) && (rows (w) == 1 || columns (w) == 1))) error ("butter: frequency must be given as WC or [WL, WH]"); elseif ((numel (w) == 2) && (w(2) <= w(1))) error ("butter: W(1) must be less than W(2)"); endif if (digital && ! all ((w >= 0) & (w <= 1))) error ("butter: all elements of W must be in the range [0,1]"); elseif (! digital && ! all (w >= 0)) error ("butter: all elements of W must be in the range [0,inf]"); endif ## Prewarp to the band edges to s plane if (digital) T = 2; # sampling frequency of 2 Hz w = 2 / T * tan (pi * w / T); endif ## Generate splane poles for the prototype Butterworth filter ## source: Kuc C = 1; ## default cutoff frequency pole = C * exp (1i * pi * (2 * [1:n] + n - 1) / (2 * n)); if (mod (n, 2) == 1) pole((n + 1) / 2) = -1; ## pure real value at exp(i*pi) endif zero = []; gain = C^n; ## splane frequency transform [zero, pole, gain] = sftrans (zero, pole, gain, w, stop); ## Use bilinear transform to convert poles to the z plane if (digital) [zero, pole, gain] = bilinear (zero, pole, gain, T); endif ## convert to the correct output form if (nargout == 2) a = real (gain * poly (zero)); b = real (poly (pole)); elseif (nargout == 3) a = zero; b = pole; c = gain; else ## output ss results [a, b, c, d] = zp2ss (zero, pole, gain); endif endfunction %!shared sf, sf2, off_db %! off_db = 0.5; %! ## Sampling frequency must be that high to make the low pass filters pass. %! sf = 6000; sf2 = sf/2; %! data=[sinetone(5,sf,10,1),sinetone(10,sf,10,1),sinetone(50,sf,10,1),sinetone(200,sf,10,1),sinetone(400,sf,10,1)]; %!test %! ## Test low pass order 1 with 3dB @ 50Hz %! data=[sinetone(5,sf,10,1),sinetone(10,sf,10,1),sinetone(50,sf,10,1),sinetone(200,sf,10,1),sinetone(400,sf,10,1)]; %! [b, a] = butter ( 1, 50 / sf2 ); %! filtered = filter ( b, a, data ); %! damp_db = 20 * log10 ( max ( filtered ( end - sf : end, : ) ) ); %! assert ( [ damp_db( 4 ) - damp_db( 5 ), damp_db( 1 : 3 ) ], [ 6 0 0 -3 ], off_db ) %!test %! ## Test low pass order 4 with 3dB @ 50Hz %! data=[sinetone(5,sf,10,1),sinetone(10,sf,10,1),sinetone(50,sf,10,1),sinetone(200,sf,10,1),sinetone(400,sf,10,1)]; %! [b, a] = butter ( 4, 50 / sf2 ); %! filtered = filter ( b, a, data ); %! damp_db = 20 * log10 ( max ( filtered ( end - sf : end, : ) ) ); %! assert ( [ damp_db( 4 ) - damp_db( 5 ), damp_db( 1 : 3 ) ], [ 24 0 0 -3 ], off_db ) %!test %! ## Test high pass order 1 with 3dB @ 50Hz %! data=[sinetone(5,sf,10,1),sinetone(10,sf,10,1),sinetone(50,sf,10,1),sinetone(200,sf,10,1),sinetone(400,sf,10,1)]; %! [b, a] = butter ( 1, 50 / sf2, "high" ); %! filtered = filter ( b, a, data ); %! damp_db = 20 * log10 ( max ( filtered ( end - sf : end, : ) ) ); %! assert ( [ damp_db( 2 ) - damp_db( 1 ), damp_db( 3 : end ) ], [ 6 -3 0 0 ], off_db ) %!test %! ## Test high pass order 4 with 3dB @ 50Hz %! data=[sinetone(5,sf,10,1),sinetone(10,sf,10,1),sinetone(50,sf,10,1),sinetone(200,sf,10,1),sinetone(400,sf,10,1)]; %! [b, a] = butter ( 4, 50 / sf2, "high" ); %! filtered = filter ( b, a, data ); %! damp_db = 20 * log10 ( max ( filtered ( end - sf : end, : ) ) ); %! assert ( [ damp_db( 2 ) - damp_db( 1 ), damp_db( 3 : end ) ], [ 24 -3 0 0 ], off_db ) %% Test input validation %!error [a, b] = butter () %!error [a, b] = butter (1) %!error [a, b] = butter (1, 2, 3, 4, 5) %!error [a, b] = butter (.5, .2) %!error [a, b] = butter (3, .2, "invalid") %!demo %! sf = 800; sf2 = sf/2; %! data=[[1;zeros(sf-1,1)],sinetone(25,sf,1,1),sinetone(50,sf,1,1),sinetone(100,sf,1,1)]; %! [b,a]=butter ( 1, 50 / sf2 ); %! filtered = filter(b,a,data); %! %! clf %! subplot ( columns ( filtered ), 1, 1) %! plot(filtered(:,1),";Impulse response;") %! subplot ( columns ( filtered ), 1, 2 ) %! plot(filtered(:,2),";25Hz response;") %! subplot ( columns ( filtered ), 1, 3 ) %! plot(filtered(:,3),";50Hz response;") %! subplot ( columns ( filtered ), 1, 4 ) %! plot(filtered(:,4),";100Hz response;") signal-1.3.2/inst/PaxHeaders.4544/filtfilt.m0000644000000000000000000000013212530736314015423 xustar0030 mtime=1432599756.806409466 30 atime=1432599756.806409466 30 ctime=1432599756.854411378 signal-1.3.2/inst/filtfilt.m0000644000000000000000000001014112530736314015741 0ustar00rootroot00000000000000## Copyright (C) 1999 Paul Kienzle ## Copyright (C) 2007 Francesco Potortì ## Copyright (C) 2008 Luca Citi ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## FIXME: My version seems to have similar quality to matlab, ## but both are pretty bad. They do remove gross lag errors, though. function y = filtfilt(b, a, x) if (nargin != 3) print_usage; endif rotate = (size(x,1)==1); if rotate, # a row vector x = x(:); # make it a column vector endif lx = size(x,1); a = a(:).'; b = b(:).'; lb = length(b); la = length(a); n = max(lb, la); lrefl = 3 * (n - 1); if la < n, a(n) = 0; endif if lb < n, b(n) = 0; endif ## Compute a the initial state taking inspiration from ## Likhterov & Kopeika, 2003. "Hardware-efficient technique for ## minimizing startup transients in Direct Form II digital filters" kdc = sum(b) / sum(a); if (abs(kdc) < inf) # neither NaN nor +/- Inf si = fliplr(cumsum(fliplr(b - kdc * a))); else si = zeros(size(a)); # fall back to zero initialization endif si(1) = []; for (c = 1:size(x,2)) # filter all columns, one by one v = [2*x(1,c)-x((lrefl+1):-1:2,c); x(:,c); 2*x(end,c)-x((end-1):-1:end-lrefl,c)]; # a column vector ## Do forward and reverse filtering v = filter(b,a,v,si*v(1)); # forward filter v = flipud(filter(b,a,flipud(v),si*v(end))); # reverse filter y(:,c) = v((lrefl+1):(lx+lrefl)); endfor if (rotate) # x was a row vector y = rot90(y); # rotate it back endif endfunction %!error filtfilt (); %!error filtfilt (1, 2, 3, 4); %!test %! randn('state',0); %! r = randn(1,200); %! [b,a] = butter(10, [.2, .25]); %! yfb = filtfilt(b, a, r); %! assert (size(r), size(yfb)); %! assert (mean(abs(yfb)) < 1e3); %! assert (mean(abs(yfb)) < mean(abs(r))); %! ybf = fliplr(filtfilt(b, a, fliplr(r))); %! assert (mean(abs(ybf)) < 1e3); %! assert (mean(abs(ybf)) < mean(abs(r))); %!test %! randn('state',0); %! r = randn(1,1000); %! s = 10 * sin(pi * 4e-2 * (1:length(r))); %! [b,a] = cheby1(2, .5, [4e-4 8e-2]); %! y = filtfilt(b, a, r+s); %! assert (size(r), size(y)); %! assert (mean(abs(y)) < 1e3); %! assert (corr(s(250:750), y(250:750)) > .95) %! [b,a] = butter(2, [4e-4 8e-2]); %! yb = filtfilt(b, a, r+s); %! assert (mean(abs(yb)) < 1e3); %! assert (corr(y, yb) > .99) %!test %! randn('state',0); %! r = randn(1,1000); %! s = 10 * sin(pi * 4e-2 * (1:length(r))); %! [b,a] = butter(2, [4e-4 8e-2]); %! y = filtfilt(b, a, [r.' s.']); %! yr = filtfilt(b, a, r); %! ys = filtfilt(b, a, s); %! assert (y, [yr.' ys.']); %! y2 = filtfilt(b.', a.', [r.' s.']); %! assert (y, y2); signal-1.3.2/inst/PaxHeaders.4544/welchwin.m0000644000000000000000000000013212530736314015426 xustar0030 mtime=1432599756.838410741 30 atime=1432599756.838410741 30 ctime=1432599756.854411378 signal-1.3.2/inst/welchwin.m0000644000000000000000000000731712530736314015757 0ustar00rootroot00000000000000## Copyright (C) 2007 Muthiah Annamalai ## Copyright (C) 2008-2009 Mike Gross ## Copyright (C) 2008-2009 Peter V. Lanspeary ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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}. ## ## @seealso{blackman, kaiser} ## @end deftypefn function w = welchwin (m, opt) if (nargin < 1 || nargin > 2) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("welchwin: M must be a positive integer"); endif N = (m - 1) / 2; mmin = 3; if (nargin == 2) switch (opt) case "periodic" N = m / 2; mmin = 2; case "symmetric" N = (m - 1) / 2; otherwise error ("welchwin: window type must be either \"periodic\" or \"symmetric\""); endswitch endif ## Periodic window is not properly defined for m < 2. ## Symmetric window is not properly defined for m < 3. if (m < mmin) error ("welchwin: M must be an integer greater than %d", mmin); endif n = [0:m-1]'; w = 1 - ((n-N)./N).^2; endfunction %!demo %! m = 32; %! t = [0:m-1]; %! printf ("Graph: single period of "); %! printf ("%d-point periodic (blue) and symmetric (red) windows\n", m); %! xp = welchwin (m, "periodic"); %! xs = welchwin (m, "symmetric"); %! plot (t, xp, "b", t, xs, "r") %!demo %! m = 32; %! t = [0:4*m-1]; %! printf ("Graph: 4 periods of "); %! printf ("%d-point periodic (blue) and symmetric (red) windows\n", m); %! xp = welchwin (m, "periodic"); %! xs = welchwin (m, "symmetric"); %! xp2 = repmat (xp, 4, 1); %! xs2 = repmat (xs, 4, 1); %! plot (t, xp2, "b", t, xs2, "r") %!demo %! m = 32; %! n = 512; %! xp = welchwin (m, "periodic"); %! s = fftshift (max (1e-2, abs (fft (postpad (xp, n))))); %! f = [-0.5:1/n:0.5-1/n]; %! printf ("%dx null-padded, power spectrum of %d-point window\n", n/m, m); %! semilogy (f, s) %!assert (welchwin (3), [0; 1; 0]); %!assert (welchwin (15), flipud (welchwin (15))); %!assert (welchwin (16), flipud (welchwin (16))); %!assert (welchwin (15), welchwin (15, "symmetric")); %!assert (welchwin (16)(1:15), welchwin (15, "periodic")); %% Test input validation %!error welchwin () %!error welchwin (0.5) %!error welchwin (-1) %!error welchwin (ones (1, 4)) %!error welchwin (1, 2, 3) %!error welchwin (1, "invalid") signal-1.3.2/inst/PaxHeaders.4544/findpeaks.m0000644000000000000000000000013212530736314015552 xustar0030 mtime=1432599756.806409466 30 atime=1432599756.806409466 30 ctime=1432599756.854411378 signal-1.3.2/inst/findpeaks.m0000644000000000000000000002757612530736314016114 0ustar00rootroot00000000000000## Copyright (c) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, see . ## -*- texinfo -*- ## @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 intercal here 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 crosses the @asis{"baseline"} value. The ## width of the peak is calculated by @command{diff(roots)}. ## @end table ## ## This function accepts property-value pair given in the list below: ## ## @table @asis ## ## @item "MinPeakHeight" ## Minimum peak height (positive scalar). Only peaks that exceed this ## value will be returned. For data taking positive and negative values ## use the option "DoubleSided". Default value @code{2*std (abs (detrend ## (data,0)))}. ## ## @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. ## Default value 4. ## ## @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 neighborhood size is equal to the value of ## @asis{"MinPeakDistance"}. The width is evaluated at the half height ## of the peak with baseline at "MinPeakHeight". Default value 2. ## ## @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 function [pks idx varargout] = findpeaks (data, varargin) if (nargin < 1) print_usage (); endif if (! (isvector (data) && numel (data) >= 3)) error ("findpeaks:InvalidArgument", "findpeaks: DATA must be a vector of at least 3 elements"); endif transpose = (rows (data) == 1); if (transpose) data = data.'; endif ## --- Parse arguments --- # __data__ = abs (detrend (data, 0)); posscal = @(x) isscalar (x) && x >= 0; parser = inputParser (); parser.FunctionName = "findpeaks"; ## FIXME: inputParser was first implemented in the general package in the ## old @class type. This allowed for a very similar interface to ## Matlab but not quite equal. classdef was then implemented in ## Octave 4.0 release, which enabled inputParser to be implemented ## properly. However, this causes problem because we don't know ## what implementation may be running. A new version of the general ## package is being released to avoid the two implementations to ## co-exist. ## ## To keep supporting older octave versions, we have an alternative ## path that avoids inputParser. And if inputParser is available, ## we check what implementation is is, and act accordingly. ## Note that in Octave 4.0, inputParser is classdef and Octave behaves ## weird for it. which ("inputParser") will return empty (thinks its a ## builtin function). if (exist ("inputParser") == 2 && isempty (strfind (which ("inputParser"), ["@inputParser" filesep "inputParser.m"]))) ## making use of classdef's inputParser .. parser.addParamValue ("MinPeakHeight", 2*std (__data__),posscal); parser.addParamValue ("MinPeakDistance", 4, posscal); parser.addParamValue ("MinPeakWidth", 2, posscal); parser.addSwitch ("DoubleSided"); parser.parse (varargin{:}); minH = parser.Results.MinPeakHeight; minD = parser.Results.MinPeakDistance; minW = parser.Results.MinPeakWidth; dSided = parser.Results.DoubleSided; else ## either old @inputParser or no inputParser at all... lvarargin = lower (varargin); ds = strcmpi (lvarargin, "DoubleSided"); if (any (ds)) dSided = true; lvarargin(ds) = []; else dSided = false; endif [~, minH, minD, minW] = parseparams (lvarargin, "minpeakheight", 2 * std (__data__), "minpeakdistance", 4, "minpeakwidth", 2); if (! posscal (minH)) error ("findpeaks: MinPeakHeight must be a positive scalar"); elseif (! posscal (minD)) error ("findpeaks: MinPeakDistance must be a positive scalar"); elseif (! posscal (minW)) error ("findpeaks: MinPeakWidth must be a positive scalar"); endif endif if (dSided) [data, __data__] = deal (__data__, data); elseif (min (data) < 0) error ("findpeaks:InvalidArgument", 'Data contains negative values. You may want to "DoubleSided" option'); endif ## Rough estimates of first and second derivative df1 = diff (data, 1)([1; (1:end)']); df2 = diff (data, 2)([1; 1; (1:end)']); ## check for changes of sign of 1st derivative and negativity of 2nd ## derivative. ## <= in 1st derivative includes the case of oversampled signals. idx = find (df1.*[df1(2:end); 0] <= 0 & [df2(2:end); 0] < 0); ## Get peaks that are beyond given height tf = data(idx) > minH; idx = idx(tf); ## sort according to magnitude [~, tmp] = sort (data(idx), "descend"); idx_s = idx(tmp); ## Treat peaks separated less than minD as one D = abs (bsxfun (@minus, idx_s, idx_s')); if (any (D(:) < minD)) i = 1; peak = cell (); node2visit = 1:size(D,1); visited = []; idx_pruned = idx_s; ## debug ## h = plot(1:length(data),data,"-",idx_s,data(idx_s),'.r',idx_s,data(idx_s),'.g'); ## set(h(3),"visible","off"); while (! isempty (node2visit)) d = D(node2visit(1),:); visited = [visited node2visit(1)]; node2visit(1) = []; neighs = setdiff (find (d < minD), visited); if (! isempty (neighs)) ## debug ## set(h(3),"xdata",idx_s(neighs),"ydata",data(idx_s(neighs)),"visible","on") ## pause(0.2) ## set(h(3),"visible","off"); idx_pruned = setdiff (idx_pruned, idx_s(neighs)); visited = [visited neighs]; node2visit = setdiff (node2visit, visited); ## debug ## set(h(2),"xdata",idx_pruned,"ydata",data(idx_pruned)) ## pause endif endwhile idx = idx_pruned; endif extra = struct ("parabol", [], "height", [], "baseline", [], "roots", []); ## Estimate widths of peaks and filter for: ## width smaller than given. ## wrong concavity. ## not high enough ## data at peak is lower than parabola by 1% if (minW > 0) ## debug ## h = plot(1:length(data),data,"-",idx,data(idx),'.r',... ## idx,data(idx),'og',idx,data(idx),'-m'); ## set(h(4),"linewidth",2) ## set(h(3:4),"visible","off"); idx_pruned = idx; n = numel (idx); np = numel (data); struct_count = 0; for i=1:n ind = (round (max(idx(i)-minD/2,1)) : ... round (min(idx(i)+minD/2,np)))'; pp = polyfit (ind, data(ind), 2); H = pp(3) - pp(2)^2/(4*pp(1)); ## debug ## x = linspace(ind(1)-1,ind(end)+1,10); ## set(h(4),"xdata",x,"ydata",polyval(pp,x),"visible","on") ## set(h(3),"xdata",ind,"ydata",data(ind),"visible","on") ## pause(0.2) ## set(h(3:4),"visible","off"); rz = roots ([pp(1:2) pp(3)-mean([H,minH])]); width = abs (diff (rz)); if (width < minW || pp(1) > 0 || H < minH || data(idx(i)) < 0.99*H) idx_pruned = setdiff (idx_pruned, idx(i)); elseif (nargout > 2) struct_count++; extra.parabol(struct_count).x = ind([1 end]); extra.parabol(struct_count).pp = pp; extra.roots(struct_count,1:2)= rz; extra.height(struct_count) = H; extra.baseline(struct_count) = mean ([H minH]); endif ## debug ## set(h(2),"xdata",idx_pruned,"ydata",data(idx_pruned)) ## pause(0.2) endfor idx = idx_pruned; endif if (dSided) pks = __data__(idx); else pks = data(idx); endif if (transpose) pks = pks.'; idx = idx.'; endif if (nargout() > 2) varargout{1} = extra; endif endfunction %!demo %! t = 2*pi*linspace(0,1,1024)'; %! y = sin(3.14*t) + 0.5*cos(6.09*t) + 0.1*sin(10.11*t+1/6) + 0.1*sin(15.3*t+1/3); %! %! data1 = abs(y); # Positive values %! [pks idx] = findpeaks(data1); %! %! data2 = y; # Double-sided %! [pks2 idx2] = findpeaks(data2,"DoubleSided"); %! [pks3 idx3] = findpeaks(data2,"DoubleSided","MinPeakHeight",0.5); %! %! subplot(1,2,1) %! plot(t,data1,t(idx),data1(idx),'.m') %! subplot(1,2,2) %! plot(t,data2,t(idx2),data2(idx2),".m;>2*std;",t(idx3),data2(idx3),"or;>0.1;") %! legend("Location","NorthOutside","Orientation","horizontal") %! %! #---------------------------------------------------------------------------- %! # Finding the peaks of smooth data is not a big deal! %!demo %! t = 2*pi*linspace(0,1,1024)'; %! y = sin(3.14*t) + 0.5*cos(6.09*t) + 0.1*sin(10.11*t+1/6) + 0.1*sin(15.3*t+1/3); %! %! data = abs(y + 0.1*randn(length(y),1)); # Positive values + noise %! [pks idx] = findpeaks(data,"MinPeakHeight",1); %! %! dt = t(2)-t(1); %! [pks2 idx2] = findpeaks(data,"MinPeakHeight",1,... %! "MinPeakDistance",round(0.5/dt)); %! %! subplot(1,2,1) %! plot(t,data,t(idx),data(idx),'.r') %! subplot(1,2,2) %! plot(t,data,t(idx2),data(idx2),'.r') %! %! #---------------------------------------------------------------------------- %! # Noisy data may need tuning of the parameters. In the 2nd example, %! # MinPeakDistance is used as a smoother of the peaks. %!assert (isempty (findpeaks ([1, 1, 1]))) %!assert (isempty (findpeaks ([1; 1; 1]))) ## Test for bug #45056 %!test %! ## Test input vector is an oversampled sinusoid with clipped peaks %! x = min (3, cos (2*pi*[0:8000] ./ 600) + 2.01); %! assert (! isempty (findpeaks (x))) %% Test input validation %!error findpeaks () %!error findpeaks (1) %!error findpeaks ([1, 2]) ## Failing test because we are not Matlab compatible %!xtest assert (findpeaks ([34 134 353 64 134 14 56 67 234 143 64 575 8657]), %! [353 134 234]) signal-1.3.2/inst/PaxHeaders.4544/zerocrossing.m0000644000000000000000000000012612530736314016340 xustar0028 mtime=1432599756.8424109 28 atime=1432599756.8424109 30 ctime=1432599756.854411378 signal-1.3.2/inst/zerocrossing.m0000644000000000000000000000430212530736314016655 0ustar00rootroot00000000000000## Copyright (C) 2008 Carlo de Falco ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## @seealso{fzero, roots} ## @end deftypefn function retval = zerocrossing (x,y) x = x(:);y = y(:); crossing_intervals = (y(1:end-1).*y(2:end) <= 0); left_ends = (x(1:end-1))(crossing_intervals); right_ends = (x(2:end))(crossing_intervals); left_vals = (y(1:end-1))(crossing_intervals); right_vals = (y(2:end))(crossing_intervals); mid_points = (left_ends+right_ends)/2; zero_intervals = find(left_vals==right_vals); retval1 = mid_points(zero_intervals); left_ends(zero_intervals) = []; right_ends(zero_intervals) = []; left_vals(zero_intervals) = []; right_vals(zero_intervals) = []; retval2=left_ends-(right_ends-left_ends).*left_vals./(right_vals-left_vals); retval = union(retval1,retval2); endfunction %!test %! x = linspace(0,1,100); %! y = rand(1,100)-0.5; %! x0= zerocrossing(x,y); %! y0 = interp1(x,y,x0); %! assert(norm(y0,inf), 0, 100*eps) %!test %! x = linspace(0,1,100); %! y = rand(1,100)-0.5; %! y(10:20) = 0; %! x0= zerocrossing(x,y); %! y0 = interp1(x,y,x0); %! assert(norm(y0,inf), 0, 100*eps) %!demo %! x = linspace(0,1,100); %! y = rand(1,100)-0.5; %! x0= zerocrossing(x,y); %! y0 = interp1(x,y,x0); %! plot(x,y,x0,y0,'x') %!demo %! x = linspace(0,1,100); %! y = rand(1,100)-0.5; %! y(10:20) = 0; %! x0= zerocrossing(x,y); %! y0 = interp1(x,y,x0); %! plot(x,y,x0,y0,'x') signal-1.3.2/inst/PaxHeaders.4544/fht.m0000644000000000000000000000013212530736314014367 xustar0030 mtime=1432599756.806409466 30 atime=1432599756.806409466 30 ctime=1432599756.854411378 signal-1.3.2/inst/fht.m0000644000000000000000000000414012530736314014707 0ustar00rootroot00000000000000## Copyright (C) 2008 Muthiah Annamalai ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## @seealso{ifht, fft} ## @end deftypefn function m = fht( d, n, dim ) if ( nargin < 1 ) print_usage(); endif if ( nargin == 3 ) Y = fft(d,n,dim); elseif ( nargin == 2 ) Y = fft(d,n); else Y = fft(d); endif m = real(Y) - imag(Y); ## -- Traditional -- ## N = length(d); ## for K = 1:N ## i = 0:N-1; ## t = 2*pi*(K-1).*i/N; ## ker = (cos(t) + sin(t)); ## val = dot(d,ker); ## m(K) = val; ## endfor endfunction %! %!assert( fht([1 2 3 4]),[10 -4 -2 0] ) %! signal-1.3.2/inst/PaxHeaders.4544/ifht.m0000644000000000000000000000013212530736314014540 xustar0030 mtime=1432599756.814409784 30 atime=1432599756.814409784 30 ctime=1432599756.854411378 signal-1.3.2/inst/ifht.m0000644000000000000000000000377412530736314015074 0ustar00rootroot00000000000000## Copyright (C) 2008 Muthiah Annamalai ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## @seealso{fht, fft} ## @end deftypefn function m = ifht( d, n, dim ) if ( nargin < 1 ) print_usage(); endif if ( nargin == 3 ) Y = ifft(d,n,dim); elseif ( nargin == 2 ) Y = ifft(d,n); else Y = ifft(d); endif m = real(Y) + imag(Y); ## -- Traditional -- ## N = length(d); ## for K = 1:N ## i = 0:N-1; ## t = (2*pi*(K-1).*i/N); ## ker = (cos(t) + sin(t)); ## val = dot(d,ker)./N; ## m(K) = val; ## endfor endfunction %!assert(ifht(fht(1:4)),[1 2 3 4]) signal-1.3.2/inst/PaxHeaders.4544/arburg.m0000644000000000000000000000013212530736314015070 xustar0030 mtime=1432599756.790408828 30 atime=1432599756.790408828 30 ctime=1432599756.854411378 signal-1.3.2/inst/arburg.m0000644000000000000000000002267312530736314015423 0ustar00rootroot00000000000000## Copyright (C) 2006 Peter V. Lanspeary ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## ## @seealso{ar_psd} ## @end deftypefn function varargout = arburg( x, poles, criterion ) ## ## Check arguments if ( nargin < 2 ) error( 'arburg(x,poles): Need at least 2 args.' ); elseif ( ~isvector(x) || length(x) < 3 ) error( 'arburg: arg 1 (x) must be vector of length >2.' ); elseif ( ~isscalar(poles) || ~isreal(poles) || fix(poles)~=poles || poles<=0.5) error( 'arburg: arg 2 (poles) must be positive integer.' ); elseif ( poles >= length(x)-2 ) ## lattice-filter algorithm requires "poles0 error( 'arburg: arg 2 (poles) must be less than length(x)-2.' ); elseif ( nargin>2 && ~isempty(criterion) && ... (~ischar(criterion) || size(criterion,1)~=1 ) ) error( 'arburg: arg 3 (criterion) must be string.' ); else ## ## Set the model-selection-criterion flags. ## is_AKICc, isa_KIC and is_corrected are short-circuit flags if ( nargin > 2 && ~isempty(criterion) ) is_AKICc = strcmp(criterion,'AKICc'); # AKICc isa_KIC = is_AKICc || strcmp(criterion,'KIC'); # KIC or AKICc is_corrected = is_AKICc || strcmp(criterion,'AICc'); # AKICc or AICc use_inf_crit = is_corrected || isa_KIC || strcmp(criterion,'AIC'); use_FPE = strcmp(criterion,'FPE'); if ( ~use_inf_crit && ~use_FPE ) error( 'arburg: value of arg 3 (criterion) not recognized' ); endif else use_inf_crit = 0; use_FPE = 0; endif ## ## f(n) = forward prediction error ## b(n) = backward prediction error ## Storage of f(n) and b(n) is a little tricky. Because f(n) is always ## combined with b(n-1), f(1) and b(N) are never used, and therefore are ## not stored. Not storing unused data makes the calculation of the ## reflection coefficient look much cleaner :) ## N.B. {initial v} = {error for zero-order model} = ## {zero-lag autocorrelation} = E(x*conj(x)) = x*x'/N ## E = expectation operator N = length(x); k = []; if ( size(x,1) > 1 ) # if x is column vector f = x(2:N); b = x(1:N-1); v = real(x'*x) / N; else # if x is row vector f = x(2:N).'; b = x(1:N-1).'; v = real(x*x') / N; endif ## new_crit/old_crit is the mode-selection criterion new_crit = abs(v); old_crit = 2 * new_crit; for p = 1:poles ## ## new reflection coeff = -2* E(f.conj(b)) / ( E(f^2)+E(b(^2) ) last_k= -2 * (b' * f) / ( f' * f + b' * b); ## Levinson-Durbin recursion for residual new_v = v * ( 1.0 - real(last_k * conj(last_k)) ); if ( p > 1 ) ## ## Apply the model-selection criterion and break out of loop if it ## increases (rather than decreases). ## Do it before we update the old model "a" and "v". ## ## * Information Criterion (AKICc, KIC, AICc, AIC) if ( use_inf_crit ) old_crit = new_crit; ## AKICc = log(new_v)+p/N/(N-p)+(3-(p+2)/N)*(p+1)/(N-p-2); ## KIC = log(new_v)+ 3 *(p+1)/N; ## AICc = log(new_v)+ 2 *(p+1)/(N-p-2); ## AIC = log(new_v)+ 2 *(p+1)/N; ## -- Calculate KIC, AICc & AIC by using is_AKICc, is_KIC and ## is_corrected to "short circuit" the AKICc calculation. ## The extra 4--12 scalar arithmetic ops should be quicker than ## doing if...elseif...elseif...elseif...elseif. new_crit = log(new_v) + is_AKICc*p/N/(N-p) + ... (2+isa_KIC-is_AKICc*(p+2)/N) * (p+1) / (N-is_corrected*(p+2)); if ( new_crit > old_crit ) break; endif ## ## (FPE) Final prediction error elseif ( use_FPE ) old_crit = new_crit; new_crit = new_v * (N+p+1)/(N-p-1); if ( new_crit > old_crit ) break; endif endif ## Update model "a" and "v". ## Use Levinson-Durbin recursion formula (for complex data). a = [ prev_a + last_k .* conj(prev_a(p-1:-1:1)) last_k ]; else # if( p==1 ) a = last_k; endif k = [ k; last_k ]; v = new_v; if ( p < poles ) prev_a = a; ## calculate new prediction errors (by recursion): ## f(p,n) = f(p-1,n) + k * b(p-1,n-1) n=2,3,...n ## b(p,n) = b(p-1,n-1) + conj(k) * f(p-1,n) n=2,3,...n ## remember f(p,1) is not stored, so don't calculate it; make f(p,2) ## the first element in f. b(p,n) isn't calculated either. nn = N-p; new_f = f(2:nn) + last_k * b(2:nn); b = b(1:nn-1) + conj(last_k) * f(1:nn-1); f = new_f; endif endfor varargout{1} = [1 a]; varargout{2} = v; if ( nargout>=3 ) varargout{3} = k; endif endif endfunction signal-1.3.2/inst/PaxHeaders.4544/firls.m0000644000000000000000000000013212530736314014725 xustar0030 mtime=1432599756.810409625 30 atime=1432599756.810409625 30 ctime=1432599756.854411378 signal-1.3.2/inst/firls.m0000644000000000000000000001047012530736314015250 0ustar00rootroot00000000000000## Copyright (C) 2006 Quentin Spencer ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function coef = firls(N, frequencies, pass, weight, str); if (nargin < 3 || nargin > 6) print_usage; elseif (nargin == 3) weight = ones (1, length(pass)/2); str = []; elseif (nargin == 4) if ischar (weight) str = weight; weight = ones (size (pass)); else str = []; endif endif if length (frequencies) ~= length (pass) error("F and A must have equal lengths."); elseif 2 * length (weight) ~= length (pass) error("W must contain one weight per band."); elseif ischar (str) error("This feature is implemented yet"); else N += mod (N, 2); M = N/2; w = kron (weight(:), [-1; 1]); omega = frequencies * pi; i1 = 1:2:length (omega); i2 = 2:2:length (omega); ## Generate the matrix Q ## As illustrated in the above-cited reference, the matrix can be ## expressed as the sum of a Hankel and Toeplitz matrix. A factor of ## 1/2 has been dropped and the final filter coefficients multiplied ## by 2 to compensate. cos_ints = [omega; sin((1:N)' * omega)]; q = [1, 1./(1:N)]' .* (cos_ints * w); Q = toeplitz (q(1:M+1)) + hankel (q(1:M+1), q(M+1:end)); ## The vector b is derived from solving the integral: ## ## _ w ## / 2 ## b = / W(w) D(w) cos(kw) dw ## k / w ## - 1 ## ## Since we assume that W(w) is constant over each band (if not, the ## computation of Q above would be considerably more complex), but ## D(w) is allowed to be a linear function, in general the function ## W(w) D(w) is linear. The computations below are derived from the ## fact that: ## _ ## / a ax + b ## / (ax + b) cos(nx) dx = --- cos (nx) + ------ sin(nx) ## / 2 n ## - n ## cos_ints2 = [omega(i1).^2 - omega(i2).^2; ... cos((1:M)' * omega(i2)) - cos((1:M)' * omega(i1))] ./ ... ([2, 1:M]' * (omega(i2) - omega(i1))); d = [-weight .* pass(i1); weight .* pass(i2)] (:); b = [1, 1./(1:M)]' .* ((kron (cos_ints2, [1, 1]) + cos_ints(1:M+1,:)) * d); ## Having computed the components Q and b of the matrix equation, ## solve for the filter coefficients. a = Q \ b; coef = [ a(end:-1:2); 2 * a(1); a(2:end) ]; endif endfunction signal-1.3.2/inst/PaxHeaders.4544/ncauer.m0000644000000000000000000000013212530736314015063 xustar0030 mtime=1432599756.822410103 30 atime=1432599756.822410103 30 ctime=1432599756.854411378 signal-1.3.2/inst/ncauer.m0000644000000000000000000000643312530736314015412 0ustar00rootroot00000000000000## Copyright (C) 2001 Paulo Neis ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## usage: [Zz, Zp, Zg] = ncauer(Rp, Rs, n) ## ## Analog prototype for Cauer filter. ## [z, p, g]=ncauer(Rp, Rs, ws) ## Rp = Passband ripple ## Rs = Stopband ripple ## Ws = Desired order ## ## 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. function [zer, pol, T0]=ncauer(Rp, Rs, n) ## Cutoff frequency = 1: wp=1; ## Stop band edge ws: ws=__ellip_ws(n, Rp, Rs); k=wp/ws; k1=sqrt(1-k^2); q0=(1/2)*((1-sqrt(k1))/(1+sqrt(k1))); q= q0 + 2*q0^5 + 15*q0^9 + 150*q0^13; #(....) D=(10^(0.1*Rs)-1)/(10^(0.1*Rp)-1); ## Filter order maybe this, but not used now: ## n=ceil(log10(16*D)/log10(1/q)) l=(1/(2*n))*log((10^(0.05*Rp)+1)/(10^(0.05*Rp)-1)); sig01=0; sig02=0; for m=0 : 30 sig01=sig01+(-1)^m * q^(m*(m+1)) * sinh((2*m+1)*l); endfor for m=1 : 30 sig02=sig02+(-1)^m * q^(m^2) * cosh(2*m*l); endfor sig0=abs((2*q^(1/4)*sig01)/(1+2*sig02)); w=sqrt((1+k*sig0^2)*(1+sig0^2/k)); ## if rem(n,2) r=(n-1)/2; else r=n/2; endif ## wi=zeros(1,r); for ii=1 : r if rem(n,2) mu=ii; else mu=ii-1/2; endif soma1=0; for m=0 : 30 soma1 = soma1 + 2*q^(1/4) * ((-1)^m * q^(m*(m+1)) * sin(((2*m+1)*pi*mu)/n)); endfor soma2=0; for m=1 : 30 soma2 = soma2 + 2*((-1)^m * q^(m^2) * cos((2*m*pi*mu)/n)); endfor wi(ii)=(soma1/(1+soma2)); endfor ## Vi=sqrt((1-(k.*(wi.^2))).*(1-(wi.^2)/k)); A0i=1./(wi.^2); sqrA0i=1./(wi); B0i=((sig0.*Vi).^2 + (w.*wi).^2)./((1+sig0^2.*wi.^2).^2); B1i=(2 * sig0.*Vi)./(1 + sig0^2 * wi.^2); ## Gain T0: if rem(n,2) T0=sig0*prod(B0i./A0i)*sqrt(ws); else T0=10^(-0.05*Rp)*prod(B0i./A0i); endif ## zeros: zer=[i*sqrA0i, -i*sqrA0i]; ## poles: pol=[(-2*sig0*Vi+2*i*wi.*w)./(2*(1+sig0^2*wi.^2)), (-2*sig0*Vi-2*i*wi.*w)./(2*(1+sig0^2*wi.^2))]; ## If n odd, there is a real pole -sig0: if rem(n,2) pol=[pol, -sig0]; endif ## pol=(sqrt(ws)).*pol; zer=(sqrt(ws)).*zer; endfunction ## usage: ws = __ellip_ws(n, rp, rs) ## Calculate the stop band edge for the Cauer filter. function ws=__ellip_ws(n, rp, rs) kl0 = ((10^(0.1*rp)-1)/(10^(0.1*rs)-1)); k0 = (1-kl0); int = ellipke([kl0 ; k0]); ql0 = int(1); q0 = int(2); x = n*ql0/q0; kl = fminbnd(@(y) __ellip_ws_min(y,x) ,eps, 1-eps); ws = sqrt(1/kl); endfunction ## usage: err = __ellip_ws_min(kl, x) function err=__ellip_ws_min(kl, x) int=ellipke([kl; 1-kl]); ql=int(1); q=int(2); err=abs((ql/q)-x); endfunction signal-1.3.2/inst/PaxHeaders.4544/wrev.m0000644000000000000000000000013212530736314014571 xustar0030 mtime=1432599756.838410741 30 atime=1432599756.838410741 30 ctime=1432599756.854411378 signal-1.3.2/inst/wrev.m0000644000000000000000000000210212530736314015105 0ustar00rootroot00000000000000## Copyright (C) 2008 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} wrev (@var{x}) ## Reverse the order of the element of the vector @var{x}. ## @seealso{flipud, fliplr} ## @end deftypefn function y = wrev(x) if (nargin < 1|| nargin > 1); print_usage; endif if(~isvector(x)) error('x must be a vector'); endif l = length(x); k = 0:l-1; y = x(l-k); endfunction signal-1.3.2/inst/PaxHeaders.4544/gausswin.m0000644000000000000000000000013212530736314015446 xustar0030 mtime=1432599756.810409625 30 atime=1432599756.810409625 30 ctime=1432599756.854411378 signal-1.3.2/inst/gausswin.m0000644000000000000000000000320512530736314015767 0ustar00rootroot00000000000000## Copyright (C) 1999 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function w = gausswin (m, a) if (nargin < 1 || nargin > 2) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("gausswin: M must be a positive integer"); elseif (nargin == 1) a = 2.5; endif w = exp ( -0.5 * ( a/m * [ -(m-1) : 2 : m-1 ]' ) .^ 2 ); endfunction %!assert (gausswin (1), 1) %% Test input validation %!error gausswin () %!error gausswin (0.5) %!error gausswin (-1) %!error gausswin (ones (1, 4)) %!error gausswin (1, 2, 3) signal-1.3.2/inst/PaxHeaders.4544/cceps.m0000644000000000000000000000013212530736314014703 xustar0030 mtime=1432599756.794408987 30 atime=1432599756.794408987 30 ctime=1432599756.854411378 signal-1.3.2/inst/cceps.m0000644000000000000000000000415512530736314015231 0ustar00rootroot00000000000000## Copyright (C) 1994 Dept of Probability Theory and Statistics TU Wien ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## Author: Andreas Weingessel ## Apr 1, 1994 ## Last modified by AW on Nov 8, 1994 function cep = cceps (x, c) if (nargin == 1) c = 0; elseif (nargin != 2) print_usage; endif [nr, nc] = size (x); if (nc != 1) if (nr == 1) x = x'; nr = nc; else error ("cceps: x must be a vector"); endif endif bad_signal_message = ["cceps: bad signal x, ", ... "some Fourier coefficients are zero."]; F = fft (x); if (min (abs (F)) == 0) error (bad_signal_message); endif ## determine if correction necessary half = fix (nr / 2); cor = 0; if (2 * half == nr) cor = (c && (real (F (half + 1)) < 0)); if (cor) F = fft (x(1:nr-1)) if (min (abs (F)) == 0) error (bad_signal_message); endif endif endif cep = fftshift (ifft (log (F))); ## make result real if (c) cep = real (cep); if (cor) ## make cepstrum of same length as input vector cep (nr) = 0; endif endif endfunction signal-1.3.2/inst/PaxHeaders.4544/private0000644000000000000000000000013212530736314015025 xustar0030 mtime=1432599756.826410262 30 atime=1432599756.854411378 30 ctime=1432599756.854411378 signal-1.3.2/inst/private/0000755000000000000000000000000012530736314015423 5ustar00rootroot00000000000000signal-1.3.2/inst/private/PaxHeaders.4544/polyrev.m0000644000000000000000000000013212530736314016760 xustar0030 mtime=1432599756.826410262 30 atime=1432599756.826410262 30 ctime=1432599756.854411378 signal-1.3.2/inst/private/polyrev.m0000644000000000000000000000214312530736314017301 0ustar00rootroot00000000000000## Copyright (C) 2007 R.G.H. Eschauzier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{p_out} =} polyrev (@var{p_in}) ## Undocumented internal function. This function is used by the impinvar ## and invimpinvar functions in the signal package. ## @end deftypefn ## Adapted by Carnë Draug on 2011 ## Reverse the coefficients of a polynomial function p_out = polyrev (p_in) p_out = p_in(end:-1:1); endfunction signal-1.3.2/inst/private/PaxHeaders.4544/__fwht_opts__.m0000644000000000000000000000013212530736314020071 xustar0030 mtime=1432599756.822410103 30 atime=1432599756.822410103 30 ctime=1432599756.854411378 signal-1.3.2/inst/private/__fwht_opts__.m0000644000000000000000000000452312530736314020416 0ustar00rootroot00000000000000## Copyright (C) 2013 Mike Miller ## ## This program is free software: you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation, either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{y}, @var{len}] =} __fwht_opts__ (@var{caller}, @var{x}, @var{n}, @var{order}) ## Undocumented internal function. ## @end deftypefn ## Author: Mike Miller function [y, len] = __fwht_opts__ (caller, x, n, order) if (nargin < 1) print_usage (); elseif (nargin != 4) print_usage (caller); endif [nr, nc] = size (x); if (isempty (n)) if (nr == 1) n = 2^nextpow2 (nc); else n = 2^nextpow2 (nr); endif elseif (!(isscalar (n) && n == fix (n) && n > 0)) error ("%s: N must be a positive scalar", caller); else f = log2(n); if (f != fix (f)) error ("%s: N must be a power of 2", caller); endif endif if (isempty (order)) order = "sequency"; endif if (!(strncmp (order, "dyadic", 6) || strncmp (order, "hadamard", 8) || strncmp (order, "sequency", 8))) error ("%s: invalid order option", caller); endif if (nr == 1) nc = n; x = x(:); else nr = n; endif ## Zero-based index for normal Hadamard ordering idx = 0:n-1; ## Gray code permutation of index for alternate orderings idx_bin = dec2bin (idx) - "0"; idx_bin_a = idx_bin(:,1:end-1); idx_bin_b = idx_bin(:,2:end); idx_bin(:,2:end) = mod (idx_bin_a + idx_bin_b, 2); idx_bin = char (idx_bin + "0"); if (strncmp (order, "dyadic", 6)) idx = bin2dec (fliplr (dec2bin (idx))) + 1; elseif (strncmp (order, "sequency", 8)) idx = bin2dec (fliplr (idx_bin)) + 1; else idx += 1; endif len = n; x = postpad (x, len); if (len < 2) y = x; else y = __fwht__ (x); endif y = reshape (y(idx,:), nr, nc); endfunction signal-1.3.2/inst/private/PaxHeaders.4544/inv_residue.m0000644000000000000000000000013212530736314017574 xustar0030 mtime=1432599756.826410262 30 atime=1432599756.826410262 30 ctime=1432599756.854411378 signal-1.3.2/inst/private/inv_residue.m0000644000000000000000000000443312530736314020121 0ustar00rootroot00000000000000## Copyright (C) 2007 R.G.H. Eschauzier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{b_out}, @var{a_out}] =} inv_residue (@var{r_in}, @var{p_in}, @var{k_in}, @var{tol}) ## Undocumented internal function. This function is used by the impinvar ## and invimpinvar functions in the signal package. ## @end deftypefn ## Adapted by Carnë Draug on 2011 ## Inverse of Octave residue function function [b_out, a_out] = inv_residue(r_in, p_in, k_in, tol) n = length(r_in); # Number of poles/residues k = 0; # Capture constant term if (length(k_in)==1) # A single direct term (order N = order D) k = k_in(1); # Capture constant term elseif (length(k_in)>1) # Greater than one means non-physical system error("Order numerator > order denominator"); endif a_out = poly(p_in); b_out = zeros(1,n+1); b_out += k*a_out; # Constant term: add k times denominator to numerator i=1; while (i<=n) term = [1 -p_in(i)]; # Term to be factored out p = r_in(i)*deconv(a_out,term); # Residue times resulting polynomial p = prepad(p, n+1, 0, 2); # Pad for proper length b_out += p; m = 1; mterm = term; first_pole = p_in(i); while (i ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{b} =} h1_z_deriv (@var{n}, @var{p}, @var{ts}) ## Undocumented internal function. This function is used by the impinvar ## and invimpinvar functions in the signal package. ## @end deftypefn ## Adapted by Carnë Draug on 2011 ## Find {-zd/dz}^n*H1(z). I.e., first differentiate, then multiply by -z, then differentiate, etc. ## The result is (ts^(n+1))*(b(1)*p/(z-p)^1 + b(2)*p^2/(z-p)^2 + b(n+1)*p^(n+1)/(z-p)^(n+1)). ## Works for n>0. function b = h1_z_deriv(n, p, ts) ## Build the vector d that holds coefficients for all the derivatives of H1(z) ## The results reads d(n)*z^(1)*(d/dz)^(1)*H1(z) + d(n-1)*z^(2)*(d/dz)^(2)*H1(z) +...+ d(1)*z^(n)*(d/dz)^(n)*H1(z) d = (-1)^n; # Vector with the derivatives of H1(z) for i= (1:n-1) d = [d 0]; # Shift result right (multiply by -z) d += prepad(polyder(d), i+1, 0, 2); # Add the derivative endfor ## Build output vector b = zeros (1, n + 1); for i = (1:n) b += d(i) * prepad(h1_deriv(n-i+1), n+1, 0, 2); endfor b *= ts^(n+1)/factorial(n); ## Multiply coefficients with p^i, where i is the index of the coeff. b.*=p.^(n+1:-1:1); endfunction ## Find (z^n)*(d/dz)^n*H1(z), where H1(z)=ts*z/(z-p), ts=sampling period, ## p=exp(sm*ts) and sm is the s-domain pole with multiplicity n+1. ## The result is (ts^(n+1))*(b(1)*p/(z-p)^1 + b(2)*p^2/(z-p)^2 + b(n+1)*p^(n+1)/(z-p)^(n+1)), ## where b(i) is the binomial coefficient bincoeff(n,i) times n!. Works for n>0. function b = h1_deriv(n) b = factorial(n)*bincoeff(n,0:n); # Binomial coefficients: [1], [1 1], [1 2 1], [1 3 3 1], etc. b *= (-1)^n; endfunction signal-1.3.2/inst/private/PaxHeaders.4544/to_real.m0000644000000000000000000000013212530736314016705 xustar0030 mtime=1432599756.826410262 30 atime=1432599756.826410262 30 ctime=1432599756.854411378 signal-1.3.2/inst/private/to_real.m0000644000000000000000000000216412530736314017231 0ustar00rootroot00000000000000## Copyright (C) 2007 R.G.H. Eschauzier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{p_out} =} to_real (@var{p_in}) ## Undocumented internal function. This function is used by the impinvar ## and invimpinvar functions in the signal package. ## @end deftypefn ## Adapted by Carnë Draug on 2011 ## Round complex number to nearest real number function p_out = to_real(p_in) p_out = abs(p_in) .* sign(real(p_in)); endfunction signal-1.3.2/inst/private/PaxHeaders.4544/validate_filter_bands.m0000644000000000000000000000013212530736314021565 xustar0030 mtime=1432599756.826410262 30 atime=1432599756.826410262 30 ctime=1432599756.854411378 signal-1.3.2/inst/private/validate_filter_bands.m0000644000000000000000000000407612530736314022115 0ustar00rootroot00000000000000## Copyright (C) 2014 Mike Miller ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} validate_filter_bands (@var{func}, @var{wp}, @var{ws}) ## Validate filter design frequency response bands. This is an internal ## convenience function used by @code{buttord}, @code{cheb1ord}, ## @code{cheb2ord}, @code{ellipord}. ## @end deftypefn function validate_filter_bands (func, wp, ws) if (nargin != 3) print_usage (); elseif (! ischar (func)) error ("validate_filter_bands: FUNC must be a string"); elseif (! (isvector (wp) && isvector (ws) && (numel (wp) == numel (ws)))) error ([func ": WP and WS must both be scalars or vectors of length 2\n"]); elseif (! ((numel (wp) == 1) || (numel (wp) == 2))) error ([func ": WP and WS must both be scalars or vectors of length 2\n"]); elseif (! (isreal (wp) && all (wp >= 0) && all (wp <= 1))) error ([func ": all elements of WP must be in the range [0,1]\n"]); elseif (! (isreal (ws) && all (ws >= 0) && all (ws <= 1))) error ([func ": all elements of WS must be in the range [0,1]\n"]); elseif ((numel (wp) == 2) && (wp(2) <= wp(1))) error ([func ": WP(1) must be less than WP(2)\n"]) elseif ((numel (ws) == 2) && (ws(2) <= ws(1))) error ([func ": WS(1) must be less than WS(2)\n"]) elseif ((numel (wp) == 2) && (all (wp > ws) || all (ws > wp))) error ([func ": WP must be contained by WS or WS must be contained by WP\n"]); endif endfunction signal-1.3.2/inst/PaxHeaders.4544/cheb2ord.m0000644000000000000000000000013212530736314015276 xustar0030 mtime=1432599756.798409147 30 atime=1432599756.798409147 30 ctime=1432599756.854411378 signal-1.3.2/inst/cheb2ord.m0000644000000000000000000001315412530736314015623 0ustar00rootroot00000000000000## Copyright (C) 2000 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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}, @var{wc}] =} 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} can be given as inputs to @code{cheby2}. ## ## 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. ## ## @seealso{buttord, cheb1ord, cheby2, ellipord} ## @end deftypefn function [n, Wc] = cheb2ord(Wp, Ws, Rp, Rs) if nargin != 4 print_usage; else validate_filter_bands ("cheb2ord", Wp, Ws); endif T = 2; ## returned frequency is the same as the input frequency Wc = Ws; ## warp the target frequencies according to the bilinear transform Ws = (2/T)*tan(pi*Ws./T); Wp = (2/T)*tan(pi*Wp./T); if (Wp(1) < Ws(1)) ## low pass if (length(Wp) == 1) Wa = Wp/Ws; else ## FIXME: Implement band reject filter type error ("cheb2ord: band reject is not yet implemented"); endif; else ## if high pass, reverse the sense of the test if (length(Wp) == 1) Wa = Ws/Wp; else ## band pass Wa=(Wp.^2 - Ws(1)*Ws(2))./(Wp*(Ws(1)-Ws(2))); endif; endif; Wa = min(abs(Wa)); ## compute minimum n which satisfies all band edge conditions stop_atten = 10^(abs(Rs)/10); pass_atten = 10^(abs(Rp)/10); n = ceil(acosh(sqrt((stop_atten-1)/(pass_atten-1)))/acosh(1/Wa)); endfunction %!demo %! Fs = 10000; %! [n, Wc] = cheb2ord (1000/(Fs/2), 1200/(Fs/2), 0.5, 29); %! %! subplot (221); %! plot ([0, 1000, 1000, 0, 0], [0, 0, -0.5, -0.5, 0], ";;"); %! hold on; %! grid; %! title("Pass band Wp=1000 Rp=0.0"); %! xlabel("Frequency (Hz)"); %! ylabel("Attenuation (dB)"); %! [b, a] = cheby2 (n, 29, Wc); %! [h, w] = freqz (b, a, [], Fs); %! plot (w, 20*log10(abs(h)), ";;"); %! axis ([ 0, 1500, -1, 0]); %! hold off; %! %! subplot (222); %! plot ([1200, Fs/2, Fs/2, 1200, 1200], [-29, -29, -500, -500, -29], ";;"); %! hold on; %! axis ([ 0, Fs/2, -250, 0]); %! title("Stop band Ws=1200 Rs=29"); %! xlabel("Frequency (Hz)"); %! ylabel("Attenuation (dB)"); %! grid; %! [b, a] = cheby2 (n, 29, Wc); %! [h, w] = freqz (b, a, [], Fs); %! plot (w, 20*log10(abs(h)), ";;"); %! hold off; %! %! subplot (223); %! plot ([0, 1000, 1000, 0, 0], [0, 0, -0.5, -0.5, 0], ";;"); %! hold on; %! axis ([ 800, 1010, -0.6, -0.0]); %! title("Pass band detail Wp=1000 Rp=0.5"); %! xlabel("Frequency (Hz)"); %! ylabel("Attenuation (dB)"); %! grid; %! [b, a] = cheby2 (n, 29, Wc); %! [h, w] = freqz (b, a, [800:1010], Fs); %! plot (w, 20*log10(abs(h)), "r;filter n;"); %! [b, a] = cheby2 (n-1, 29, Wc); %! [h, w] = freqz (b, a, [800:1010], Fs); %! plot (w, 20*log10(abs(h)), "b;filter n-1;"); %! [b, a] = cheby2 (n+1, 29, Wc); %! [h, w] = freqz (b, a, [800:1010], Fs); %! plot (w, 20*log10(abs(h)), "g;filter n+1;"); %! hold off; %! %! subplot (224); %! plot ([1200, Fs/2, Fs/2, 1200, 1200], [-29, -29, -500, -500, -29], ";;"); %! hold on; %! axis ([ 1190, 1210, -40, -20]); %! title("Stop band detail Wp=1200 Rp=29"); %! xlabel("Frequency (Hz)"); %! ylabel("Attenuation (dB)"); %! grid; %! [b, a] = cheby2 (n, 29, Wc); %! [h, w] = freqz (b, a, [1190:1210], Fs); %! plot (w, 20*log10(abs(h)), "r;filter n;"); %! [b, a] = cheby2 (n-1, 29, Wc); %! [h, w] = freqz (b, a, [1190:1210], Fs); %! plot (w, 20*log10(abs(h)), "b;filter n-1;"); %! [b, a] = cheby2 (n+1, 29, Wc); %! [h, w] = freqz (b, a, [1190:1210], Fs); %! plot (w, 20*log10(abs(h)), "g;filter n+1;"); %! hold off; %% Test case from demo %!assert (cheb2ord (0.2, 0.24, 0.5, 29), 8) %% Test input validation %!error cheb2ord () %!error cheb2ord (.1) %!error cheb2ord (.1, .2) %!error cheb2ord (.1, .2, 3) %!error cheb2ord (.1, .2, 3, 4, 5) %!error cheb2ord ([.1 .1], [.2 .2], 3, 4) %!error cheb2ord ([.1 .2], [.5 .6], 3, 4) %!error cheb2ord ([.1 .5], [.2 .6], 3, 4) signal-1.3.2/inst/PaxHeaders.4544/digitrevorder.m0000644000000000000000000000013212530736314016457 xustar0030 mtime=1432599756.802409306 30 atime=1432599756.802409306 30 ctime=1432599756.854411378 signal-1.3.2/inst/digitrevorder.m0000644000000000000000000000453512530736314017007 0ustar00rootroot00000000000000## Copyright (C) 2013 Mike Miller ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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}. ## @seealso{bitrevorder, fft, ifft} ## @end deftypefn function [y, i] = digitrevorder (x, r) if (nargin < 1 || nargin > 2) print_usage (); elseif (! isvector (x)) error ("digitrevorder: X must be a vector"); elseif (!(isscalar (r) && r == fix (r) && r >= 2 && r <= 36)) error ("digitrevorder: R must be an integer between 2 and 36"); else tmp = log (numel (x)) / log (r); if (fix (tmp) != tmp) error ("digitrevorder: X must have length equal to an integer power of %d", r); endif endif old_ind = 0:numel (x) - 1; new_ind = base2dec (fliplr (dec2base (old_ind, r)), r); i = new_ind + 1; y(old_ind + 1) = x(i); if (columns (x) == 1) y = y'; else i = i'; endif endfunction %!assert (digitrevorder (0, 2), 0); %!assert (digitrevorder (0, 36), 0); %!assert (digitrevorder (0:3, 4), 0:3); %!assert (digitrevorder ([0:3]', 4), [0:3]'); %!assert (digitrevorder (0:7, 2), [0 4 2 6 1 5 3 7]); %!assert (digitrevorder (0:15, 2), [0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15]); %!assert (digitrevorder (0:15, 4), [0 4 8 12 1 5 9 13 2 6 10 14 3 7 11 15]); %% Test input validation %!error digitrevorder (); %!error digitrevorder (1); %!error digitrevorder (1, 2, 3); %!error digitrevorder ([], 1); %!error digitrevorder ([], 37); %!error digitrevorder (0:3, 8); signal-1.3.2/inst/PaxHeaders.4544/czt.m0000644000000000000000000000013212530736314014406 xustar0030 mtime=1432599756.802409306 30 atime=1432599756.802409306 30 ctime=1432599756.854411378 signal-1.3.2/inst/czt.m0000644000000000000000000000654612530736314014742 0ustar00rootroot00000000000000## Copyright (C) 2004 Daniel Gunyan ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## Algorithm (based on Oppenheim and Schafer, "Discrete-Time Signal ## Processing", pp. 623-628): ## make chirp of length -N+1 to max(N-1,M-1) ## chirp => w^([-N+1:max(N-1,M-1)]^2/2) ## multiply x by chirped a and by N-elements of chirp, and call it g ## convolve g with inverse chirp, and call it gg ## pad ffts so that multiplication works ## ifft(fft(g)*fft(1/chirp)) ## multiply gg by M-elements of chirp and call it done function y = czt(x, m, w, a) if nargin < 1 || nargin > 4, print_usage; endif [row, col] = size(x); if row == 1, x = x(:); col = 1; endif if nargin < 2 || isempty(m), m = length(x(:,1)); endif if length(m) > 1, error("czt: m must be a single element\n"); endif if nargin < 3 || isempty(w), w = exp(-2*j*pi/m); endif if nargin < 4 || isempty(a), a = 1; endif if length(w) > 1, error("czt: w must be a single element\n"); endif if length(a) > 1, error("czt: a must be a single element\n"); endif ## indexing to make the statements a little more compact n = length(x(:,1)); N = [0:n-1]'+n; NM = [-(n-1):(m-1)]'+n; M = [0:m-1]'+n; nfft = 2^nextpow2(n+m-1); # fft pad W2 = w.^(([-(n-1):max(m-1,n-1)]'.^2)/2); # chirp for idx = 1:col fg = fft(x(:,idx).*(a.^-(N-n)).*W2(N), nfft); fw = fft(1./W2(NM), nfft); gg = ifft(fg.*fw, nfft); y(:,idx) = gg(M).*W2(M); endfor if row == 1, y = y.'; endif endfunction %!shared x %! x = [1,2,4,1,2,3,5,2,3,5,6,7,8,4,3,6,3,2,5,1]; %!assert(fft(x),czt(x),10000*eps); %!assert(fft(x'),czt(x'),10000*eps); %!assert(fft([x',x']),czt([x',x']),10000*eps); signal-1.3.2/inst/PaxHeaders.4544/fwht.m0000644000000000000000000000013212530736314014556 xustar0030 mtime=1432599756.810409625 30 atime=1432599756.810409625 30 ctime=1432599756.854411378 signal-1.3.2/inst/fwht.m0000644000000000000000000000544012530736314015102 0ustar00rootroot00000000000000## Copyright (C) 2013 Mike Miller ## ## This program is free software: you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation, either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## ## @seealso{ifwht} ## @end deftypefn ## Author: Mike Miller function y = fwht (x, n, order) if (nargin < 1 || nargin > 3) print_usage (); elseif (nargin == 1) n = order = []; elseif (nargin == 2) order = []; endif [y, n] = __fwht_opts__ ("fwht", x, n, order); y /= n; endfunction %!assert (isempty (fwht ([]))); %!assert (fwht (zeros (16)), zeros (16)); %!assert (fwht (ones (16, 1)), [1; (zeros (15, 1))]); %!assert (fwht (zeros (17, 1)), zeros (32, 1)); %!assert (fwht ([1 -1 1 -1 1 -1 1 -1]), [0 0 0 0 0 0 0 1]); %!test %! x = randi (16, 16); %! assert (ifwht (fwht (x)), x); %!test %! x = randi (16, 16); %! assert (ifwht (fwht (x, [], "sequency"), [], "sequency"), x); %!test %! x = randi (16, 16); %! assert (ifwht (fwht (x, [], "hadamard"), [], "hadamard"), x); %!test %! x = randi (16, 16); %! assert (ifwht (fwht (x, [], "dyadic"), [], "dyadic"), x); %% Test input validation %!error fwht (); %!error fwht (1, 2, 3, 4); %!error fwht (0, 0); %!error fwht (0, 5); %!error fwht (0, [], "invalid"); signal-1.3.2/inst/PaxHeaders.4544/dctmtx.m0000644000000000000000000000013212530736314015111 xustar0030 mtime=1432599756.802409306 30 atime=1432599756.802409306 30 ctime=1432599756.854411378 signal-1.3.2/inst/dctmtx.m0000644000000000000000000000333612530736314015437 0ustar00rootroot00000000000000## Copyright (C) 2001 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## ## @seealso{dct, idct, dct2, idct2} ## @end deftypefn function T = dctmtx(n) if nargin != 1 print_usage; endif if n > 1 T = [ sqrt(1/n)*ones(1,n) ; ... sqrt(2/n)*cos((pi/2/n)*([1:n-1]'*[1:2:2*n])) ]; elseif n == 1 T = 1; else error ("dctmtx: n must be at least 1"); endif endfunction signal-1.3.2/inst/PaxHeaders.4544/gmonopuls.m0000644000000000000000000000013212530736314015631 xustar0030 mtime=1432599756.810409625 30 atime=1432599756.810409625 30 ctime=1432599756.854411378 signal-1.3.2/inst/gmonopuls.m0000644000000000000000000000206112530736314016151 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} gmonopuls (@var{t},@var{fc}) ## Return the gaussian monopulse. ## @end deftypefn function y = gmonopuls(t, fc = 1e3) if (nargin<1 || nargin > 2), print_usage; endif if fc < 0 , error("fc must be positive"); endif y = 2*sqrt(exp(1)) .* pi.*t.*fc.*exp(-2 .* (pi.*t.*fc).^2); endfunction signal-1.3.2/inst/PaxHeaders.4544/sos2zp.m0000644000000000000000000000013212530736314015046 xustar0030 mtime=1432599756.834410581 30 atime=1432599756.834410581 30 ctime=1432599756.854411378 signal-1.3.2/inst/sos2zp.m0000644000000000000000000000610312530736314015367 0ustar00rootroot00000000000000## Copyright (C) 2005 Julius O. Smith III ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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}.' = [1 a1 a2]} for ## section 1, etc. The b0 entry must be nonzero for each section. ## 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 = [i; -i; 0; 0] ## @result{} p = [0.9, -0.9, 0.7i, -0.7i] ## @result{} k = 1 ## @end example ## ## @seealso{zp2sos, sos2tf, tf2sos, zp2tf, tf2zp} ## @end deftypefn function [z,p,k] = sos2zp (sos, g = 1) if (nargin < 1 || nargin > 2) print_usage; endif gains = sos(:,1); # All b0 coeffs k = prod(gains)*g; # pole-zero gain if k==0, error('sos2zp: one or more section gains is zero'); endif sos(:,1:3) = sos(:,1:3)./ [gains gains gains]; [N,m] = size(sos); if m~=6, error('sos2zp: sos matrix should be N by 6'); endif z = zeros(2*N,1); p = zeros(2*N,1); for i=1:N ndx = [2*i-1:2*i]; zi = roots(sos(i,1:3)); z(ndx) = zi; pi = roots(sos(i,4:6)); p(ndx) = pi; endfor endfunction %!test %! b1t=[1 2 3]; a1t=[1 .2 .3]; %! b2t=[4 5 6]; a2t=[1 .4 .5]; %! sos=[b1t a1t; b2t a2t]; %! z = [-1-1.41421356237310i;-1+1.41421356237310i;... %! -0.625-1.05326872164704i;-0.625+1.05326872164704i]; %! p = [-0.2-0.678232998312527i;-0.2+0.678232998312527i;... %! -0.1-0.538516480713450i;-0.1+0.538516480713450i]; %! k = 4; %! [z2,p2,k2] = sos2zp(sos,1); %! assert({cplxpair(z2),cplxpair(p2),k2},{z,p,k},100*eps); signal-1.3.2/inst/PaxHeaders.4544/morlet.m0000644000000000000000000000013212530736314015110 xustar0030 mtime=1432599756.822410103 30 atime=1432599756.822410103 30 ctime=1432599756.854411378 signal-1.3.2/inst/morlet.m0000644000000000000000000000210412530736314015426 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{psi}, @var{x}] =} morlet (@var{lb}, @var{ub}, @var{n}) ## Compute the Morlet wavelet. ## @end deftypefn function [psi,x] = morlet(lb,ub,n) if (nargin < 3); print_usage; endif if (n <= 0) error("n must be strictly positive"); endif x = linspace(lb,ub,n); psi = cos(5.*x) .* exp(-x.^2/2) ; endfunction signal-1.3.2/inst/PaxHeaders.4544/impinvar.m0000644000000000000000000000013212530736314015433 xustar0030 mtime=1432599756.814409784 30 atime=1432599756.814409784 30 ctime=1432599756.854411378 signal-1.3.2/inst/impinvar.m0000644000000000000000000001242512530736314015760 0ustar00rootroot00000000000000## Copyright (c) 2007 R.G.H. Eschauzier ## Copyright (c) 2011 Carnë Draug ## Copyright (c) 2011 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## ## @seealso{bilinear, invimpinvar} ## @end deftypefn function [b_out, a_out] = impinvar (b_in, a_in, fs = 1, tol = 0.0001) if (nargin <2) print_usage; endif ## to be compatible with the matlab implementation where an empty vector can ## be used to get the default if (isempty(fs)) ts = 1; else ts = 1/fs; # we should be using sampling frequencies to be compatible with Matlab endif [r_in, p_in, k_in] = residue(b_in, a_in); # partial fraction expansion n = length(r_in); # Number of poles/residues if (length(k_in)>0) # Greater than zero means we cannot do impulse invariance error("Order numerator >= order denominator"); endif r_out = zeros(1,n); # Residues of H(z) p_out = zeros(1,n); # Poles of H(z) k_out = 0; # Constant term of H(z) i=1; while (i<=n) m = 1; first_pole = p_in(i); # Pole in the s-domain while (i ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function [Sz, Sp, Sg] = sftrans(Sz, Sp, Sg, W, stop) if (nargin != 5) print_usage; endif C = 1; p = length(Sp); z = length(Sz); if z > p || p == 0 error("sftrans: must have at least as many poles as zeros in s-plane"); endif if length(W)==2 Fl = W(1); Fh = W(2); if stop ## ---------------- ------------------------- ------------------------ ## 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 ## ---------------- ------------------------- ------------------------ if (isempty(Sz)) Sg = Sg * real (1./ prod(-Sp)); elseif (isempty(Sp)) Sg = Sg * real(prod(-Sz)); else Sg = Sg * real(prod(-Sz)/prod(-Sp)); endif b = (C*(Fh-Fl)/2)./Sp; Sp = [b+sqrt(b.^2-Fh*Fl), b-sqrt(b.^2-Fh*Fl)]; extend = [sqrt(-Fh*Fl), -sqrt(-Fh*Fl)]; if isempty(Sz) Sz = [extend(1+rem([1:2*p],2))]; else b = (C*(Fh-Fl)/2)./Sz; Sz = [b+sqrt(b.^2-Fh*Fl), b-sqrt(b.^2-Fh*Fl)]; if (p > z) Sz = [Sz, extend(1+rem([1:2*(p-z)],2))]; endif endif else ## ---------------- ------------------------- ------------------------ ## 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 ## ---------------- ------------------------- ------------------------ Sg = Sg * (C/(Fh-Fl))^(z-p); b = Sp*((Fh-Fl)/(2*C)); Sp = [b+sqrt(b.^2-Fh*Fl), b-sqrt(b.^2-Fh*Fl)]; if isempty(Sz) Sz = zeros(1,p); else b = Sz*((Fh-Fl)/(2*C)); Sz = [b+sqrt(b.^2-Fh*Fl), b-sqrt(b.^2-Fh*Fl)]; if (p>z) Sz = [Sz, zeros(1, (p-z))]; endif endif endif else Fc = W; if stop ## ---------------- ------------------------- ------------------------ ## High Pass zero: Fc C/x pole: Fc C/x ## S -> C Fc/S pole: 0 zero: 0 ## gain: -x gain: -1/x ## ---------------- ------------------------- ------------------------ if (isempty(Sz)) Sg = Sg * real (1./ prod(-Sp)); elseif (isempty(Sp)) Sg = Sg * real(prod(-Sz)); else Sg = Sg * real(prod(-Sz)/prod(-Sp)); endif Sp = C * Fc ./ Sp; if isempty(Sz) Sz = zeros(1,p); else Sz = [C * Fc ./ Sz]; if (p > z) Sz = [Sz, zeros(1,p-z)]; endif endif else ## ---------------- ------------------------- ------------------------ ## Low Pass zero: Fc x/C pole: Fc x/C ## S -> C S/Fc gain: C/Fc gain: Fc/C ## ---------------- ------------------------- ------------------------ Sg = Sg * (C/Fc)^(z-p); Sp = Fc * Sp / C; Sz = Fc * Sz / C; endif endif endfunction signal-1.3.2/inst/PaxHeaders.4544/ellipord.m0000644000000000000000000000013212530736314015420 xustar0030 mtime=1432599756.806409466 30 atime=1432599756.806409466 30 ctime=1432599756.854411378 signal-1.3.2/inst/ellipord.m0000644000000000000000000000716212530736314015747 0ustar00rootroot00000000000000## Copyright (C) 2001 Paulo Neis ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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}, @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. ## ## Reference: Lamar, Marcus Vinicius, @cite{Notas de aula da disciplina TE 456 - ## Circuitos Analogicos II}, UFPR, 2001/2002. ## @seealso{buttord, cheb1ord, cheb2ord, ellip} ## @end deftypefn function [n, Wp] = ellipord(Wp, Ws, Rp, Rs) if (nargin != 4) print_usage (); else validate_filter_bands ("ellipord", Wp, Ws); endif ## sampling frequency of 2 Hz T = 2; Wpw = tan(pi.*Wp./T); # prewarp Wsw = tan(pi.*Ws./T); # prewarp ## pass/stop band to low pass filter transform: if (length(Wpw)==2 && length(Wsw)==2) wp=1; w02 = Wpw(1) * Wpw(2); # Central frequency of stop/pass band (square) w3 = w02/Wsw(2); w4 = w02/Wsw(1); if (w3 > Wsw(1)) ws = (Wsw(2)-w3)/(Wpw(2)-Wpw(1)); elseif (w4 < Wsw(2)) ws = (w4-Wsw(1))/(Wpw(2)-Wpw(1)); else ws = (Wsw(2)-Wsw(1))/(Wpw(2)-Wpw(1)); endif elseif (Wpw > Wsw) wp = Wsw; ws = Wpw; else wp = Wpw; ws = Wsw; endif k=wp/ws; k1=sqrt(1-k^2); q0=(1/2)*((1-sqrt(k1))/(1+sqrt(k1))); q= q0 + 2*q0^5 + 15*q0^9 + 150*q0^13; #(....) D=(10^(0.1*Rs)-1)/(10^(0.1*Rp)-1); n=ceil(log10(16*D)/log10(1/q)); endfunction %% Test input validation %!error ellipord () %!error ellipord (.1) %!error ellipord (.1, .2) %!error ellipord (.1, .2, 3) %!error ellipord (.1, .2, 3, 4, 5) %!error ellipord ([.1 .1], [.2 .2], 3, 4) %!error ellipord ([.1 .2], [.5 .6], 3, 4) %!error ellipord ([.1 .5], [.2 .6], 3, 4) signal-1.3.2/inst/PaxHeaders.4544/tfe.m0000644000000000000000000000013212530736314014364 xustar0030 mtime=1432599756.834410581 30 atime=1432599756.834410581 30 ctime=1432599756.854411378 signal-1.3.2/inst/tfe.m0000644000000000000000000000370112530736314014706 0ustar00rootroot00000000000000## Copyright (C) 2006 Peter V. Lanspeary ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## Usage: ## [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. function varargout = tfe(varargin) ## ## Check fixed argument if ( nargin<2 ) error( 'tfe: Need at least 2 args. Use help tfe.' ); endif nvarargin = length(varargin); ## remove any pwelch RESULT args and add 'trans' for iarg=1:nvarargin arg = varargin{iarg}; if ( ~isempty(arg) && ischar(arg) && ( strcmp(arg,'power') || ... strcmp(arg,'cross') || strcmp(arg,'trans') || ... strcmp(arg,'coher') || strcmp(arg,'ypower') )) varargin{iarg} = []; endif endfor varargin{nvarargin+1} = 'trans'; ## saved_compatib = pwelch('R11-'); if ( nargout==0 ) pwelch(varargin{:}); elseif ( nargout==1 ) Pxx = pwelch(varargin{:}); varargout{1} = Pxx; elseif ( nargout>=2 ) [Pxx,f] = pwelch(varargin{:}); varargout{1} = Pxx; varargout{2} = f; endif pwelch(saved_compatib); endfunction signal-1.3.2/inst/PaxHeaders.4544/cmorwavf.m0000644000000000000000000000013212530736314015432 xustar0030 mtime=1432599756.798409147 30 atime=1432599756.798409147 30 ctime=1432599756.854411378 signal-1.3.2/inst/cmorwavf.m0000644000000000000000000000223612530736314015756 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function [psi,x] = cmorwavf (lb,ub,n,fb,fc) if (nargin ~= 5) print_usage; elseif (n <= 0 || floor(n) ~= n) error("n must be an integer strictly positive"); endif x = linspace(lb,ub,n); psi =((pi*fb)^(-0.5))*exp(2*i*pi*fc.*x).*exp(-x.^2/fb); endfunction signal-1.3.2/inst/PaxHeaders.4544/invimpinvar.m0000644000000000000000000000013212530736314016150 xustar0030 mtime=1432599756.818409944 30 atime=1432599756.818409944 30 ctime=1432599756.854411378 signal-1.3.2/inst/invimpinvar.m0000644000000000000000000001262612530736314016500 0ustar00rootroot00000000000000## Copyright (c) 2007 R.G.H. Eschauzier ## Copyright (c) 2011 Carnë Draug ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## ## @seealso{bilinear, impinvar} ## @end deftypefn ## Impulse invariant conversion from s to z domain function [b_out, a_out] = invimpinvar (b_in, a_in, fs = 1, tol = 0.0001) if (nargin <2) print_usage; endif ## to be compatible with the matlab implementation where an empty vector can ## be used to get the default if (isempty(fs)) ts = 1; else ts = 1/fs; # we should be using sampling frequencies to be compatible with Matlab endif b_in = [b_in 0]; # so we can calculate in z instead of z^-1 [r_in, p_in, k_in] = residue(b_in, a_in); # partial fraction expansion n = length(r_in); # Number of poles/residues if (length(k_in) > 1) # Greater than one means we cannot do impulse invariance error("Order numerator > order denominator"); endif r_out = zeros(1,n); # Residues of H(s) sm_out = zeros(1,n); # Poles of H(s) i=1; while (i<=n) m=1; first_pole = p_in(i); # Pole in the z-domain while (i1) # Go through residues starting from highest order down r_out(j) = r_in(j) / ((ts * p_in)^j); # Back to binomial coefficient for highest order (always 1) r_in(1:j) -= r_out(j) * polyrev(h1_z_deriv(j-1,p_in,ts)); # Subtract highest order result, leaving r_in(j) zero j--; endwhile ## Single pole (no multiplicity) r_out(1) = r_in(1) / ((ts * p_in)); k_out = r_in(1) / p_in; sm_out = log(p_in) / ts; endfunction %!function err = ztoserr(bz,az,fs) %! %! # number of time steps %! n=100; %! %! # make sure system is realizable (no delays) %! bz=prepad(bz,length(az)-1,0,2); %! %! # inverse impulse invariant transform to s-domain %! [bs as]=invimpinvar(bz,az,fs); %! %! # create sys object of transfer function %! s=tf(bs,as); %! %! # calculate impulse response of continuous time system %! # at discrete time intervals 1/fs %! ys=impulse(s,(n-1)/fs,1/fs)'; %! %! # impulse response of discrete time system %! yz=filter(bz,az,[1 zeros(1,n-1)]); %! %! # find rms error %! err=sqrt(sum((yz*fs.-ys).^2)/length(ys)); %! endfunction %! %!assert(ztoserr([1],[1 -0.5],0.01),0,0.0001); %!assert(ztoserr([1],[1 -1 0.25],0.01),0,0.0001); %!assert(ztoserr([1 1],[1 -1 0.25],0.01),0,0.0001); %!assert(ztoserr([1],[1 -1.5 0.75 -0.125],0.01),0,0.0001); %!assert(ztoserr([1 1],[1 -1.5 0.75 -0.125],0.01),0,0.0001); %!assert(ztoserr([1 1 1],[1 -1.5 0.75 -0.125],0.01),0,0.0001); %!assert(ztoserr([1],[1 0 0.25],0.01),0,0.0001); %!assert(ztoserr([1 1],[1 0 0.25],0.01),0,0.0001); %!assert(ztoserr([1],[1 0 0.5 0 0.0625],0.01),0,0.0001); %!assert(ztoserr([1 1],[1 0 0.5 0 0.0625],0.01),0,0.0001); %!assert(ztoserr([1 1 1],[1 0 0.5 0 0.0625],0.01),0,0.0001); %!assert(ztoserr([1 1 1 1],[1 0 0.5 0 0.0625],0.01),0,0.0001); signal-1.3.2/inst/PaxHeaders.4544/ultrwin.m0000644000000000000000000000013212530736314015312 xustar0030 mtime=1432599756.838410741 30 atime=1432599756.838410741 30 ctime=1432599756.854411378 signal-1.3.2/inst/ultrwin.m0000644000000000000000000002022512530736314015634 0ustar00rootroot00000000000000## Copyright (c) 2013 Rob Sykes ## ## This program is free software: you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation, either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## @seealso{chebwin, kaiser} ## @end deftypefn function [w, xmu] = ultrwin (m, mu, par, key = "beta", norm = 0) ## This list of parameter types must be kept in sync with the enum order. types = {"xmu", "beta", "att", "latt"}; type = []; if (ischar (key)) type = find (strncmpi (key, types, numel (key))); endif if (nargin < 3 || nargin > 5) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("ultrwin: M must be a positive integer"); elseif (! (isscalar (mu) && isreal (mu))) error ("ultrwin: MU must be a real scalar"); elseif (! ischar (key)) error ("ultrwin: parameter type must be a string"); elseif (isempty (type)) error ("ultrwin: invalid parameter type '%s'", key); elseif (! (isscalar (par) && isreal (par))) error (["ultrwin: ", upper (types(type)), " must be a real scalar"]); elseif (! (isscalar (norm) && norm == fix (norm) && norm >= 0)) # Alt. norms; WIP error ("ultrwin: NORM must be a non-negative integer"); endif [w, xmu] = __ultrwin__(m, mu, par, type-1, norm); endfunction %!test %! assert(ultrwin(100, 1, 1), ones(100, 1), 1e-14); %!test %! L = 201; xmu = 1.01; m = L-1; %! for mu = -1.35:.3:1.35 %! x = xmu*cos([0:m]*pi/L); %! C(2,:) = 2*mu*x; C(1,:) = 1; %! for k = 2:m; C(k+1,:) = 2*(k+mu-1)/k*x.*C(k,:) - (k+2*mu-2)/k*C(k-1,:); end %! b = real(ifft(C(m+1,:))); b = b(m/2+2:L)/b(1); %! assert(ultrwin(L, mu, xmu, "x")', [b 1 fliplr(b)], 1e-12); %! end %!test %! b = [ %! 5.7962919401511820e-03 %! 1.6086991349967078e-02 %! 3.6019014684117417e-02 %! 6.8897525451558125e-02 %! 1.1802364384553447e-01 %! 1.8566749737411145e-01 %! 2.7234740630826737e-01 %! 3.7625460141456091e-01 %! 4.9297108901880221e-01 %! 6.1558961695849457e-01 %! 7.3527571856983598e-01 %! 8.4222550739092694e-01 %! 9.2688779484512085e-01 %! 9.8125497127708561e-01]'; %! [w xmu] = ultrwin(29, 0, 3); %! assert(w', [b 1 fliplr(b)], 1e-14); %! assert(xmu, 1.053578297819277, 1e-14); %!test %! b = [ %! 2.9953636903962466e-02 %! 7.6096450051659603e-02 %! 1.5207129867916891e-01 %! 2.5906995366355179e-01 %! 3.9341065451220536e-01 %! 5.4533014012036929e-01 %! 6.9975915071207051e-01 %! 8.3851052636906720e-01 %! 9.4345733548690369e-01]'; %! assert(ultrwin(20, .5, 50, "a")', [b 1 1 fliplr(b)], 1e-14); %!test %! b = [ %! 1.0159906492322712e-01 %! 1.4456358609406283e-01 %! 2.4781689516201011e-01 %! 3.7237015168857646e-01 %! 5.1296973026690407e-01 %! 6.5799041448113671e-01 %! 7.9299087042967320e-01 %! 9.0299778924260576e-01 %! 9.7496213649820296e-01]'; %! assert(ultrwin(19, -.4, 40, "l")', [b 1 fliplr(b)], 1e-14); %!demo %! w=ultrwin(120, -1, 40, "l"); [W,f]=freqz(w); clf %! subplot(2,1,1); plot(f/pi, 20*log10(W/abs(W(1)))); grid; axis([0 1 -90 0]) %! subplot(2,1,2); plot(0:length(w)-1, w); grid %! %----------------------------------------------------------- %! % Figure shows an Ultraspherical window with MU=-1, LATT=40: %! % frequency domain above, time domain below. %!demo %! c="krbm"; clf; subplot(2, 1, 1) %! for beta=2:5 %! w=ultrwin(80, -.5, beta); [W,f]=freqz(w); %! plot(f/pi, 20*log10(W/abs(W(1))), c(1+mod(beta, length(c)))); hold on %! end; grid; axis([0 1 -140 0]); hold off %! subplot(2, 1, 2); %! for n=2:10 %! w=ultrwin(n*20, 1, 3); [W,f]=freqz(w,1,2^11); %! plot(f/pi, 20*log10(W/abs(W(1))), c(1+mod(n, length(c)))); hold on %! end; grid; axis([0 .2 -100 0]); hold off %! %-------------------------------------------------- %! % Figure shows transfers of Ultraspherical windows: %! % above: varying BETA with fixed N & MU, %! % below: varying N with fixed MU & BETA. %!demo %! c="krbm"; clf; subplot(2, 1, 1) %! for j=0:4 %! w=ultrwin(80, j*.6-1.2, 50, "a"); [W,f]=freqz(w); %! plot(f/pi, 20*log10(W/abs(W(1))), c(1+mod(j, length(c)))); hold on %! end; grid; axis([0 1 -100 0]); hold off %! subplot(2, 1, 2); %! for j=4:-1:0 %! w=ultrwin(80, j*.75-1.5, 50, "l"); [W,f]=freqz(w); %! plot(f/pi, 20*log10(W/abs(W(1))), c(1+mod(j, length(c)))); hold on %! end; grid; axis([0 1 -100 0]); hold off %! %-------------------------------------------------- %! % Figure shows transfers of Ultraspherical windows: %! % above: varying MU with fixed N & ATT, %! % below: varying MU with fixed N & LATT. %!demo %! clf; a=[.8 2 -115 5]; fc=1.1/pi; l="labelxy"; %! for k=1:3; switch (k); case 1; w=kaiser(L=159, 7.91); %! case 2; w=ultrwin(L=165, 0, 2.73); case 3; w=ultrwin(L=153, .5, 2.6); end %! subplot(3, 1, 4-k); f=[1:(L-1)/2]*pi;f=sin(fc*f)./f; f=[fliplr(f) fc f]'; %! [h,f]=freqz(w.*f,1,2^14); plot(f,20*log10(h)); grid; axis(a,l); l="labely"; %! end %! %----------------------------------------------------------- %! % Figure shows example lowpass filter design (Fp=1, Fs=1.2 %! % rad/s, att=80 dB) and comparison with other windows. From %! % top to bottom: Ultraspherical, Dolph-Chebyshev, and Kaiser %! % windows, with lengths 153, 165, and 159 respectively. signal-1.3.2/inst/PaxHeaders.4544/freqs_plot.m0000644000000000000000000000013212530736314015764 xustar0030 mtime=1432599756.810409625 30 atime=1432599756.810409625 30 ctime=1432599756.854411378 signal-1.3.2/inst/freqs_plot.m0000644000000000000000000000273012530736314016307 0ustar00rootroot00000000000000## Copyright (C) 2003 Julius O. Smith III ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} freqs_plot (@var{w}, @var{h}) ## Plot the amplitude and phase of the vector @var{h}. ## @end deftypefn function freqs_plot(w,h) n = length(w); mag = 20*log10(abs(h)); phase = unwrap(arg(h)); maxmag = max(mag); subplot(211); plot(w, mag, ";Magnitude (dB);"); title('Frequency response plot by freqs'); axis("labely"); ylabel("dB"); xlabel(""); grid("on"); if (maxmag - min(mag) > 100) # make 100 a parameter? axis([w(1), w(n), maxmag-100, maxmag]); else axis("autoy"); endif subplot(212); plot(w, phase/(2*pi), ";Phase (radians/2pi);"); axis("label"); title(""); grid("on"); axis("autoy"); xlabel("Frequency (rad/sec)"); ylabel("Cycles"); axis([w(1), w(n)]); endfunction signal-1.3.2/inst/PaxHeaders.4544/bitrevorder.m0000644000000000000000000000013212530736314016135 xustar0030 mtime=1432599756.790408828 30 atime=1432599756.790408828 30 ctime=1432599756.854411378 signal-1.3.2/inst/bitrevorder.m0000644000000000000000000000337712530736314016470 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## Copyright (C) 2013 Mike Miller ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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)}. ## @seealso{digitrevorder, fft, ifft} ## @end deftypefn function [y, i] = bitrevorder (x) if (nargin != 1) print_usage (); elseif (! isvector (x)) error ("bitrevorder: X must be a vector"); elseif (fix (log2 (numel (x))) != log2 (numel (x))) error ("bitrevorder: X must have length equal to an integer power of 2"); endif [y, i] = digitrevorder (x, 2); endfunction %!assert (bitrevorder (0), 0); %!assert (bitrevorder (0:1), 0:1); %!assert (bitrevorder ([0:1]'), [0:1]'); %!assert (bitrevorder (0:7), [0 4 2 6 1 5 3 7]); %!assert (bitrevorder (0:15), [0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15]); %% Test input validation %!error bitrevorder (); %!error bitrevorder (1, 2); %!error bitrevorder ([]); %!error bitrevorder (0:2); signal-1.3.2/inst/PaxHeaders.4544/zplane.m0000644000000000000000000000012612530736314015102 xustar0028 mtime=1432599756.8424109 28 atime=1432599756.8424109 30 ctime=1432599756.854411378 signal-1.3.2/inst/zplane.m0000644000000000000000000001231012530736314015415 0ustar00rootroot00000000000000## Copyright (C) 1999, 2001 Paul Kienzle ## Copyright (C) 2004 Stefan van der Walt ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} zplane (@var{z}, @var{p}) ## @deftypefnx {Function File} {} zplane (@var{b}, @var{a}) ## ## Plot the poles and zeros. If the arguments are row vectors then they ## represent filter coefficients (numerator polynomial b and denominator ## polynomial a), but if they are column vectors or matrices then they ## represent poles and zeros. ## ## This is a horrid interface, but I didn't choose it; better would be ## to accept b,a or z,p,g like other functions. The saving grace is ## that poly(x) always returns a row vector and roots(x) always returns ## a column vector, so it is usually right. You must only be careful ## when you are creating filters by hand. ## ## Note that due to the nature of the 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 ## ## The denominator a defaults to 1, and the poles p defaults to []. ## @end deftypefn ## FIXME: Consider a plot-like interface: ## zplane(x1,y1,fmt1,x2,y2,fmt2,...) ## with y_i or fmt_i optional as usual. This would allow ## legends and control over point color and filters of ## different orders. function zplane(z, p = []) if (nargin < 1 || nargin > 2) print_usage; endif if columns(z)>1 || columns(p)>1 if rows(z)>1 || rows(p)>1 ## matrix form: columns are already zeros/poles else ## z -> b ## p -> a if isempty(z), z=1; endif if isempty(p), p=1; endif M = length(z) - 1; N = length(p) - 1; z = [ roots(z); zeros(N - M, 1) ]; p = [ roots(p); zeros(M - N, 1) ]; endif endif xmin = min([-1; real(z(:)); real(p(:))]); xmax = max([ 1; real(z(:)); real(p(:))]); ymin = min([-1; imag(z(:)); imag(p(:))]); ymax = max([ 1; imag(z(:)); imag(p(:))]); xfluff = max([0.05*(xmax-xmin), (1.05*(ymax-ymin)-(xmax-xmin))/10]); yfluff = max([0.05*(ymax-ymin), (1.05*(xmax-xmin)-(ymax-ymin))/10]); xmin = xmin - xfluff; xmax = xmax + xfluff; ymin = ymin - yfluff; ymax = ymax + yfluff; text(); plot_with_labels(z, "o"); plot_with_labels(p, "x"); refresh; r = exp(2i*pi*[0:100]/100); plot(real(r), imag(r),'k'); hold on; axis equal; grid on; axis(1.05*[xmin, xmax, ymin, ymax]); if (!isempty(p)) h = plot(real(p), imag(p), "bx"); set (h, 'MarkerSize', 7); endif if (!isempty(z)) h = plot(real(z), imag(z), "bo"); set (h, 'MarkerSize', 7); endif hold off; endfunction function plot_with_labels(x, symbol) if ( !isempty(x) ) x_u = unique(x(:)); for i = 1:length(x_u) n = sum(x_u(i) == x(:)); if (n > 1) text(real(x_u(i)), imag(x_u(i)), [" " num2str(n)]); endif endfor col = "rgbcmy"; for c = 1:columns(x) plot(real( x(:,c) ), imag( x(:,c) ), [col(mod(c,6)),symbol ";;"]); endfor endif endfunction %!demo %! ## construct target system: %! ## symmetric zero-pole pairs at r*exp(iw),r*exp(-iw) %! ## zero-pole singletons at s %! pw=[0.2, 0.4, 0.45, 0.95]; #pw = [0.4]; %! pr=[0.98, 0.98, 0.98, 0.96]; #pr = [0.85]; %! ps=[]; %! zw=[0.3]; # zw=[]; %! zr=[0.95]; # zr=[]; %! zs=[]; %! %! ## system function for target system %! p=[[pr, pr].*exp(1i*pi*[pw, -pw]), ps]'; %! z=[[zr, zr].*exp(1i*pi*[zw, -zw]), zs]'; %! M = length(z); N = length(p); %! sys_a = [ zeros(1, M-N), real(poly(p)) ]; %! sys_b = [ zeros(1, N-M), real(poly(z)) ]; %! disp("The first two graphs should be identical, with poles at (r,w)="); %! disp(sprintf(" (%.2f,%.2f)", [pr ; pw])); %! disp("and zeros at (r,w)="); %! disp(sprintf(" (%.2f,%.2f)", [zr ; zw])); %! disp("with reflection across the horizontal plane"); %! subplot(231); %! zplane(sys_b, sys_a); %! title("transfer function form"); %! subplot(232); %! zplane(z,p); %! title("pole-zero form"); %! subplot(233); %! zplane(z); %! title("empty p"); %! subplot(234); %! zplane(sys_b); %! title("empty a"); %! disp("The matrix plot has 2 sets of points, one inside the other"); %! subplot(235); %! zplane([z, 0.7*z], [p, 0.7*p]); %! title("matrix"); signal-1.3.2/inst/PaxHeaders.4544/hann.m0000644000000000000000000000013212530736314014532 xustar0030 mtime=1432599756.814409784 30 atime=1432599756.814409784 30 ctime=1432599756.854411378 signal-1.3.2/inst/hann.m0000644000000000000000000000401012530736314015046 0ustar00rootroot00000000000000## Copyright (C) 2014 Mike Miller ## ## This program is free software: you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation, either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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})}. ## ## @seealso{hanning} ## @end deftypefn function w = hann (varargin) if (nargin < 1 || nargin > 2) print_usage (); endif w = hanning (varargin{:}); endfunction %!assert (hann (1), 1); %!assert (hann (2), zeros (2, 1)); %!assert (hann (16), flipud (hann (16)), 10*eps); %!assert (hann (15), flipud (hann (15)), 10*eps); %!test %! N = 15; %! A = hann (N); %! assert (A(ceil (N/2)), 1); %!assert (hann (15), hann (15, "symmetric")); %!assert (hann (16)(1:15), hann (15, "periodic")); %!test %! N = 16; %! A = hann (N, "periodic"); %! assert (A (N/2 + 1), 1); %% Test input validation %!error hann () %!error hann (0.5) %!error hann (-1) %!error hann (1, "invalid") signal-1.3.2/inst/PaxHeaders.4544/decimate.m0000644000000000000000000000013212530736314015361 xustar0030 mtime=1432599756.802409306 30 atime=1432599756.802409306 30 ctime=1432599756.854411378 signal-1.3.2/inst/decimate.m0000644000000000000000000000765512530736314015717 0ustar00rootroot00000000000000## Copyright (C) 2000 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function y = decimate(x, q, n, ftype) if (nargin < 2 || nargin > 4) print_usage (); elseif (! (isscalar (q) && (q == fix (q)) && (q > 0))) error ("decimate: Q must be a positive integer"); endif if (nargin < 3) ftype = "iir"; n = []; elseif (nargin < 4) if (ischar (n)) ftype = n; n = []; else ftype = "iir"; endif endif if (! any (strcmp (ftype, {"fir", "iir"}))) error ('decimate: filter type must be either "fir" or "iir"'); endif fir = strcmp (ftype, "fir"); if (isempty (n)) if (fir) n = 30; else n = 8; endif endif if (! (isscalar (n) && (n == fix (n)) && (n > 0))) error ("decimate: N must be a positive integer"); endif if (fir) b = fir1 (n, 1/q); y = fftfilt (b, x); else [b, a] = cheby1 (n, 0.05, 0.8/q); y = filtfilt (b, a, x); endif y = y(1:q:length(x)); endfunction %!demo %! t=0:0.01:2; x=chirp(t,2,.5,10,'quadratic')+sin(2*pi*t*0.4); %! y = decimate(x,4); # factor of 4 decimation %! stem(t(1:121)*1000,x(1:121),"-g;Original;"); hold on; # plot original %! stem(t(1:4:121)*1000,y(1:31),"-r;Decimated;"); hold off; # decimated %! %------------------------------------------------------------------ %! % The signal to decimate 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. You will also 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. %% Test input validation %!error decimate () %!error decimate (1) %!error decimate (1, 2, 3, 4, 5) %!error decimate (1, -1) signal-1.3.2/inst/PaxHeaders.4544/pulstran.m0000644000000000000000000000013212530736314015456 xustar0030 mtime=1432599756.826410262 30 atime=1432599756.826410262 30 ctime=1432599756.854411378 signal-1.3.2/inst/pulstran.m0000644000000000000000000001404212530736314016000 0ustar00rootroot00000000000000## Copyright (C) 2000 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## FIXME: Make it faster. It is currently unusable for anything real. ## It may not be possible to speed it up with the present interface. ## See speech/voice.m for a better way. ## Note that pulstran can be used for some pretty strange things such ## as simple band-limited interpolation: ## xf = 0:0.05:10; yf = sin(2*pi*xf/5); ## xp = 0:10; yp = sin(2*pi*xp/5); # .2 Hz sine sampled every second ## s = pulstran(xf, [xp, yp],'sinc'); ## plot(f, yf, ";original;", xf, s, ";sinc;",xp,yp,"*;;"); ## You wouldn't want to do this in practice since it is expensive, and ## since it works much better with a windowed sinc function, at least ## for short samples. function y = pulstran(t, d, pulse, varargin) if nargin<3 || (!ischar(pulse) && nargin>5) print_usage; endif y = zeros(size(t)); if isempty(y), return; endif if rows(d) == 1, d=d'; endif if columns(d) == 2, a=d(:,2); else a=ones(rows(d),1); endif if ischar(pulse) ## apply function t+d for all d for i=1:rows(d) y = y+a(i)*feval(pulse,t-d(i,1),varargin{:}); endfor else ## interpolate each pulse at the specified times Fs = 1; method = 'linear'; if nargin==4 arg=varargin{1}; if ischar(arg), method=arg; else Fs = arg; endif elseif nargin==5 Fs = varargin{1}; method = varargin{2}; endif span = (length(pulse)-1)/Fs; t_pulse = (0:length(pulse)-1)/Fs; for i=1:rows(d) dt = t-d(i,1); idx = find(dt>=0 & dt<=span); y(idx) = y(idx) + a(i)*interp1(t_pulse, pulse, dt(idx), method); endfor endif endfunction %!error pulstran %!error pulstran(1,2,3,4,5,6) %!## parameter size and shape checking %!shared t,d %! t = 0:0.01:1; d=0:0.1:1; %!assert (isempty(pulstran([], d, 'sin'))); %!assert (pulstran(t, [], 'sin'), zeros(size(t))); %!assert (isempty(pulstran([], d, boxcar(5)))); %!assert (pulstran(t, [], boxcar(5)), zeros(size(t))); %!assert (size(pulstran(t,d,'sin')), size(t)); %!assert (size(pulstran(t,d','sin')), size(t)); %!assert (size(pulstran(t',d,'sin')), size(t')); %!assert (size(pulstran(t,d','sin')), size(t)); %!demo %! fs = 11025; # arbitrary sample rate %! f0 = 100; # pulse train sample rate %! w = 0.003; # pulse width of 3 milliseconds %! t = 0:1/fs:0.1; d=0:1/f0:0.1; # define sample times and pulse times %! a = hanning(length(d)); # define pulse amplitudes %! %! subplot(221); %! x = pulstran(t', d', 'rectpuls', w); %! plot([0:length(x)-1]*1000/fs, x); %! hold on; plot(d*1000,ones(size(d)),'g*;pulse;'); hold off; %! ylabel("amplitude"); xlabel("time (ms)"); %! title("rectpuls"); %! %! subplot(223); %! x = pulstran(f0*t, [f0*d', a], 'sinc'); %! plot([0:length(x)-1]*1000/fs, x); %! hold on; plot(d*1000,a,'g*;pulse;'); hold off; %! ylabel("amplitude"); xlabel("time (ms)"); %! title("sinc => band limited interpolation"); %! %! subplot(222); %! pulse = boxcar(30); # pulse width of 3 ms at 10 kHz %! x = pulstran(t, d', pulse, 10000); %! plot([0:length(x)-1]*1000/fs, x); %! hold on; plot(d*1000,ones(size(d)),'g*;pulse;'); hold off; %! ylabel("amplitude"); xlabel("time (ms)"); %! title("interpolated boxcar"); %! %! subplot(224); %! pulse = sin(2*pi*[0:0.0001:w]/w).*[w:-0.0001:0]; %! x = pulstran(t', [d', a], pulse', 10000); %! plot([0:length(x)-1]*1000/fs, x); %! hold on; plot(d*1000,a*w,'g*;pulse;'); hold off; title(""); %! ylabel("amplitude"); xlabel("time (ms)"); %! title("interpolated asymmetric sin"); %! %! %---------------------------------------------------------- %! % Should see (1) rectangular pulses centered on *, %! % (2) rectangular pulses to the right of *, %! % (3) smooth interpolation between the *'s, and %! % (4) asymmetric sines to the right of * signal-1.3.2/inst/PaxHeaders.4544/square.m0000644000000000000000000000013212530736314015106 xustar0030 mtime=1432599756.834410581 30 atime=1432599756.834410581 30 ctime=1432599756.854411378 signal-1.3.2/inst/square.m0000644000000000000000000000142012530736314015424 0ustar00rootroot00000000000000## Author: Paul Kienzle (2006) ## This program is granted to the public domain. ## -*- texinfo -*- ## @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, the square wave is +1 for that portion of the ## time. ## ## @verbatim ## on time ## duty cycle = ------------------ ## on time + off time ## @end verbatim ## ## @seealso{cos, sawtooth, sin, tripuls} ## @end deftypefn function v = square (t, duty = 0.5) if (nargin < 1 || nargin > 2) print_usage; endif t /= 2*pi; v = ones(size(t)); v(t-floor(t) >= duty) = -1; endfunction signal-1.3.2/inst/PaxHeaders.4544/tripuls.m0000644000000000000000000000013212530736314015310 xustar0030 mtime=1432599756.838410741 30 atime=1432599756.838410741 30 ctime=1432599756.854411378 signal-1.3.2/inst/tripuls.m0000644000000000000000000000544512530736314015641 0ustar00rootroot00000000000000## Copyright (C) 2001 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 [-w/2,w/2), sampled at ## times t. This is useful with the function pulstran for generating a ## series pulses. ## ## 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 -w/2, and 1 indicates that the peak should be at w/2. ## ## 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 ## auplot(pulstran(0:1/fs:4/f0, 0:1/f0:4/f0, 'tripuls', w), fs); ## @end group ## @end example ## ## @seealso{pulstran} ## @end deftypefn function y = tripuls (t, w = 1, skew = 0) if nargin<1 || nargin>3, print_usage; endif y = zeros(size(t)); peak = skew*w/2; try wfi = warning("off", "Octave:fortran-indexing"); catch wfi = 0; end_try_catch unwind_protect idx = find(t>=-w/2 & t <= peak); if (idx) y(idx) = ( t(idx) + w/2 ) / ( peak + w/2 ); endif idx = find(t>peak & t < w/2); if (idx) y(idx) = ( t(idx) - w/2 ) / ( peak - w/2 ); endif unwind_protect_cleanup warning(wfi); end_unwind_protect endfunction %!assert(tripuls(0:1/100:0.3,.1), tripuls([0:1/100:0.3]',.1)'); %!assert(isempty(tripuls([],.1))); %!demo %! fs = 11025; # arbitrary sample rate %! f0 = 100; # pulse train sample rate %! w = 0.5/f0; # pulse width 1/10th the distance between pulses %! subplot(211); %! x = pulstran(0:1/fs:4/f0, 0:1/f0:4/f0, 'tripuls', w); %! plot([0:length(x)-1]*1000/fs, x); %! ylabel("amplitude"); xlabel("time (ms)"); %! title("graph shows 5 ms pulses at 0,10,20,30 and 40 ms"); %! subplot(212); %! x = pulstran(0:1/fs:4/f0, 0:1/f0:4/f0, 'tripuls', w, -0.5); %! plot([0:length(x)-1]*1000/fs, x); %! ylabel("amplitude"); xlabel("time (ms)"); %! title("graph shows 5 ms pulses at 0,10,20,30 and 40 ms, skew -0.5"); signal-1.3.2/inst/PaxHeaders.4544/schtrig.m0000644000000000000000000000013212530736314015251 xustar0030 mtime=1432599756.830410422 30 atime=1432599756.830410422 30 ctime=1432599756.854411378 signal-1.3.2/inst/schtrig.m0000644000000000000000000000467112530736314015602 0ustar00rootroot00000000000000## Copyright (c) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{rmsx},@var{w}] =} schtrig (@var{x},@var{lvl},@var{rst}=1) ## Implements a multisignal Schmitt trigger with levels @var{lvl}. ## ## The triger works along the first dimension of the array @var{x}. When @code{@var{rst}==1} ## the state of the trigger for all signals is set to the low state (i.e. 0). ## ## Run @code{demo schtrig} to see an example. ## ## @seealso{clustersegment} ## @end deftypefn function v = schtrig (x, lvl, rst = 1) persistent st0; if length(lvl) == 1 lvl = abs (lvl)*[1 -1]; else lvl = sort(lvl,'descend'); endif [nT nc] = size(x); v = NA (nT, nc); if rst || isempty(st0) st0 = zeros(1,nc); endif v(1,:) = st0; ## Signal is above up level up = x > lvl(1); v(up) = 1; ## Signal is below down level dw = x < lvl(2); v(dw) = 0; ## Resolve intermediate states ## Find data between the levels idx = isnan (v); ranges = clustersegment (idx'); for i=1:nc ## Record the state at the beginning of the interval between levels if !isempty (ranges{i}) prev = ranges{i}(1,:)-1; prev(prev<1) = 1; st0 = v(prev,i); ## Copy the initial state to the interval ini_idx = ranges{i}(1,:); end_idx = ranges{i}(2,:); for j =1:length(ini_idx) v(ini_idx(j):end_idx(j),i) = st0(j); endfor endif endfor st0 = v(end,:); endfunction %!demo %! t = linspace(0,1,100)'; %! x = sin (2*pi*2*t) + sin (2*pi*5*t).*[0.8 0.3]; %! %! lvl = [0.8 0.25]'; %! v = schtrig (x,lvl); %! %! h = plot(t,x,t,v); %! set (h([1 3]),'color','b'); %! set (h([2 4]),'color',[0 1 0.5]); %! set (h,'linewidth',2); %! line([0; 1],lvl([1; 1]),'color','r'); %! line([0;1],lvl([2;2]),'color','b') signal-1.3.2/inst/PaxHeaders.4544/dftmtx.m0000644000000000000000000000013212530736314015114 xustar0030 mtime=1432599756.802409306 30 atime=1432599756.802409306 30 ctime=1432599756.854411378 signal-1.3.2/inst/dftmtx.m0000644000000000000000000000257312530736314015444 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## @seealso{fft, ifft} ## @end deftypefn function d = dftmtx(n) if (nargin != 1) print_usage; elseif (!isscalar(n)) error ("dftmtx: argument must be scalar"); endif d = fft(eye(n)); endfunction signal-1.3.2/inst/PaxHeaders.4544/bilinear.m0000644000000000000000000000013212530736314015373 xustar0030 mtime=1432599756.790408828 30 atime=1432599756.790408828 30 ctime=1432599756.854411378 signal-1.3.2/inst/bilinear.m0000644000000000000000000001110212530736314015707 0ustar00rootroot00000000000000## Copyright (C) 1999 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function [Zz, Zp, Zg] = bilinear(Sz, Sp, Sg, T) if nargin==3 T = Sg; [Sz, Sp, Sg] = tf2zp(Sz, Sp); elseif nargin!=4 print_usage; endif p = length(Sp); z = length(Sz); if z > p || p==0 error("bilinear: must have at least as many poles as zeros in s-plane"); endif ## ---------------- ------------------------- ------------------------ ## 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 ## ---------------- ------------------------- ------------------------ Zg = real(Sg * prod((2-Sz*T)/T) / prod((2-Sp*T)/T)); Zp = (2+Sp*T)./(2-Sp*T); if isempty(Sz) Zz = -ones(size(Zp)); else Zz = [(2+Sz*T)./(2-Sz*T)]; Zz = postpad(Zz, p, -1); endif if nargout==2, [Zz, Zp] = zp2tf(Zz, Zp, Zg); endif endfunction signal-1.3.2/inst/PaxHeaders.4544/filtic.m0000644000000000000000000000013212530736314015060 xustar0030 mtime=1432599756.806409466 30 atime=1432599756.806409466 30 ctime=1432599756.854411378 signal-1.3.2/inst/filtic.m0000644000000000000000000000724712530736314015413 0ustar00rootroot00000000000000## Copyright (C) 2004 David Billinghurst ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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)4 || nargin<3) || (nargout>1) print_usage; endif if nargin < 4, x = []; endif nz = max(length(a)-1,length(b)-1); zf=zeros(nz,1); ## Pad arrays a and b to length nz+1 if required if length(a)<(nz+1) a(length(a)+1:nz+1)=0; endif if length(b)<(nz+1) b(length(b)+1:nz+1)=0; endif ## Pad arrays x and y to length nz if required if length(x) < nz x(length(x)+1:nz)=0; endif if length(y) < nz y(length(y)+1:nz)=0; endif for i=nz:-1:1 for j=i:nz-1 zf(j) = b(j+1)*x(i) - a(j+1)*y(i)+zf(j+1); endfor zf(nz)=b(nz+1)*x(i)-a(nz+1)*y(i); endfor endfunction %!test %! ## Simple low pass filter %! b=[0.25 0.25]; %! a=[1.0 -0.5]; %! zf_ref=0.75; %! zf=filtic(b,a,[1.0],[1.0]); %! assert(zf,zf_ref,8*eps); %! %!test %! ## Simple high pass filter %! b=[0.25 -0.25]; %! a=[1.0 0.5]; %! zf_ref = [-0.25]; %! zf=filtic(b,a,[0.0],[1.0]); %! assert(zf,zf_ref,8*eps); %! %!test %! ## Second order cases %! [b,a]=butter(2,0.4); %! N=1000; ## Long enough for filter to settle %! xx=ones(1,N); %! [yy,zf_ref] = filter(b,a,xx); %! x=xx(N:-1:N-1); %! y=yy(N:-1:N-1); %! zf = filtic(b,a,y,x); %! assert(zf,zf_ref,8*eps); %! %! xx = cos(2*pi*linspace(0,N-1,N)/8); %! [yy,zf_ref] = filter(b,a,xx); %! x=xx(N:-1:N-1); %! y=yy(N:-1:N-1); %! zf = filtic(b,a,y,x); %! assert(zf,zf_ref,8*eps); %! %!test %! ## Third order filter - takes longer to settle %! N=10000; %! [b,a]=cheby1(3,10,0.5); %! xx=ones(1,N); %! [yy,zf_ref] = filter(b,a,xx); %! x=xx(N:-1:N-2); %! y=yy(N:-1:N-2); %! zf = filtic(b,a,y,x); %! assert(zf,zf_ref,8*eps); %! %!test %! ## Eight order high pass filter %! N=10000; %! [b,a]=butter(8,0.2); %! xx = cos(2*pi*linspace(0,N-1,N)/8); %! [yy,zf_ref] = filter(b,a,xx); %! x=xx(N:-1:N-7); %! y=yy(N:-1:N-7); %! zf = filtic(b,a,y,x); %! assert(zf,zf_ref,8*eps); %! %!test %! ## Case with 3 args %! [b,a]=butter(2,0.4); %! N=100; %! xx=[ones(1,N) zeros(1,2)]; %! [yy,zf_ref] = filter(b,a,xx); %! y=[yy(N+2) yy(N+1)]; %! zf=filtic(b,a,y); %! assert(zf,zf_ref,8*eps); signal-1.3.2/inst/PaxHeaders.4544/meyeraux.m0000644000000000000000000000013212530736314015445 xustar0030 mtime=1432599756.822410103 30 atime=1432599756.818409944 30 ctime=1432599756.854411378 signal-1.3.2/inst/meyeraux.m0000644000000000000000000000173312530736314015772 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} meyeraux (@var{x}) ## Compute the Meyer wavelet auxiliary function. ## @end deftypefn function y = meyeraux(x) if (nargin < 1); print_usage; endif y = 35.*x.^4-84.*x.^5+70.*x.^6-20.*x.^7; endfunction signal-1.3.2/inst/PaxHeaders.4544/impz.m0000644000000000000000000000013212530736314014565 xustar0030 mtime=1432599756.814409784 30 atime=1432599756.814409784 30 ctime=1432599756.854411378 signal-1.3.2/inst/impz.m0000644000000000000000000000677112530736314015121 0ustar00rootroot00000000000000## Copyright (C) 1999 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## ## @seealso{freqz, zplane} ## @end deftypefn ## FIXME: Call equivalent function from control toolbox since it is ## probably more sophisticated than this one, and since it ## is silly to maintain two different versions of essentially ## the same thing. function [x_r, t_r] = impz(b, a = [1], n = [], fs = 1) if nargin == 0 || nargin > 4 print_usage; endif if isempty(n) && length(a) > 1 precision = 1e-6; r = roots(a); maxpole = max(abs(r)); if (maxpole > 1+precision) # unstable -- cutoff at 120 dB n = floor(6/log10(maxpole)); elseif (maxpole < 1-precision) # stable -- cutoff at -120 dB n = floor(-6/log10(maxpole)); else # periodic -- cutoff after 5 cycles n = 30; ## find longest period less than infinity ## cutoff after 5 cycles (w=10*pi) rperiodic = r(find(abs(r)>=1-precision & abs(arg(r))>0)); if !isempty(rperiodic) n_periodic = ceil(10*pi./min(abs(arg(rperiodic)))); if (n_periodic > n) n = n_periodic; endif endif ## find most damped pole ## cutoff at -60 dB rdamped = r(find(abs(r)<1-precision)); if !isempty(rdamped) n_damped = floor(-3/log10(max(abs(rdamped)))); if (n_damped > n) n = n_damped; endif endif endif n = n + length(b); elseif isempty(n) n = length(b); endif if length(a) == 1 x = fftfilt(b/a, [1, zeros(1,n-1)]); else x = filter(b, a, [1, zeros(1,n-1)]); endif t = [0:n-1]/fs; if nargout >= 1 x_r = x; endif if nargout >= 2 t_r = t; endif if nargout == 0 unwind_protect title "Impulse Response"; if (fs > 1000) t = t * 1000; xlabel("Time (msec)"); else xlabel("Time (sec)"); endif plot(t, x, "^r;;"); unwind_protect_cleanup title ("") xlabel ("") end_unwind_protect endif endfunction signal-1.3.2/inst/PaxHeaders.4544/ar_psd.m0000644000000000000000000000013212530736314015056 xustar0030 mtime=1432599756.790408828 30 atime=1432599756.790408828 30 ctime=1432599756.854411378 signal-1.3.2/inst/ar_psd.m0000644000000000000000000002713712530736314015411 0ustar00rootroot00000000000000## Copyright (C) 2006 Peter V. Lanspeary ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function varargout = ar_psd(a,v,varargin) ## ## Check fixed arguments if ( nargin < 2 ) error( 'ar_psd: needs at least 2 args. Use help ar_psd.' ); elseif ( ~isvector(a) || length(a)<2 ) error( 'ar_psd: arg 1 (a) must be vector, length>=2.' ); elseif ( ~isscalar(v) ) error( 'ar_psd: arg 2 (v) must be real scalar >0.' ); else real_model = isreal(a); ## ## default values for optional arguments freq = 256; user_freqs = 0; ## boolean: true for user-specified frequencies Fs = 1.0; ## FFT padding factor (is also frequency range divisor): 1=whole, 2=half. pad_fact = 1 + real_model; do_shift = 0; force_FFT = 0; force_poly = 0; plot_type = 1; ## ## decode and check optional arguments ## end_numeric_args is boolean; becomes true at 1st string arg end_numeric_args = 0; for iarg = 1:length(varargin) arg = varargin{iarg}; end_numeric_args = end_numeric_args || ischar(arg); ## skip empty arguments if ( isempty(arg) ) 1; ## numeric optional arguments must be first, cannot follow string args ## N.B. older versions of matlab may not have the function "error" so ## the user writes "function error(msg); disp(msg); end" and we need ## a "return" here. elseif ( ~ischar(arg) ) if ( end_numeric_args ) error( 'ar_psd: control arg must be string.' ); ## ## first optional numeric arg is "freq" elseif ( iarg == 1 ) user_freqs = isvector(arg) && length(arg)>1; if ( ~isscalar(arg) && ~user_freqs ) error( 'ar_psd: arg 3 (freq) must be vector or scalar.' ); elseif ( ~user_freqs && ( ~isreal(arg) || ... fix(arg)~=arg || arg <= 2 || arg >= 1048576 ) ) error('ar_psd: arg 3 (freq) must be integer >=2, <=1048576' ); elseif ( user_freqs && ~isreal(arg) ) error( 'ar_psd: arg 3 (freq) vector must be real.' ); endif freq = arg(:); # -> column vector ## ## second optional numeric arg is "Fs" - sampling frequency elseif ( iarg == 2 ) if ( ~isscalar(arg) || ~isreal(arg) || arg<=0 ) error( 'ar_psd: arg 4 (Fs) must be real positive scalar.' ); endif Fs = arg; ## else error( 'ar_psd: control arg must be string.' ); endif ## ## decode control-string arguments elseif ( strcmp(arg,'plot') || strcmp(arg,'squared') ) plot_type = 1; elseif ( strcmp(arg,'semilogx') ) plot_type = 2; elseif ( strcmp(arg,'semilogy') ) plot_type = 3; elseif ( strcmp(arg,'loglog') ) plot_type = 4; elseif ( strcmp(arg,'dB') ) plot_type = 5; elseif ( strcmp(arg,'fft') ) force_FFT = 1; force_poly = 0; elseif ( strcmp(arg,'poly') ) force_FFT = 0; force_poly = 1; elseif ( strcmp(arg,'half') || strcmp(arg,'onesided') ) pad_fact = 2; # FFT zero-padding factor (pad FFT to double length) do_shift = 0; elseif ( strcmp(arg,'whole') || strcmp(arg,'twosided') ) pad_fact = 1; # FFT zero-padding factor (do not pad) do_shift = 0; elseif ( strcmp(arg,'shift') || strcmp(arg,'centerdc') ) pad_fact = 1; do_shift = 1; else error( 'ar_psd: string arg: illegal value: %s', arg ); endif endfor ## end of decoding and checking args ## if ( user_freqs ) ## user provides (column) vector of frequencies if ( any(abs(freq)>Fs/2) ) error( 'ar_psd: arg 3 (freq) cannot exceed half sampling frequency.' ); elseif ( pad_fact==2 && any(freq<0) ) error( 'ar_psd: arg 3 (freq) must be positive in onesided spectrum' ); endif freq_len = length(freq); fft_len = freq_len; use_FFT = 0; do_shift = 0; else ## internally generated frequencies freq_len = freq; freq = (Fs/pad_fact/freq_len) * [0:freq_len-1]'; ## decide which method to use (poly or FFT) is_power_of_2 = rem(log(freq_len),log(2))<10.*eps; use_FFT = ( ~ force_poly && is_power_of_2 ) || force_FFT; fft_len = freq_len * pad_fact; endif ## ## calculate denominator of Equation 2.28, Kay and Marple, ref [1]Jr.: len_coeffs = length(a); if ( use_FFT ) ## FFT method fft_out = fft( [ a(:); zeros(fft_len-len_coeffs,1) ] ); else ## polynomial method ## complex data on "half" frequency range needs -ve frequency values if ( pad_fact==2 && ~real_model ) freq = [freq; -freq(freq_len:-1:1)]; fft_len = 2*freq_len; endif fft_out = polyval( a(len_coeffs:-1:1), exp( (-i*2*pi/Fs) * freq ) ); endif ## ## The power spectrum (PSD) is the scaled squared reciprocal of amplitude ## of the FFT/polynomial. This is NOT the reciprocal of the periodogram. ## The PSD is a continuous function of frequency. For uniformly ## distributed frequency values, the FFT algorithm might be the most ## efficient way of calculating it. ## psd = ( v / Fs ) ./ ( fft_out .* conj(fft_out) ); ## ## range='half' or 'onesided', ## add PSD at -ve frequencies to PSD at +ve frequencies ## N.B. unlike periodogram, PSD at zero frequency _is_ doubled. if ( pad_fact==2 ) freq = freq(1:freq_len); if ( real_model ) ## real data, double the psd psd = 2 * psd(1:freq_len); elseif ( use_FFT ) ## complex data, FFT method, internally-generated frequencies psd = psd(1:freq_len)+[psd(1); psd(fft_len:-1:freq_len+2)]; else ## complex data, polynomial method ## user-defined and internally-generated frequencies psd = psd(1:freq_len)+psd(fft_len:-1:freq_len+1); endif ## ## range='shift' ## disabled for user-supplied frequencies ## Shift zero-frequency to the middle (pad_fact==1) elseif ( do_shift ) len2 = fix((fft_len+1)/2); psd = [psd(len2+1:fft_len); psd(1:len2)]; freq = [freq(len2+1:fft_len)-Fs; freq(1:len2)]; endif ## ## Plot the spectrum if there are no return variables. if ( nargout >= 2 ) varargout{1} = psd; varargout{2} = freq; elseif ( nargout == 1 ) varargout{1} = psd; else if ( plot_type == 1 ) plot(freq,psd); elseif ( plot_type == 2 ) semilogx(freq,psd); elseif ( plot_type == 3 ) semilogy(freq,psd); elseif ( plot_type == 4 ) loglog(freq,psd); elseif ( plot_type == 5 ) plot(freq,10*log10(psd)); endif endif endif endfunction signal-1.3.2/inst/PaxHeaders.4544/ellip.m0000644000000000000000000000013212530736314014713 xustar0030 mtime=1432599756.806409466 30 atime=1432599756.806409466 30 ctime=1432599756.854411378 signal-1.3.2/inst/ellip.m0000644000000000000000000001240712530736314015240 0ustar00rootroot00000000000000## Copyright (C) 2001 Paulo Neis ## Copyright (C) 2003 Doug Stewart ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## - Kienzle, Paul, functions from Octave-Forge, 1999 (http://octave.sf.net). ## @end deftypefn function [a, b, c, d] = ellip (n, rp, rs, w, varargin) if (nargin > 6 || nargin < 4 || nargout > 4 || nargout < 2) print_usage (); endif ## interpret the input parameters if (! (isscalar (n) && (n == fix (n)) && (n > 0))) error ("ellip: filter order N must be a positive integer"); endif stop = false; digital = true; for i = 1:numel (varargin) switch (varargin{i}) case "s" digital = false; case "z" digital = true; case {"high", "stop"} stop = true; case {"low", "pass"} stop = false; otherwise error ("ellip: expected [high|stop] or [s|z]"); endswitch endfor if (! ((numel (w) <= 2) && (rows (w) == 1 || columns (w) == 1))) error ("ellip: frequency must be given as WC or [WL, WH]"); elseif ((numel (w) == 2) && (w(2) <= w(1))) error ("ellip: W(1) must be less than W(2)"); endif if (digital && ! all ((w >= 0) & (w <= 1))) error ("ellip: all elements of W must be in the range [0,1]"); elseif (! digital && ! all (w >= 0)) error ("ellip: all elements of W must be in the range [0,inf]"); endif if (! (isscalar (rp) && isnumeric (rp) && (rp >= 0))) error ("ellip: passband ripple RP must be a non-negative scalar"); endif if (! (isscalar (rs) && isnumeric (rs) && (rs >= 0))) error ("ellip: stopband attenuation RS must be a non-negative scalar"); endif ## Prewarp the digital frequencies if (digital) T = 2; # sampling frequency of 2 Hz w = 2 / T * tan (pi * w / T); endif ## Generate s-plane poles, zeros and gain [zero, pole, gain] = ncauer (rp, rs, n); ## splane frequency transform [zero, pole, gain] = sftrans (zero, pole, gain, w, stop); ## Use bilinear transform to convert poles to the z plane if (digital) [zero, pole, gain] = bilinear (zero, pole, gain, T); endif ## convert to the correct output form if (nargout == 2) a = real (gain * poly (zero)); b = real (poly (pole)); elseif (nargout == 3) a = zero; b = pole; c = gain; else ## output ss results [a, b, c, d] = zp2ss (zero, pole, gain); endif endfunction %!demo %! [n, Ws] = ellipord ([.1 .2], [.01 .4], 1, 90); %! [b, a] = ellip (5, 1, 90, [.1 .2]); %! [h, w] = freqz (b, a); %! %! plot (w./pi, 20*log10 (abs (h)), ";;") %! xlabel ("Frequency"); %! ylabel ("abs(H[w])[dB]"); %! axis ([0, 1, -100, 0]); %! %! hold ("on"); %! x=ones (1, length (h)); %! plot (w./pi, x.*-1, ";-1 dB;") %! plot (w./pi, x.*-90, ";-90 dB;") %! hold ("off"); %% Test input validation %!error [a, b] = ellip () %!error [a, b] = ellip (1) %!error [a, b] = ellip (1, 2) %!error [a, b] = ellip (1, 2, 3) %!error [a, b] = ellip (1, 2, 3, 4, 5, 6, 7) %!error [a, b] = ellip (.5, 2, 40, .2) %!error [a, b] = ellip (3, 2, 40, .2, "invalid") signal-1.3.2/inst/PaxHeaders.4544/qp_kaiser.m0000644000000000000000000000013212530736314015564 xustar0030 mtime=1432599756.826410262 30 atime=1432599756.826410262 30 ctime=1432599756.854411378 signal-1.3.2/inst/qp_kaiser.m0000644000000000000000000000547412530736314016117 0ustar00rootroot00000000000000## Copyright (C) 2002 André Carezia ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function h = qp_kaiser (nb, at, linear = 0) if (nargin < 2) print_usage; elseif !(isscalar (nb) && (nb == round(nb)) && (nb >= 0)) error ("qp_kaiser: nb has to be a positive integer"); elseif !(isscalar (at) && (at == real (at))) error ("qp_kaiser: at has to be a real constant"); endif ## Bandwidth bandwidth = pi/nb; ## Attenuation correction (empirically ## determined by M. Gerken ## ) corr = (1.4+0.6*(at-20)/80)^(20/at); at = corr * at; ## size of window (rounded to next odd ## integer) N = (at - 8) / (2.285*bandwidth); M = fix(N/2); N = 2*M + 1; ## Kaiser window if (at>50) beta = 0.1102 * (at - 8.7); elseif (at>21) beta = 0.5842 * (at - 21)^0.4 + 0.07886 * (at - 21); else beta = 0; endif w = kaiser(N,beta); ## squared in freq. domain wsquared = conv(w,w); ## multiplied by ideal lowpass filter n = -(N-1):(N-1); hideal = 1/nb * sinc(n/nb); hcomp = wsquared .* hideal; ## extract square-root of response and ## compute minimum-phase version Ndft = 2^15; Hsqr = sqrt(abs(fft(hcomp,Ndft))); if (linear) h = real(ifft(Hsqr)); h = h(2:N); h = [fliplr(h) h(1) h]; else Hmin = Hsqr .* exp(-j*imag(hilbert(log(Hsqr)))); h = real(ifft(Hmin)); h = h(1:N); endif ## truncate and fix amplitude scale ## (H(0)=1) h = h / sum(h); endfunction signal-1.3.2/inst/PaxHeaders.4544/cheby2.m0000644000000000000000000000013212530736314014762 xustar0030 mtime=1432599756.798409147 30 atime=1432599756.798409147 30 ctime=1432599756.854411378 signal-1.3.2/inst/cheby2.m0000644000000000000000000001256012530736314015307 0ustar00rootroot00000000000000## Copyright (C) 1999 Paul Kienzle ## Copyright (C) 2003 Doug Stewart ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function [a, b, c, d] = cheby2 (n, rs, w, varargin) if (nargin > 5 || nargin < 3 || nargout > 4 || nargout < 2) print_usage (); endif ## interpret the input parameters if (! (isscalar (n) && (n == fix (n)) && (n > 0))) error ("cheby2: filter order N must be a positive integer"); endif stop = false; digital = true; for i = 1:numel (varargin) switch (varargin{i}) case "s" digital = false; case "z" digital = true; case {"high", "stop"} stop = true; case {"low", "pass"} stop = false; otherwise error ("cheby2: expected [high|stop] or [s|z]"); endswitch endfor if (! ((numel (w) <= 2) && (rows (w) == 1 || columns (w) == 1))) error ("cheby2: frequency must be given as WC or [WL, WH]"); elseif ((numel (w) == 2) && (w(2) <= w(1))) error ("cheby2: W(1) must be less than W(2)"); endif if (digital && ! all ((w >= 0) & (w <= 1))) error ("cheby2: all elements of W must be in the range [0,1]"); elseif (! digital && ! all (w >= 0)) error ("cheby2: all elements of W must be in the range [0,inf]"); endif if (! (isscalar (rs) && isnumeric (rs) && (rs >= 0))) error ("cheby2: stopband attenuation RS must be a non-negative scalar"); endif ## Prewarp to the band edges to s plane if (digital) T = 2; # sampling frequency of 2 Hz w = 2 / T * tan (pi * w / T); endif ## Generate splane poles and zeros for the Chebyshev type 2 filter ## From: Stearns, SD; David, RA; (1988). Signal Processing Algorithms. ## New Jersey: Prentice-Hall. C = 1; ## default cutoff frequency lambda = 10^(rs / 20); phi = log (lambda + sqrt (lambda^2 - 1)) / n; theta = pi * ([1:n] - 0.5) / n; alpha = -sinh (phi) * sin (theta); beta = cosh (phi) * cos (theta); if (rem (n, 2)) ## drop theta==pi/2 since it results in a zero at infinity zero = 1i * C ./ cos (theta([1:(n - 1) / 2, (n + 3) / 2:n])); else zero = 1i * C ./ cos (theta); endif pole = C ./ (alpha.^2 + beta.^2) .* (alpha - 1i * beta); ## Compensate for amplitude at s=0 ## Because of the vagaries of floating point computations, the ## prod(pole)/prod(zero) sometimes comes out as negative and ## with a small imaginary component even though analytically ## the gain will always be positive, hence the abs(real(...)) gain = abs (real (prod (pole) / prod (zero))); ## splane frequency transform [zero, pole, gain] = sftrans (zero, pole, gain, w, stop); ## Use bilinear transform to convert poles to the z plane if (digital) [zero, pole, gain] = bilinear (zero, pole, gain, T); endif ## convert to the correct output form if (nargout == 2) a = real (gain * poly (zero)); b = real (poly (pole)); elseif (nargout == 3) a = zero; b = pole; c = gain; else ## output ss results [a, b, c, d] = zp2ss (zero, pole, gain); endif endfunction %% Test input validation %!error [a, b] = cheby2 () %!error [a, b] = cheby2 (1) %!error [a, b] = cheby2 (1, 2) %!error [a, b] = cheby2 (1, 2, 3, 4, 5, 6) %!error [a, b] = cheby2 (.5, 40, .2) %!error [a, b] = cheby2 (3, 40, .2, "invalid") signal-1.3.2/inst/PaxHeaders.4544/tfestimate.m0000644000000000000000000000013212530736314015753 xustar0030 mtime=1432599756.834410581 30 atime=1432599756.834410581 30 ctime=1432599756.854411378 signal-1.3.2/inst/tfestimate.m0000644000000000000000000000447112530736314016302 0ustar00rootroot00000000000000## Copyright (C) 2006 Peter V. Lanspeary ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## @seealso{pwelch} ## @end deftypefn function varargout = tfestimate(varargin) ## ## Check fixed argument if (nargin < 2 || nargin > 7) print_usage (); endif nvarargin = length(varargin); ## remove any pwelch RESULT args and add 'cross' for iarg=1:nvarargin arg = varargin{iarg}; if ( ~isempty(arg) && ischar(arg) && ( strcmp(arg,'power') || ... strcmp(arg,'cross') || strcmp(arg,'trans') || ... strcmp(arg,'coher') || strcmp(arg,'ypower') )) varargin{iarg} = []; endif endfor varargin{nvarargin+1} = 'trans'; ## if ( nargout==0 ) pwelch(varargin{:}); elseif ( nargout==1 ) Pxx = pwelch(varargin{:}); varargout{1} = Pxx; elseif ( nargout>=2 ) [Pxx,f] = pwelch(varargin{:}); varargout{1} = Pxx; varargout{2} = f; endif endfunction signal-1.3.2/inst/PaxHeaders.4544/cheb2ap.m0000644000000000000000000000013212530736314015112 xustar0030 mtime=1432599756.798409147 30 atime=1432599756.798409147 30 ctime=1432599756.854411378 signal-1.3.2/inst/cheb2ap.m0000644000000000000000000000260512530736314015436 0ustar00rootroot00000000000000## Copyright (C) 2013 Carnë Draug ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, see . ## -*- texinfo -*- ## @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")}. ## ## @seealso{cheby2} ## @end deftypefn function [z, p, g] = cheb2ap (n, Rp) if (nargin != 2) print_usage(); elseif (! isscalar (n) || ! isnumeric (n) || fix (n) != n || n <= 0) error ("cheb2ap: N must be a positive integer") elseif (! isscalar (Rs) || ! isnumeric (Rs) || Rs < 0) error ("cheb2ap: RS must be a non-negative scalar") endif [z, p, g] = cheby2 (n, Rs, 1, "s"); endfunction signal-1.3.2/inst/PaxHeaders.4544/__power.m0000644000000000000000000000013212530736314015240 xustar0030 mtime=1432599756.790408828 30 atime=1432599756.786408669 30 ctime=1432599756.854411378 signal-1.3.2/inst/__power.m0000644000000000000000000000605312530736314015565 0ustar00rootroot00000000000000## Copyright (C) 1999 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## FIXME: consider folding this into freqz --- just one more parameter to ## distinguish between 'linear', 'log', 'logsquared' and 'squared' function varargout = __power (b, a, varargin) if (nargin < 2 || nargin > 6) print_usage; endif nfft = []; Fs = []; range = []; range_fact = 1.0; units = []; pos = 0; for i=1:length(varargin) arg = varargin{i}; if strcmp(arg, 'squared') || strcmp(arg, 'db') units = arg; elseif strcmp(arg, 'whole') range = arg; range_fact = 1.0; elseif strcmp(arg, 'half') range = arg; range_fact = 2.0; elseif ischar(arg) usage(usagestr); elseif pos == 0 nfft = arg; pos++; elseif pos == 1 Fs = arg; pos++; else usage(usagestr); endif endfor if isempty(nfft); nfft = 256; endif if isempty(Fs); Fs = 2; endif if isempty(range) range = 'half'; range_fact = 2.0; endif [P, w] = freqz(b, a, nfft, range, Fs); P = (range_fact/Fs)*(P.*conj(P)); if nargout == 0, if strcmp(units, 'squared') plot(w, P, ";;"); else plot(w, 10.0*log10(abs(P)), ";;"); endif endif if nargout >= 1, varargout{1} = P; endif if nargout >= 2, varargout{2} = w; endif endfunction signal-1.3.2/inst/PaxHeaders.4544/clustersegment.m0000644000000000000000000000013212530736314016652 xustar0030 mtime=1432599756.798409147 30 atime=1432599756.798409147 30 ctime=1432599756.854411378 signal-1.3.2/inst/clustersegment.m0000644000000000000000000000505012530736314017173 0ustar00rootroot00000000000000## Copyright (c) 2010 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, see . ## -*- texinfo -*- ## @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 function contRange = clustersegment(xhi) ## Find discontinuities bool_discon = diff(xhi,1,2); [Np Na] = size(xhi); contRange = cell(1,Np); for i = 1:Np idxUp = find(bool_discon(i,:)>0)+1; idxDwn = find(bool_discon(i,:)<0); tLen = length(idxUp) + length(idxDwn); if xhi(i,1)==1 ## first event was down contRange{i}(1) = 1; contRange{i}(2:2:tLen+1) = idxDwn; contRange{i}(3:2:tLen+1) = idxUp; else ## first event was up contRange{i}(1:2:tLen) = idxUp; contRange{i}(2:2:tLen) = idxDwn; endif if xhi(i,end)==1 ## last event was up contRange{i}(end+1) = Na; endif tLen = length(contRange{i}); if tLen ~=0 contRange{i}=reshape(contRange{i},2,tLen/2); endif endfor if Np == 1 contRange = cell2mat (contRange); endif endfunction %!demo %! xhi = [0 0 1 1 1 0 0 1 0 0 0 1 1]; %! ranges = clustersegment (xhi) %! %! % The first sequence of 1's in xhi lies in the interval %! ranges(1,1):ranges(2,1) %!demo %! xhi = rand(3,10)>0.4 %! ranges = clustersegment(xhi) signal-1.3.2/inst/PaxHeaders.4544/tukeywin.m0000644000000000000000000000013212530736314015465 xustar0030 mtime=1432599756.838410741 30 atime=1432599756.838410741 30 ctime=1432599756.854411378 signal-1.3.2/inst/tukeywin.m0000644000000000000000000000516212530736314016012 0ustar00rootroot00000000000000## Copyright (C) 2007 Laurent Mazet ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 0 and a full box for @var{r} equals to 1. 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. ## @seealso{hanning} ## @end deftypefn function w = tukeywin (m, r = 1/2) if (nargin < 1 || nargin > 2) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("tukeywin: M must be a positive integer"); elseif (nargin == 2) ## check that 0 < r < 1 if r > 1 r = 1; elseif r < 0 r = 0; endif endif ## generate window switch r case 0, ## full box w = ones (m, 1); case 1, ## Hanning window w = hanning (m); otherwise ## cosine-tapered window t = linspace(0,1,m)(1:end/2)'; w = (1 + cos(pi*(2*t/r-1)))/2; w(floor(r*(m-1)/2)+2:end) = 1; w = [w; ones(mod(m,2)); flipud(w)]; endswitch endfunction %!demo %! m = 100; %! r = 1/3; %! w = tukeywin (m, r); %! title(sprintf("%d-point Tukey window, R = %d/%d", m, [p, q] = rat(r), q)); %! plot(w); %!assert (tukeywin (1), 1) %!assert (tukeywin (2), zeros (2, 1)) %!assert (tukeywin (3), [0; 1; 0]) %!assert (tukeywin (16, 0), rectwin (16)) %!assert (tukeywin (16, 1), hanning (16)) %% Test input validation %!error tukeywin () %!error tukeywin (0.5) %!error tukeywin (-1) %!error tukeywin (ones (1, 4)) %!error tukeywin (1, 2, 3) signal-1.3.2/inst/PaxHeaders.4544/hilbert.m0000644000000000000000000000013212530736314015237 xustar0030 mtime=1432599756.814409784 30 atime=1432599756.814409784 30 ctime=1432599756.854411378 signal-1.3.2/inst/hilbert.m0000644000000000000000000000752612530736314015572 0ustar00rootroot00000000000000## Copyright (C) 2000 Paul Kienzle ## Copyright (C) 2007 Peter L. Soendergaard ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function f=hilbert(f, N = [], dim = []) ## ------ PRE: initialization and dimension shifting --------- if (nargin<1 || nargin>3) print_usage; endif if ~isreal(f) warning ('HILBERT: ignoring imaginary part of signal'); f = real (f); endif D=ndims(f); ## Dummy assignment. order=1; if isempty(dim) dim=1; if sum(size(f)>1)==1 ## We have a vector, find the dimension where it lives. dim=find(size(f)>1); endif else if (numel(dim)~=1 || ~isnumeric(dim)) error('HILBERT: dim must be a scalar.'); endif if rem(dim,1)~=0 error('HILBERT: dim must be an integer.'); endif if (dim<1) || (dim>D) error('HILBERT: dim must be in the range from 1 to %d.',D); endif endif if (numel(N)>1 || ~isnumeric(N)) error('N must be a scalar.'); elseif (~isempty(N) && rem(N,1)~=0) error('N must be an integer.'); endif if dim>1 order=[dim, 1:dim-1,dim+1:D]; ## Put the desired dimension first. f=permute(f,order); endif Ls=size(f,1); ## If N is empty it is set to be the length of the transform. if isempty(N) N=Ls; endif ## Remember the exact size for later and modify it for the new length permutedsize=size(f); permutedsize(1)=N; ## Reshape f to a matrix. f=reshape(f,size(f,1),numel(f)/size(f,1)); W=size(f,2); if ~isempty(N) f=postpad(f,N); endif ## ------- actual computation ----------------- if N>2 f=fft(f); if rem(N,2)==0 f=[f(1,:); 2*f(2:N/2,:); f(N/2+1,:); zeros(N/2-1,W)]; else f=[f(1,:); 2*f(2:(N+1)/2,:); zeros((N-1)/2,W)]; endif f=ifft(f); endif ## ------- POST: Restoration of dimensions ------------ ## Restore the original, permuted shape. f=reshape(f,permutedsize); if dim>1 ## Undo the permutation. f=ipermute(f,order); endif endfunction %!demo %! ## notice that the imaginary signal is phase-shifted 90 degrees %! t=linspace(0,10,256); %! z = hilbert(sin(2*pi*0.5*t)); %! grid on; plot(t,real(z),';real;',t,imag(z),';imag;'); %!demo %! ## the magnitude of the hilbert transform eliminates the carrier %! t=linspace(0,10,1024); %! x=5*cos(0.2*t).*sin(100*t); %! grid on; plot(t,x,'g;z;',t,abs(hilbert(x)),'b;|hilbert(z)|;'); signal-1.3.2/inst/PaxHeaders.4544/bohmanwin.m0000644000000000000000000000013212530736314015570 xustar0030 mtime=1432599756.794408987 30 atime=1432599756.794408987 30 ctime=1432599756.854411378 signal-1.3.2/inst/bohmanwin.m0000644000000000000000000000277612530736314016125 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} bohmanwin (@var{m}) ## Return the filter coefficients of a Bohman window of length @var{m}. ## @seealso{rectwin, bartlett} ## @end deftypefn function w = bohmanwin (m) if (nargin != 1) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("bohmanwin: M must be a positive integer"); endif if (m == 1) w = 1; else N = m - 1; n = -N/2:N/2; w = (1-2.*abs(n)./N).*cos(2.*pi.*abs(n)./N) + (1./pi).*sin(2.*pi.*abs(n)./N); w(1) = 0; w(length(w))=0; w = w'; endif endfunction %!assert (bohmanwin (1), 1) %!assert (bohmanwin (2), zeros (2, 1)) %% Test input validation %!error bohmanwin () %!error bohmanwin (0.5) %!error bohmanwin (-1) %!error bohmanwin (ones (1, 4)) %!error bohmanwin (1, 2) signal-1.3.2/inst/PaxHeaders.4544/ss2zp.m0000644000000000000000000000013212530736314014667 xustar0030 mtime=1432599756.834410581 30 atime=1432599756.834410581 30 ctime=1432599756.854411378 signal-1.3.2/inst/ss2zp.m0000644000000000000000000000231612530736314015212 0ustar00rootroot00000000000000## Copyright (C) 1994, 1996, 2000, 2004, 2005, 2006, 2007 Auburn University ## Copyright (C) 2012 Lukas F. Reichlin ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{p}, @var{z}, @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 ## Author: David Clem function [z, p, k] = ss2zp (varargin) if (nargin == 0) print_usage (); endif [z, p, k] = zpkdata (ss (varargin{:}), "vector"); endfunction signal-1.3.2/inst/PaxHeaders.4544/pyulear.m0000644000000000000000000000013212530736314015267 xustar0030 mtime=1432599756.826410262 30 atime=1432599756.826410262 30 ctime=1432599756.854411378 signal-1.3.2/inst/pyulear.m0000644000000000000000000001160312530736314015611 0ustar00rootroot00000000000000## Copyright (C) 2006 Peter V. Lanspeary ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## usage: ## [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. ## x %% [vector] sampled data ## ## poles %% [integer scalar] required number of poles of the AR model ## ## 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] ## ## Fs %% [real scalar] sampling frequency (Hertz) [default=1] ## ## ## 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 return values are not required by the caller, the spectrum ## is plotted and nothing is returned. ## psd %% [real vector] power-spectrum estimate ## f_out %% [real vector] frequency values ## ## HINTS ## This function is a wrapper for aryule and ar_psd. ## See "help aryule", "help ar_psd". function [psd,f_out]=pyulear(x,poles,varargin) ## if ( nargin<2 ) error( 'pburg: need at least 2 args. Use "help pburg"' ); endif ## [ar_coeffs,residual,k]=aryule(x,poles); if ( nargout==0 ) ar_psd(ar_coeffs,residual,varargin{:}); elseif ( nargout==1 ) psd = ar_psd(ar_coeffs,residual,varargin{:}); elseif ( nargout>=2 ) [psd,f_out] = ar_psd(ar_coeffs,residual,varargin{:}); endif endfunction %!demo %! rand ("seed", 2038014164); %! a = [1.0 -1.6216505 1.1102795 -0.4621741 0.2075552 -0.018756746]; %! Fs = 25; %! n = 16384; %! signal = detrend (filter (0.70181, a, rand (1, n))); %! % frequency shift by modulating with exp(j.omega.t) %! skewed = signal .* exp (2*pi*i*2/Fs*[1:n]); %! hold on %! pyulear (signal, 3, [], Fs); %! pyulear (signal, 4, [], Fs, "whole"); %! pyulear (signal, 5, 128, Fs, "shift", "semilogy"); %! pyulear (skewed, 7, 128, Fs, "shift", "semilogy"); %! user_freq = [-0.2:0.02:0.2]*Fs; %! pyulear (skewed, 7, user_freq, Fs, "semilogy"); %! hold off signal-1.3.2/inst/PaxHeaders.4544/nuttallwin.m0000644000000000000000000000013212530736314016007 xustar0030 mtime=1432599756.822410103 30 atime=1432599756.822410103 30 ctime=1432599756.854411378 signal-1.3.2/inst/nuttallwin.m0000644000000000000000000000504212530736314016331 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## ## @seealso{blackman, blackmanharris} ## @end deftypefn function w = nuttallwin (m, opt) if (nargin < 1 || nargin > 2) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("nuttallwin: M must be a positive integer"); endif N = m - 1; if (nargin == 2) switch (opt) case "periodic" N = m; case "symmetric" N = m - 1; otherwise error ("nuttallwin: window type must be either \"periodic\" or \"symmetric\""); endswitch endif if (m == 1) w = 1; else a0 = 0.355768; a1 = 0.487396; a2 = 0.144232; a3 = 0.012604; n = [-N/2:(m-1)/2]'; w = a0 + a1.*cos(2.*pi.*n./N) + a2.*cos(4.*pi.*n./N) + a3.*cos(6.*pi.*n./N); endif endfunction %!assert (nuttallwin (1), 1) %!assert (nuttallwin (2), zeros (2, 1), eps) %!assert (nuttallwin (15), flipud (nuttallwin (15)), 10*eps); %!assert (nuttallwin (16), flipud (nuttallwin (16)), 10*eps); %!assert (nuttallwin (15), nuttallwin (15, "symmetric")); %!assert (nuttallwin (16)(1:15), nuttallwin (15, "periodic")); %% Test input validation %!error nuttallwin () %!error nuttallwin (0.5) %!error nuttallwin (-1) %!error nuttallwin (ones (1, 4)) %!error nuttallwin (1, 2) %!error nuttallwin (1, "invalid") signal-1.3.2/inst/PaxHeaders.4544/zp2sos.m0000644000000000000000000000012612530736314015051 xustar0028 mtime=1432599756.8424109 28 atime=1432599756.8424109 30 ctime=1432599756.854411378 signal-1.3.2/inst/zp2sos.m0000644000000000000000000001040112530736314015363 0ustar00rootroot00000000000000## Copyright (C) 2005 Julius O. Smith III ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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}.' = [1 a1 a2]} for ## section 1, etc. The b0 entry must be nonzero for each section. ## 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 ## ## @seealso{sos2pz, sos2tf, tf2sos, zp2tf, tf2zp} ## @end deftypefn function [sos,g] = zp2sos(z,p,k) if nargin<3, k=1; endif if nargin<2, p=[]; endif [zc,zr] = cplxreal(z(:)); [pc,pr] = cplxreal(p(:)); ## zc,zr,pc,pr nzc=length(zc); npc=length(pc); nzr=length(zr); npr=length(pr); ## Pair up real zeros: if nzr if mod(nzr,2)==1, zr=[zr;0]; nzr=nzr+1; endif nzrsec = nzr/2; zrms = -zr(1:2:nzr-1)-zr(2:2:nzr); zrp = zr(1:2:nzr-1).*zr(2:2:nzr); else nzrsec = 0; endif ## Pair up real poles: if npr if mod(npr,2)==1, pr=[pr;0]; npr=npr+1; endif nprsec = npr/2; prms = -pr(1:2:npr-1)-pr(2:2:npr); prp = pr(1:2:npr-1).*pr(2:2:npr); else nprsec = 0; endif nsecs = max(nzc+nzrsec,npc+nprsec); ## Convert complex zeros and poles to real 2nd-order section form: zcm2r = -2*real(zc); zca2 = abs(zc).^2; pcm2r = -2*real(pc); pca2 = abs(pc).^2; sos = zeros(nsecs,6); sos(:,1) = ones(nsecs,1); # all 2nd-order polynomials are monic sos(:,4) = ones(nsecs,1); nzrl=nzc+nzrsec; # index of last real zero section nprl=npc+nprsec; # index of last real pole section for i=1:nsecs if i<=nzc # lay down a complex zero pair: sos(i,2:3) = [zcm2r(i) zca2(i)]; elseif i<=nzrl # lay down a pair of real zeros: sos(i,2:3) = [zrms(i-nzc) zrp(i-nzc)]; endif if i<=npc # lay down a complex pole pair: sos(i,5:6) = [pcm2r(i) pca2(i)]; elseif i<=nprl # lay down a pair of real poles: sos(i,5:6) = [prms(i-npc) prp(i-npc)]; endif endfor ## If no output argument for the overall gain, combine it into the ## first section. if (nargout < 2) sos(1,1:3) *= k; else g = k; endif endfunction %!test %! B=[1 0 0 0 0 1]; A=[1 0 0 0 0 .9]; %! [z,p,k] = tf2zp(B,A); %! [sos,g] = zp2sos(z,p,k); %! [Bh,Ah] = sos2tf(sos,g); %! assert({Bh,Ah},{B,A},100*eps); signal-1.3.2/inst/PaxHeaders.4544/sgolay.m0000644000000000000000000000013212530736314015104 xustar0030 mtime=1432599756.830410422 30 atime=1432599756.830410422 30 ctime=1432599756.854411378 signal-1.3.2/inst/sgolay.m0000644000000000000000000001037412530736314015432 0ustar00rootroot00000000000000## Copyright (C) 2001 Paul Kienzle ## Copyright (C) 2004 Pascal Dupuis ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## ## @seealso{sgolayfilt} ## @end deftypefn ## Based on smooth.m by E. Farhi function F = sgolay (p, n, m = 0, ts = 1) if (nargin < 2 || nargin > 4) print_usage; elseif rem(n,2) != 1 error ("sgolay needs an odd filter length n"); elseif p >= n error ("sgolay needs filter length n larger than polynomial order p"); else if length(m) > 1, error("weight vector unimplemented"); endif ## Construct a set of filters from complete causal to completely ## noncausal, one filter per row. For the bulk of your data you ## will use the central filter, but towards the ends you will need ## a filter that doesn't go beyond the end points. F = zeros (n, n); k = floor (n/2); for row = 1:k+1 ## Construct a matrix of weights Cij = xi ^ j. The points xi are ## equally spaced on the unit grid, with past points using negative ## values and future points using positive values. C = ( [(1:n)-row]'*ones(1,p+1) ) .^ ( ones(n,1)*[0:p] ); ## A = pseudo-inverse (C), so C*A = I; this is constructed from the SVD A = pinv(C); ## Take the row of the matrix corresponding to the derivative ## you want to compute. F(row,:) = A(1+m,:); endfor ## The filters shifted to the right are symmetric with those to the left. F(k+2:n,:) = (-1)^m*F(k:-1:1,n:-1:1); endif F = F * ( prod(1:m) / (ts^m) ); endfunction %!test %! N=2^12; %! t=[0:N-1]'/N; %! dt=t(2)-t(1); %! w = 2*pi*50; %! offset = 0.5; # 50 Hz carrier %! # exponential modulation and its derivatives %! d = 1+exp(-3*(t-offset)); %! dd = -3*exp(-3*(t-offset)); %! d2d = 9*exp(-3*(t-offset)); %! d3d = -27*exp(-3*(t-offset)); %! # modulated carrier and its derivatives %! x = d.*sin(w*t); %! dx = dd.*sin(w*t) + w*d.*cos(w*t); %! d2x = (d2d-w^2*d).*sin(w*t) + 2*w*dd.*cos(w*t); %! d3x = (d3d-3*w^2*dd).*sin(w*t) + (3*w*d2d-w^3*d).*cos(w*t); %! %! y = sgolayfilt(x,sgolay(8,41,0,dt)); %! assert(norm(y-x)/norm(x),0,5e-6); %! %! y = sgolayfilt(x,sgolay(8,41,1,dt)); %! assert(norm(y-dx)/norm(dx),0,5e-6); %! %! y = sgolayfilt(x,sgolay(8,41,2,dt)); %! assert(norm(y-d2x)/norm(d2x),0,1e-5); %! %! y = sgolayfilt(x,sgolay(8,41,3,dt)); %! assert(norm(y-d3x)/norm(d3x),0,1e-4); signal-1.3.2/inst/PaxHeaders.4544/grpdelay.m0000644000000000000000000000013212530736314015415 xustar0030 mtime=1432599756.814409784 30 atime=1432599756.814409784 30 ctime=1432599756.854411378 signal-1.3.2/inst/grpdelay.m0000644000000000000000000002721412530736314015744 0ustar00rootroot00000000000000## Copyright (C) 2000 Paul Kienzle ## Copyright (C) 2004 Julius O. Smith III ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function [gd, w] = grpdelay (b, a = 1, nfft = 512, whole, Fs) if (nargin < 1 || nargin > 5) print_usage (); endif HzFlag = false; if (length (nfft) > 1) if (nargin > 4) print_usage (); elseif (nargin > 3) ## grpdelay (B, A, F, Fs) Fs = whole; HzFlag = true; else ## grpdelay (B, A, W) Fs = 1; endif w = 2*pi*nfft/Fs; nfft = length (w) * 2; whole = ""; else if (nargin < 5) Fs = 1; # return w in radians per sample if (nargin < 4) whole = ""; elseif (! ischar (whole)) Fs = whole; HzFlag = true; whole = ""; endif if (nargin < 3) nfft = 512; endif if (nargin < 2) a = 1; endif else HzFlag = true; endif if (isempty (nfft)) nfft = 512; endif if (! strcmp (whole, "whole")) nfft = 2*nfft; endif w = Fs*[0:nfft-1]/nfft; endif if (! HzFlag) w = w * 2 * pi; endif ## Make sure both are row vector a = a(:).'; b = b(:).'; oa = length (a) -1; # order of a(z) if (oa < 0) # a can be [] a = 1; oa = 0; endif ob = length (b) -1; # order of b(z) if (ob < 0) # b can be [] as well b = 1; ob = 0; endif oc = oa + ob; # order of c(z) c = conv (b, fliplr (conj (a))); # c(z) = b(z)*conj(a)(1/z)*z^(-oa) cr = c.*(0:oc); # cr(z) = derivative of c wrt 1/z num = fft (cr, nfft); den = fft (c, nfft); minmag = 10*eps; polebins = find (abs (den) < minmag); for b = polebins warning ("grpdelay: setting group delay to 0 at singularity"); num(b) = 0; den(b) = 1; ## try to preserve angle: ## db = den(b); ## den(b) = minmag*abs(num(b))*exp(j*atan2(imag(db),real(db))); ## warning(sprintf('grpdelay: den(b) changed from %f to %f',db,den(b))); endfor gd = real (num ./ den) - oa; if (! strcmp (whole, "whole")) ns = nfft/2; # Matlab convention ... should be nfft/2 + 1 gd = gd(1:ns); w = w(1:ns); else ns = nfft; # used in plot below endif ## compatibility gd = gd(:); w = w(:); if (nargout == 0) unwind_protect grid ("on"); # grid() should return its previous state if (HzFlag) funits = "Hz"; else funits = "radian/sample"; endif xlabel (["Frequency (" funits ")"]); ylabel ("Group delay (samples)"); plot (w(1:ns), gd(1:ns), ";;"); unwind_protect_cleanup grid ("on"); end_unwind_protect endif endfunction ## ------------------------ DEMOS ----------------------- %!demo % 1 %! %-------------------------------------------------------------- %! % From Oppenheim and Schafer, a single zero of radius r=0.9 at %! % angle pi should have a group delay of about -9 at 1 and 1/2 %! % at zero and 2*pi. %! %-------------------------------------------------------------- %! grpdelay([1 0.9],[],512,'whole',1); %! hold on; %! xlabel('Normalized Frequency (cycles/sample)'); %! stem([0, 0.5, 1],[0.5, -9, 0.5],'*b;target;'); %! hold off; %! title ('Zero at z = -0.9'); %! %!demo % 2 %! %-------------------------------------------------------------- %! % confirm the group delays approximately meet the targets %! % don't worry that it is not exact, as I have not entered %! % the exact targets. %! %-------------------------------------------------------------- %! b = poly([1/0.9*exp(1i*pi*0.2), 0.9*exp(1i*pi*0.6)]); %! a = poly([0.9*exp(-1i*pi*0.6), 1/0.9*exp(-1i*pi*0.2)]); %! grpdelay(b,a,512,'whole',1); %! hold on; %! xlabel('Normalized Frequency (cycles/sample)'); %! stem([0.1, 0.3, 0.7, 0.9], [9, -9, 9, -9],'*b;target;'); %! hold off; %! title ('Two Zeros and Two Poles'); %!demo % 3 %! %-------------------------------------------------------------- %! % fir lowpass order 40 with cutoff at w=0.3 and details of %! % the transition band [.3, .5] %! %-------------------------------------------------------------- %! subplot(211); %! Fs = 8000; % sampling rate %! Fc = 0.3*Fs/2; % lowpass cut-off frequency %! nb = 40; %! b = fir1(nb,2*Fc/Fs); % matlab freq normalization: 1=Fs/2 %! [H,f] = freqz(b,1,[],1); %! [gd,f] = grpdelay(b,1,[],1); %! plot(f,20*log10(abs(H))); %! title(sprintf('b = fir1(%d,2*%d/%d);',nb,Fc,Fs)); %! xlabel('Normalized Frequency (cycles/sample)'); %! ylabel('Amplitude Response (dB)'); %! grid('on'); %! subplot(212); %! del = nb/2; % should equal this %! plot(f,gd); %! title(sprintf('Group Delay in Pass-Band (Expect %d samples)',del)); %! ylabel('Group Delay (samples)'); %! axis([0, 0.2, del-1, del+1]); %!demo % 4 %! %-------------------------------------------------------------- %! % IIR bandstop filter has delays at [1000, 3000] %! %-------------------------------------------------------------- %! Fs = 8000; %! [b, a] = cheby1(3, 3, 2*[1000, 3000]/Fs, 'stop'); %! [H,f] = freqz(b,a,[],Fs); %! [gd,f] = grpdelay(b,a,[],Fs); %! subplot(211); %! plot(f,abs(H)); %! title('[b,a] = cheby1(3, 3, 2*[1000, 3000]/Fs, "stop");'); %! xlabel('Frequency (Hz)'); %! ylabel('Amplitude Response'); %! grid('on'); %! subplot(212); %! plot(f,gd); %! title('[gd,f] = grpdelay(b,a,[],Fs);'); %! ylabel('Group Delay (samples)'); % ------------------------ TESTS ----------------------- %!test % 00 %! [gd1,w] = grpdelay([0,1]); %! [gd2,w] = grpdelay([0,1],1); %! assert(gd1,gd2,10*eps); %!test % 0A %! [gd,w] = grpdelay([0,1],1,4); %! assert(gd,[1;1;1;1]); %! assert(w,pi/4*[0:3]',10*eps); %!test % 0B %! [gd,w] = grpdelay([0,1],1,4,'whole'); %! assert(gd,[1;1;1;1]); %! assert(w,pi/2*[0:3]',10*eps); %!test % 0C %! [gd,f] = grpdelay([0,1],1,4,0.5); %! assert(gd,[1;1;1;1]); %! assert(f,1/16*[0:3]',10*eps); %!test % 0D %! [gd,w] = grpdelay([0,1],1,4,'whole',1); %! assert(gd,[1;1;1;1]); %! assert(w,1/4*[0:3]',10*eps); %!test % 0E %! [gd,f] = grpdelay([1 -0.9j],[],4,'whole',1); %! gd0 = 0.447513812154696; gdm1 =0.473684210526316; %! assert(gd,[gd0;-9;gd0;gdm1],20*eps); %! assert(f,1/4*[0:3]',10*eps); %!test % 1A: %! gd= grpdelay(1,[1,.9],2*pi*[0,0.125,0.25,0.375]); %! assert(gd, [-0.47368;-0.46918;-0.44751;-0.32316],1e-5); %!test % 1B: %! gd= grpdelay(1,[1,.9],[0,0.125,0.25,0.375],1); %! assert(gd, [-0.47368;-0.46918;-0.44751;-0.32316],1e-5); %!test % 2: %! gd = grpdelay([1,2],[1,0.5,.9],4); %! assert(gd,[-0.29167;-0.24218;0.53077;0.40658],1e-5); %!test % 3 %! b1=[1,2];a1f=[0.25,0.5,1];a1=fliplr(a1f); %! % gd1=grpdelay(b1,a1,4); %! gd=grpdelay(conv(b1,a1f),1,4)-2; %! assert(gd, [0.095238;0.239175;0.953846;1.759360],1e-5); %!test % 4 %! Fs = 8000; %! [b, a] = cheby1(3, 3, 2*[1000, 3000]/Fs, 'stop'); %! [h, w] = grpdelay(b, a, 256, 'half', Fs); %! [h2, w2] = grpdelay(b, a, 512, 'whole', Fs); %! assert (size(h), size(w)); %! assert (length(h), 256); %! assert (size(h2), size(w2)); %! assert (length(h2), 512); %! assert (h, h2(1:256)); %! assert (w, w2(1:256)); %!test % 5 %! a = [1 0 0.9]; %! b = [0.9 0 1]; %! [dh, wf] = grpdelay(b, a, 512, 'whole'); %! [da, wa] = grpdelay(1, a, 512, 'whole'); %! [db, wb] = grpdelay(b, 1, 512, 'whole'); %! assert(dh,db+da,1e-5); ## test for bug #39133 (do not fail for row or column vector) %!test %! DR= [1.00000 -0.00000 -3.37219 0.00000 ... %! 5.45710 -0.00000 -5.24394 0.00000 ... %! 3.12049 -0.00000 -1.08770 0.00000 0.17404]; %! N = [-0.0139469 -0.0222376 0.0178631 0.0451737 ... %! 0.0013962 -0.0259712 0.0016338 0.0165189 ... %! 0.0115098 0.0095051 0.0043874]; %! assert (nthargout (1:2, @grpdelay, N, DR, 1024), %! nthargout (1:2, @grpdelay, N', DR', 1024)); signal-1.3.2/inst/PaxHeaders.4544/specgram.m0000644000000000000000000000013212530736314015407 xustar0030 mtime=1432599756.834410581 30 atime=1432599756.834410581 30 ctime=1432599756.854411378 signal-1.3.2/inst/specgram.m0000644000000000000000000002226312530736314015735 0ustar00rootroot00000000000000## Copyright (C) 1999-2001 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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= 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 function [S_r, f_r, t_r] = specgram(x, n = min(256, length(x)), Fs = 2, window = hanning(n), overlap = ceil(length(window)/2)) if nargin < 1 || nargin > 5 print_usage; ## make sure x is a vector elseif columns(x) != 1 && rows(x) != 1 error ("specgram data must be a vector"); endif if columns(x) != 1, x = x'; endif ## if only the window length is given, generate hanning window if length(window) == 1, window = hanning(window); endif ## should be extended to accept a vector of frequencies at which to ## evaluate the Fourier transform (via filterbank or chirp ## z-transform) if length(n)>1, error("specgram doesn't handle frequency vectors yet"); endif if (length (x) <= length (window)) error ("specgram: segment length must be less than the size of X"); endif ## compute window offsets win_size = length(window); if (win_size > n) n = win_size; warning ("specgram fft size adjusted to %d", n); endif step = win_size - overlap; ## build matrix of windowed data slices offset = [ 1 : step : length(x)-win_size ]; S = zeros (n, length(offset)); for i=1:length(offset) S(1:win_size, i) = x(offset(i):offset(i)+win_size-1) .* window; endfor ## compute Fourier transform S = fft (S); ## extract the positive frequency components if rem(n,2)==1 ret_n = (n+1)/2; else ret_n = n/2; endif S = S(1:ret_n, :); f = [0:ret_n-1]*Fs/n; t = offset/Fs; if nargout==0 imagesc(t, f, 20*log10(abs(S))); set (gca (), "ydir", "normal"); xlabel ("Time") ylabel ("Frequency") endif if nargout>0, S_r = S; endif if nargout>1, f_r = f; endif if nargout>2, t_r = t; endif endfunction %!shared S,f,t,x %! Fs=1000; %! x = chirp([0:1/Fs:2],0,2,500); # freq. sweep from 0-500 over 2 sec. %! step=ceil(20*Fs/1000); # one spectral slice every 20 ms %! window=ceil(100*Fs/1000); # 100 ms data window %! [S, f, t] = specgram(x); %! ## test of returned shape %!assert (rows(S), 128) %!assert (columns(f), rows(S)) %!assert (columns(t), columns(S)) %!test [S, f, t] = specgram(x'); %!assert (rows(S), 128) %!assert (columns(f), rows(S)); %!assert (columns(t), columns(S)); %!error (isempty(specgram([]))); %!error (isempty(specgram([1, 2 ; 3, 4]))); %!error (specgram) %!demo %! Fs=1000; %! x = chirp([0:1/Fs:2],0,2,500); # freq. sweep from 0-500 over 2 sec. %! step=ceil(20*Fs/1000); # one spectral slice every 20 ms %! window=ceil(100*Fs/1000); # 100 ms data window %! %! ## test of automatic plot %! [S, f, t] = specgram(x); %! specgram(x, 2^nextpow2(window), Fs, window, window-step); %!#demo # FIXME: Enable once we have an audio file to demo %! ## 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 ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## Usage: ## [Pxx,freq] = cohere(x,y,Nfft,Fs,window,overlap,range,plot_type,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. ## function varargout = cohere(varargin) ## if ( nargin<2 ) error( 'cohere: Need at least 2 args. Use help cohere.' ); endif nvarargin = length(varargin); ## remove any pwelch RESULT args and add 'trans' for iarg=1:nvarargin arg = varargin{iarg}; if ( ~isempty(arg) && ischar(arg) && ( strcmp(arg,'power') || ... strcmp(arg,'cross') || strcmp(arg,'trans') || ... strcmp(arg,'coher') || strcmp(arg,'ypower') )) varargin{iarg} = []; endif endfor varargin{nvarargin+1} = 'coher'; ## saved_compatib = pwelch('R11-'); if ( nargout==0 ) pwelch(varargin{:}); elseif ( nargout==1 ) Pxx = pwelch(varargin{:}); varargout{1} = Pxx; elseif ( nargout>=2 ) [Pxx,f] = pwelch(varargin{:}); varargout{1} = Pxx; varargout{2} = f; endif pwelch(saved_compatib); saved_compatib = 0; endfunction signal-1.3.2/inst/PaxHeaders.4544/upsamplefill.m0000644000000000000000000000013212530736314016303 xustar0030 mtime=1432599756.838410741 30 atime=1432599756.838410741 30 ctime=1432599756.854411378 signal-1.3.2/inst/upsamplefill.m0000644000000000000000000000534412530736314016632 0ustar00rootroot00000000000000## Copyright (C) 2013 - Juan Pablo Carbajal ## ## This progrm is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . ## -*- texinfo -*- ## @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 ## ## @seealso{upsample} ## @end deftypefn ## Author: Juan Pablo Carbajal function y = upsamplefill (x, v, copy=false) if nargin<2 print_usage; end [nr,nc] = size (x); if copy if any ([nr,nc]==1) y = kron (x(:), ones(v+1,1)); if nr == 1 y = y.'; endif else y = kron (x, ones(v+1,1)); endif return else % Assumes 'v' row or column vector n = length(v) + 1; N = n*nr; if any ([nr,nc]==1) N = N*nc; idx = 1:n:N; idx_c = setdiff (1:N, 1:n:N); y = zeros (N,1); y(idx) = x; y(idx_c) = repmat (v(:), max(nr,nc), 1); if nr == 1 y = y.'; endif else idx = 1:n:N; idx_c = setdiff(1:N,1:n:N); y = zeros (N,nc); y(idx,:) = x; y(idx_c,:) = repmat (v(:), nr, nc); endif endif endfunction %!assert(upsamplefill([1,3,5],2),[1,2,3,2,5,2]); %!assert(upsamplefill([1;3;5],2),[1;2;3;2;5;2]); %!assert(upsamplefill([1,2,5],[2 -2]),[1,2,-2,2,2,-2,5,2,-2]); %!assert(upsamplefill(eye(2),2,true),[1,0;1,0;1,0;0,1;0,1;0,1]); %!assert(upsamplefill([1,3,5],2,true),[1,1,1,3,3,3,5,5,5]); %!assert(upsamplefill([1;3;5],2,true),[1;1;1;3;3;3;;5;5;5]); signal-1.3.2/inst/PaxHeaders.4544/residuez.m0000644000000000000000000000013212530736314015440 xustar0030 mtime=1432599756.830410422 30 atime=1432599756.830410422 30 ctime=1432599756.854411378 signal-1.3.2/inst/residuez.m0000644000000000000000000001235112530736314015763 0ustar00rootroot00000000000000## Copyright (C) 2005 Julius O. Smith III ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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} ## ## @seealso{residue, residued} ## @end deftypefn function [r, p, f, m] = residuez(B, A, tol) ## RESIDUEZ - return residues, poles, and FIR part of B(z)/A(z) ## ## Let nb = length(b), na = length(a), and N=na-1 = no. of poles. ## If nb= na, the FIR part f will not be empty. ## Let M = nb-na+1 = order of f = length(f)-1). Then the returned filter is ## ## H(z) = f(1) + f(2)/z + f(3)/z^2 + ... + f(M+1)/z^M + R(z) ## ## where R(z) is the parallel one-pole filter bank defined above. ## Note, in particular, that the impulse-response of the one-pole ## filter bank is in parallel with that of the the FIR part. This can ## be wasteful when matching the initial impulse response is important, ## since F(z) can already match the first N terms of the impulse ## response. To obtain a decomposition in which the impulse response of ## the IIR part R(z) starts after that of the FIR part F(z), use RESIDUED. ## ## J.O. Smith, 9/19/05 if nargin==3 warning("tolerance ignored"); endif NUM = B(:)'; DEN = A(:)'; ## Matlab's residue does not return m (since it is implied by p): [r,p,f,m]=residue(conj(fliplr(NUM)),conj(fliplr(DEN))); p = 1 ./ p; r = r .* ((-p) .^m); if f, f = conj(fliplr(f)); endif endfunction %!test %! B=[1 -2 1]; A=[1 -1]; %! [r,p,f,m] = residuez(B,A); %! assert(r,0,100*eps); %! assert(p,1,100*eps); %! assert(f,[1 -1],100*eps); %! assert(m,1,100*eps); %!test %! B=1; A=[1 -1j]; %! [r,p,f,m] = residuez(B,A); %! assert(r,1,100*eps); %! assert(p,1j,100*eps); %! assert(f,[],100*eps); %! assert(m,1,100*eps); %!test %! B=1; A=[1 -1 .25]; %! [r,p,f,m] = residuez(B,A); %! [rs,is] = sort(r); %! assert(rs,[0;1],1e-7); %! assert(p(is),[0.5;0.5],1e-8); %! assert(f,[],100*eps); %! assert(m(is),[1;2],100*eps); %!test %! B=1; A=[1 -0.75 .125]; %! [r,p,f,m] = residuez(B,A); %! [rs,is] = sort(r); %! assert(rs,[-1;2],100*eps); %! assert(p(is),[0.25;0.5],100*eps); %! assert(f,[],100*eps); %! assert(m(is),[1;1],100*eps); %!test %! B=[1,6,2]; A=[1,-2,1]; %! [r,p,f,m] = residuez(B,A); %! [rs,is] = sort(r); %! assert(rs,[-10;9],1e-7); %! assert(p(is),[1;1],1e-8); %! assert(f,[2],100*eps); %! assert(m(is),[1;2],100*eps); %!test %! B=[6,2]; A=[1,-2,1]; %! [r,p,f,m] = residuez(B,A); %! [rs,is] = sort(r); %! assert(rs,[-2;8],1e-7); %! assert(p(is),[1;1],1e-8); %! assert(f,[],100*eps); %! assert(m(is),[1;2],100*eps); %!test %! B=[1,6,6,2]; A=[1,-2,1]; %! [r,p,f,m] = residuez(B,A); %! [rs,is] = sort(r); %! assert(rs,[-24;15],2e-7); %! assert(p(is),[1;1],1e-8); %! assert(f,[10,2],100*eps); %! assert(m(is),[1;2],100*eps); %!test %! B=[1,6,6,2]; A=[1,-(2+j),(1+2j),-j]; %! [r,p,f,m] = residuez(B,A); %! [rs,is] = sort(r); %! assert(rs,[-2+2.5j;7.5+7.5j;-4.5-12j],1E-6); %! assert(p(is),[1j;1;1],1E-6); %! assert(f,-2j,1E-6); %! assert(m(is),[1;2;1],1E-6); %!test %! B=[1,0,1]; A=[1,0,0,0,0,-1]; %! [r,p,f,m] = residuez(B,A); %! [as,is] = sort(angle(p)); %! rise = [ ... %! 0.26180339887499 - 0.19021130325903i; ... %! 0.03819660112501 + 0.11755705045849i; ... %! 0.4; ... %! 0.03819660112501 - 0.11755705045849i; ... %! 0.26180339887499 + 0.19021130325903i;]; %! pise = [ ... %! -0.80901699437495 - 0.58778525229247i; ... %! 0.30901699437495 - 0.95105651629515i; ... %! 1; ... %! 0.30901699437495 + 0.95105651629515i; ... %! -0.80901699437495 + 0.58778525229247i]; %! assert(r(is),rise,100*eps); %! assert(p(is),pise,100*eps); %! assert(f,[],100*eps); %! assert(m,[1;1;1;1;1],100*eps); signal-1.3.2/inst/PaxHeaders.4544/tf2zp.m0000644000000000000000000000013212530736314014653 xustar0030 mtime=1432599756.834410581 30 atime=1432599756.834410581 30 ctime=1432599756.854411378 signal-1.3.2/inst/tf2zp.m0000644000000000000000000000246412530736314015202 0ustar00rootroot00000000000000## Copyright (C) 1996, 1998, 2000, 2003, 2004, 2005, 2006, 2007 Auburn University ## Copyright (C) 2012 Lukas F. Reichlin ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## Author: A. S. Hodel function [z, p, k] = tf2zp (varargin) if (nargin == 0) print_usage (); endif [z, p, k] = zpkdata (tf (varargin{:}), "vector"); endfunction signal-1.3.2/inst/PaxHeaders.4544/fwhm.m0000644000000000000000000000013212530736314014547 xustar0030 mtime=1432599756.810409625 30 atime=1432599756.810409625 30 ctime=1432599756.854411378 signal-1.3.2/inst/fwhm.m0000644000000000000000000001277612530736314015105 0ustar00rootroot00000000000000## Author: Petr Mikulik (2009) ## This program is granted to the public domain. ## -*- texinfo -*- ## @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 function myfwhm = fwhm (y, varargin) if nargin < 1 || nargin > 5 print_usage; endif opt = 'zero'; is_alevel = 0; level = 0.5; if nargin==1 x = 1:length(y); else if ischar(varargin{1}) x = 1:length(y); k = 1; else x = y; y = varargin{1}; k = 2; endif while k <= length(varargin) if strcmp(varargin{k}, 'alevel') is_alevel = 1; k = k+1; if k > length(varargin) error('option "alevel" requires an argument'); endif level = varargin{k}; if ~isreal(level) || length(level) > 1 error('argument of "alevel" must be real number'); endif k = k+1; break endif if any(strcmp(varargin{k}, {'zero', 'min'})) opt = varargin{k}; k = k+1; endif if k > length(varargin) break; endif if strcmp(varargin{k}, 'rlevel') k = k+1; if k > length(varargin) error('option "rlevel" requires an argument'); endif level = varargin{k}; if ~isreal(level) || length(level) > 1 || level(1) < 0 || level(:) > 1 error('argument of "rlevel" must be real number from 0 to 1 (it is 0.5 for fwhm)'); endif k = k+1; break endif break endwhile if k ~= length(varargin)+1 error('fwhm: extraneous option(s)'); endif endif ## test the y matrix [nr, nc] = size(y); if (nr == 1 && nc > 1) y = y'; nr = nc; nc = 1; endif if length(x) ~= nr error('dimension of input arguments do not match'); endif ## Shift matrix columns so that y(+-xfwhm) = 0: if is_alevel ## case: full-width at the given absolute position y = y - level; else if strcmp(opt, 'zero') ## case: full-width at half maximum y = y - level * repmat(max(y), nr, 1); else ## case: full-width above background y = y - level * repmat((max(y) + min(y)), nr, 1); endif endif ## Trial for a "vectorizing" calculation of fwhm (i.e. all ## columns in one shot): ## myfwhm = zeros(1,nc); # default: 0 for fwhm undefined ## ind = find (y(1:end-1, :) .* y(2:end, :) <= 0); ## [r1,c1] = ind2sub(size(y), ind); ## ... difficult to proceed further. ## Thus calculate fwhm for each column independently: myfwhm = zeros(1,nc); # default: 0 for fwhm undefined for n=1:nc yy = y(:, n); ind = find((yy(1:end-1) .* yy(2:end)) <= 0); if length(ind) >= 2 && yy(ind(1)) > 0 # must start ascending ind = ind(2:end); endif [mx, imax] = max(yy); # protection against constant or (almost) monotonous functions if length(ind) >= 2 && imax >= ind(1) && imax <= ind(end) ind1 = ind(1); ind2 = ind1 + 1; xx1 = x(ind1) - yy(ind1) * (x(ind2) - x(ind1)) / (yy(ind2) - yy(ind1)); ind1 = ind(end); ind2 = ind1 + 1; xx2 = x(ind1) - yy(ind1) * (x(ind2) - x(ind1)) / (yy(ind2) - yy(ind1)); myfwhm(n) = xx2 - xx1; endif endfor endfunction %!test %! x=-pi:0.001:pi; y=cos(x); %! assert( abs(fwhm(x, y) - 2*pi/3) < 0.01 ); %! %!test %! assert( fwhm(-10:10) == 0 && fwhm(ones(1,50)) == 0 ); %! %!test %! x=-20:1:20; %! y1=-4+zeros(size(x)); y1(4:10)=8; %! y2=-2+zeros(size(x)); y2(4:11)=2; %! y3= 2+zeros(size(x)); y3(5:13)=10; %! assert( max(abs(fwhm(x, [y1;y2;y3]') - [20.0/3,7.5,9.25])) < 0.01 ); %! %!test %! x=1:3; y=[-1,3,-1]; assert(abs(fwhm(x,y)-0.75)<0.001 && abs(fwhm(x,y,'zero')-0.75)<0.001 && abs(fwhm(x,y,'min')-1.0)<0.001); %! %!test %! x=1:3; y=[-1,3,-1]; assert(abs(fwhm(x,y, 'rlevel', 0.1)-1.35)<0.001 && abs(fwhm(x,y,'zero', 'rlevel', 0.1)-1.35)<0.001 && abs(fwhm(x,y,'min', 'rlevel', 0.1)-1.40)<0.001); %! %!test %! x=1:3; y=[-1,3,-1]; assert(abs(fwhm(x,y, 'alevel', 2.5)-0.25)<0.001 && abs(fwhm(x,y,'alevel', -0.5)-1.75)<0.001); %! %!test %! x=-10:10; assert( fwhm(x.*x) == 0 ); %! %!test %! x=-5:5; y=18-x.*x; assert( abs(fwhm(y)-6.0) < 0.001 && abs(fwhm(x,y,'zero')-6.0) < 0.001 && abs(fwhm(x,y,'min')-7.0 ) < 0.001); signal-1.3.2/inst/PaxHeaders.4544/primitive.m0000644000000000000000000000013212530736314015616 xustar0030 mtime=1432599756.822410103 30 atime=1432599756.822410103 30 ctime=1432599756.854411378 signal-1.3.2/inst/primitive.m0000644000000000000000000000431112530736314016136 0ustar00rootroot00000000000000## Copyright (C) 2013 - Juan Pablo Carbajal ## ## This progrm is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . ## Author: Juan Pablo Carbajal ## -*- texinfo -*- ## @deftypefn {Function File} {@var{F} =} primitive (@var{f}, @var{t}, @var{F0}) ## Calculates 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 ## 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,'.',t_true,F_true) ## @end example ## ## @seealso{quadgk, cumsum} ## @end deftypefn function F = primitive (f,t,C=0) i_chunk(0,0,[]); F = arrayfun (@(x)i_chunk(f,x,C),t); endfunction function F_prev = i_chunk (f,t,init) persistent F_prev t0 if isempty (init) F_prev = []; t0 = 0; elseif isempty (F_prev) F_prev = init; else F_prev += quadgk(f,t0,t); t0 = t; endif endfunction %!demo %! 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); %! h = plot (t,F,".;numerical primtive;",t_true,F_true,"-;true primitive;"); %! set (h, "linewidth",2); %! # ------------------------------------------------- signal-1.3.2/inst/PaxHeaders.4544/blackmannuttall.m0000644000000000000000000000013212530736314016762 xustar0030 mtime=1432599756.794408987 30 atime=1432599756.794408987 30 ctime=1432599756.854411378 signal-1.3.2/inst/blackmannuttall.m0000644000000000000000000000517612530736314017314 0ustar00rootroot00000000000000## Copyright (C) 2007 Muthiah Annamalai ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## ## @seealso{nuttallwin, kaiser} ## @end deftypefn function w = blackmannuttall (m, opt) if (nargin < 1 || nargin > 2) print_usage (); elseif (! (isscalar (m) && (m == fix (m)) && (m > 0))) error ("blackmannuttall: M must be a positive integer"); endif N = m - 1; if (nargin == 2) switch (opt) case "periodic" N = m; case "symmetric" N = m - 1; otherwise error ("blackmannuttall: window type must be either \"periodic\" or \"symmetric\""); endswitch endif if (m == 1) w = 1; else a0 = 0.3635819; a1 = 0.4891775; a2 = 0.1365995; a3 = 0.0106411; n = [0:m-1]'; w = a0 - a1.*cos(2.*pi.*n./N) + a2.*cos(4.*pi.*n./N) - a3.*cos(6.*pi.*n./N); endif endfunction %!assert (blackmannuttall (1), 1) %!assert (blackmannuttall (2), 0.0003628 * ones (2, 1), eps) %!assert (blackmannuttall (15), flipud (blackmannuttall (15)), 10*eps); %!assert (blackmannuttall (16), flipud (blackmannuttall (16)), 10*eps); %!assert (blackmannuttall (15), blackmannuttall (15, "symmetric")); %!assert (blackmannuttall (16)(1:15), blackmannuttall (15, "periodic")); %% Test input validation %!error blackmannuttall () %!error blackmannuttall (0.5) %!error blackmannuttall (-1) %!error blackmannuttall (ones (1, 4)) %!error blackmannuttall (1, 2) %!error blackmannuttall (1, "invalid") signal-1.3.2/inst/PaxHeaders.4544/cplxreal.m0000644000000000000000000000013212530736314015420 xustar0030 mtime=1432599756.798409147 30 atime=1432599756.798409147 30 ctime=1432599756.854411378 signal-1.3.2/inst/cplxreal.m0000644000000000000000000000443412530736314015746 0ustar00rootroot00000000000000## Copyright (C) 2005 Julius O. Smith III ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{zc}, @var{zr}] =} cplxreal (@var{z}, @var{thresh}) ## Split the vector z into its complex (@var{zc}) and real (@var{zr}) elements, ## eliminating one of each complex-conjugate pair. ## ## INPUTS: ## @itemize ## @item ## @var{z} = row- or column-vector of complex numbers ## @item ## @var{thresh} = tolerance threshold for numerical comparisons (default = 100*eps) ## @end itemize ## ## RETURNED: ## @itemize ## @item ## @var{zc} = elements of @var{z} having positive imaginary parts ## @item ## @var{zr} = elements of @var{z} having zero imaginary part ## @end itemize ## ## Each complex element of @var{z} is assumed to have a complex-conjugate ## counterpart elsewhere in @var{z} as well. Elements are declared real ## if their imaginary parts have magnitude less than @var{thresh}. ## ## @seealso{cplxpair} ## @end deftypefn function [zc,zr] = cplxreal (z, thresh = 100*eps) ## interesting for testing: if nargin<2, thresh=1E-3; endif if isempty(z) zc=[]; zr=[]; else zcp = cplxpair(z); # sort complex pairs, real roots at end nz = length(z); nzrsec = 0; i=nz; while i && abs(imag(zcp(i))) ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, see . ## -*- texinfo -*- ## @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")}. ## ## @seealso{ellip} ## @end deftypefn function [z, p, g] = ellipap (n, Rp, Rs) if (nargin != 3) print_usage(); elseif (! isscalar (n) || ! isnumeric (n) || fix (n) != n || n <= 0) error ("ellipap: N must be a positive integer"); elseif (! isscalar (Rp) || ! isnumeric (Rp) || Rp <= 0) error ("ellipap: RP must be a positive scalar"); elseif (! isscalar (Rs) || ! isnumeric (Rs) || Rs < 0) error ("ellipap: RS must be a positive scalar"); elseif (Rp > Rs) error ("ellipap: RS must be larger than RP"); endif [z, p, g] = ellip (n, Rp, Rs, 1, "s"); endfunction signal-1.3.2/inst/PaxHeaders.4544/cpsd.m0000644000000000000000000000013212530736314014537 xustar0030 mtime=1432599756.802409306 30 atime=1432599756.802409306 30 ctime=1432599756.854411378 signal-1.3.2/inst/cpsd.m0000644000000000000000000000445012530736314015063 0ustar00rootroot00000000000000## Copyright (C) 2006 Peter V. Lanspeary ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## @seealso{pwelch} ## @end deftypefn function varargout = cpsd(varargin) ## Check fixed argument if (nargin < 2 || nargin > 7) print_usage (); endif nvarargin = length(varargin); ## remove any pwelch RESULT args and add 'cross' for iarg=1:nvarargin arg = varargin{iarg}; if ( ~isempty(arg) && ischar(arg) && ( strcmp(arg,'power') || ... strcmp(arg,'cross') || strcmp(arg,'trans') || ... strcmp(arg,'coher') || strcmp(arg,'ypower') )) varargin{iarg} = []; endif endfor varargin{nvarargin+1} = 'cross'; ## if ( nargout==0 ) pwelch(varargin{:}); elseif ( nargout==1 ) Pxx = pwelch(varargin{:}); varargout{1} = Pxx; elseif ( nargout>=2 ) [Pxx,f] = pwelch(varargin{:}); varargout{1} = Pxx; varargout{2} = f; endif endfunction signal-1.3.2/inst/PaxHeaders.4544/sawtooth.m0000644000000000000000000000013212530736314015456 xustar0030 mtime=1432599756.830410422 30 atime=1432599756.830410422 30 ctime=1432599756.854411378 signal-1.3.2/inst/sawtooth.m0000644000000000000000000000376012530736314016005 0ustar00rootroot00000000000000## Copyright (C) 2007 Juan Aguado ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function y = sawtooth (t,width) if (nargin < 1 || nargin > 2) print_usage (); endif if (nargin == 1) width = 1; else if (width < 0 || width > 1 || ! isreal (width)) error ("width must be a real number between 0 and 1."); endif endif t = mod (t / (2 * pi), 1); y = zeros (size (t)); if (width != 0) y (t < width) = 2 * t (t < width) / width - 1; endif if (width != 1) y( t >= width) = -2 * (t (t >= width) - width) / (1 - width) + 1; endif endfunction signal-1.3.2/inst/PaxHeaders.4544/pei_tseng_notch.m0000644000000000000000000000013212530736314016756 xustar0030 mtime=1432599756.822410103 30 atime=1432599756.822410103 30 ctime=1432599756.854411378 signal-1.3.2/inst/pei_tseng_notch.m0000644000000000000000000001040112530736314017273 0ustar00rootroot00000000000000## Copyright (C) 2011 Alexander Klein ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## FIXME: Implement Laplace-space frequencies and bandwidths, and perhaps ## better range checking for bandwidths? function [ b, a ] = pei_tseng_notch ( frequencies, bandwidths ) err = nargchk ( 2, 2, nargin, "string" ); if ( err ) error ( err ); elseif ( !isvector ( frequencies ) || !isvector ( bandwidths ) ) error ( "All arguments must be vectors!" ) elseif ( length ( frequencies ) != length ( bandwidths ) ) error ( "All arguments must be of equal length!" ) elseif ( !all ( frequencies > 0 && frequencies < 1 ) ) error ( "All frequencies must be in (0, 1)!" ) elseif ( !all ( bandwidths > 0 && bandwidths < 1 ) ) error ( "All bandwidths must be in (0, 1)!" ) endif ## Ensure row vectors frequencies = frequencies (:)'; bandwidths = bandwidths (:)'; ## Normalize appropriately frequencies *= pi; bandwidths *= pi; M2 = 2 * length ( frequencies ); ## Splice center and offset frequencies ( Equation 11 ) omega = vec ( [ frequencies - bandwidths / 2; frequencies ] ); ## Splice center and offset phases ( Equations 12 ) factors = ( 1 : 2 : M2 ); phi = vec ( [ -pi * factors + pi / 2; -pi * factors ] ); ## Create linear equation t_beta = tan ( ( phi + M2 * omega ) / 2 ); Q = zeros ( M2 ); for k = 1 : M2 Q ( : ,k ) = sin ( k .* omega ) - t_beta .* cos ( k .* omega ); endfor ## Compute coefficients of system function ( Equations 19, 20 ) ... h_a = ( Q \ t_beta )' ; denom = [ 1, h_a ]; num = [ fliplr( h_a ), 1 ]; ## ... and transform them to coefficients for difference equations a = denom; b = ( num + denom ) / 2; endfunction %!test %! ## 2Hz bandwidth %! sf = 800; sf2 = sf/2; %! data=[sinetone(49,sf,10,1),sinetone(50,sf,10,1),sinetone(51,sf,10,1)]; %! [b, a] = pei_tseng_notch ( 50 / sf2, 2 / sf2 ); %! filtered = filter ( b, a, data ); %! damp_db = 20 * log10 ( max ( filtered ( end - 1000 : end, : ) ) ); %! assert ( damp_db, [ -3 -251.9 -3 ], -0.1 ) %!test %! ## 1Hz bandwidth %! sf = 800; sf2 = sf/2; %! data=[sinetone(49.5,sf,10,1),sinetone(50,sf,10,1),sinetone(50.5,sf,10,1)]; %! [b, a] = pei_tseng_notch ( 50 / sf2, 1 / sf2 ); %! filtered = filter ( b, a, data ); %! damp_db = 20 * log10 ( max ( filtered ( end - 1000 : end, : ) ) ); %! assert ( damp_db, [ -3 -240.4 -3 ], -0.1 ) %!demo %! sf = 800; sf2 = sf/2; %! data=[[1;zeros(sf-1,1)],sinetone(49,sf,1,1),sinetone(50,sf,1,1),sinetone(51,sf,1,1)]; %! [b,a]=pei_tseng_notch ( 50 / sf2, 2/sf2 ); %! filtered = filter(b,a,data); %! %! clf %! subplot ( columns ( filtered ), 1, 1) %! plot(filtered(:,1),";Impulse response;") %! subplot ( columns ( filtered ), 1, 2 ) %! plot(filtered(:,2),";49Hz response;") %! subplot ( columns ( filtered ), 1, 3 ) %! plot(filtered(:,3),";50Hz response;") %! subplot ( columns ( filtered ), 1, 4 ) %! plot(filtered(:,4),";51Hz response;") signal-1.3.2/inst/PaxHeaders.4544/csd.m0000644000000000000000000000013212530736314014357 xustar0030 mtime=1432599756.802409306 30 atime=1432599756.802409306 30 ctime=1432599756.854411378 signal-1.3.2/inst/csd.m0000644000000000000000000000364312530736314014706 0ustar00rootroot00000000000000## Copyright (C) 2006 Peter V. Lanspeary ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## Usage: ## [Pxx,freq] = csd(x,y,Nfft,Fs,window,overlap,range,plot_type,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. function varargout = csd(varargin) ## Check fixed argument if ( nargin<2 ) error( 'csd: Need at least 2 args. Use help csd.' ); endif nvarargin = length(varargin); ## remove any pwelch RESULT args and add 'cross' for iarg=1:nvarargin arg = varargin{iarg}; if ( ~isempty(arg) && ischar(arg) && ( strcmp(arg,'power') || ... strcmp(arg,'cross') || strcmp(arg,'trans') || ... strcmp(arg,'coher') || strcmp(arg,'ypower') )) varargin{iarg} = []; endif endfor varargin{nvarargin+1} = 'cross'; ## saved_compatib = pwelch('R11-'); if ( nargout==0 ) pwelch(varargin{:}); elseif ( nargout==1 ) Pxx = pwelch(varargin{:}); varargout{1} = Pxx; elseif ( nargout>=2 ) [Pxx,f] = pwelch(varargin{:}); varargout{1} = Pxx; varargout{2} = f; endif pwelch(saved_compatib); endfunction signal-1.3.2/inst/PaxHeaders.4544/wconv.m0000644000000000000000000000013212530736314014742 xustar0030 mtime=1432599756.838410741 30 atime=1432599756.838410741 30 ctime=1432599756.854411378 signal-1.3.2/inst/wconv.m0000644000000000000000000000336412530736314015271 0ustar00rootroot00000000000000## Copyright (C) 2013 Lukas F. Reichlin ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . ## -*- texinfo -*- ## @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 ## Author: Lukas Reichlin ## Created: April 2013 ## Version: 0.1 function y = wconv (type, x, f, shape = "full") if (nargin < 3 || nargin > 4) print_usage (); endif switch (type(1)) case {1, "1"} y = conv2 (x(:).', f(:).', shape); if (rows (x) > 1) y = y.'; endif case {2, "2"} y = conv2 (x, f, shape); case "r" y = conv2 (x, f(:).', shape); case "c" y = conv2 (x.', f(:).', shape); y = y.'; otherwise print_usage (); endswitch endfunction signal-1.3.2/inst/PaxHeaders.4544/dct2.m0000644000000000000000000000013212530736314014442 xustar0030 mtime=1432599756.802409306 30 atime=1432599756.802409306 30 ctime=1432599756.854411378 signal-1.3.2/inst/dct2.m0000644000000000000000000000264012530736314014765 0ustar00rootroot00000000000000## Copyright (C) 2001 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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. ## @seealso{dct, idct, idct2} ## @end deftypefn function y = dct2 (x, m, n) if (nargin < 1 || nargin > 3) print_usage; endif if nargin == 1 [m, n] = size(x); elseif (nargin == 2) n = m(2); m = m(1); endif if m == 1 y = dct (x.', n).'; elseif n == 1 y = dct (x, m); else y = dct (dct (x, m).', n).'; endif endfunction signal-1.3.2/inst/PaxHeaders.4544/freqs.m0000644000000000000000000000013212530736314014726 xustar0030 mtime=1432599756.810409625 30 atime=1432599756.810409625 30 ctime=1432599756.854411378 signal-1.3.2/inst/freqs.m0000644000000000000000000000270212530736314015250 0ustar00rootroot00000000000000## Copyright (C) 2003 Julius O. Smith III ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 function H = freqs(B,A,W) if (nargin ~= 3 || nargout>1) print_usage; endif H = polyval(B,j*W)./polyval(A,j*W); if nargout<1 freqs_plot(W,H); endif endfunction %!demo %! B = [1 2]; %! A = [1 1]; %! w = linspace(0,4,128); %! freqs(B,A,w); signal-1.3.2/inst/PaxHeaders.4544/fir2.m0000644000000000000000000000013212530736314014450 xustar0030 mtime=1432599756.810409625 30 atime=1432599756.806409466 30 ctime=1432599756.854411378 signal-1.3.2/inst/fir2.m0000644000000000000000000002060412530736314014773 0ustar00rootroot00000000000000## Copyright (C) 2000 Paul Kienzle ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @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 ## @seealso{filter, fir1} ## @end deftypefn function b = fir2(n, f, m, grid_n, ramp_n, window) if nargin < 3 || nargin > 6 print_usage; endif ## verify frequency and magnitude vectors are reasonable t = length(f); if t<2 || f(1)!=0 || f(t)!=1 || any(diff(f)<0) error ("fir2: frequency must be nondecreasing starting from 0 and ending at 1"); elseif t != length(m) error ("fir2: frequency and magnitude vectors must be the same length"); ## find the grid spacing and ramp width elseif (nargin>4 && length(grid_n)>1) || ... (nargin>5 && (length(grid_n)>1 || length(ramp_n)>1)) error ("fir2: grid_n and ramp_n must be integers"); endif if nargin < 4, grid_n=[]; endif if nargin < 5, ramp_n=[]; endif ## find the window parameter, or default to hamming w=[]; if length(grid_n)>1, w=grid_n; grid_n=[]; endif if length(ramp_n)>1, w=ramp_n; ramp_n=[]; endif if nargin < 6, window=w; endif if isempty(window), window=hamming(n+1); endif if !isreal(window) || ischar(window), window=feval(window, n+1); endif if length(window) != n+1, error ("fir2: window must be of length n+1"); endif ## Default grid size is 512... unless n+1 >= 1024 if isempty (grid_n) if n+1 < 1024 grid_n = 512; else grid_n = n+1; endif endif ## ML behavior appears to always round the grid size up to a power of 2 grid_n = 2 ^ nextpow2 (grid_n); ## Error out if the grid size is not big enough for the window if 2*grid_n < n+1 error ("fir2: grid size must be greater than half the filter order"); endif if isempty (ramp_n), ramp_n = fix (grid_n / 25); endif ## Apply ramps to discontinuities if (ramp_n > 0) ## remember original frequency points prior to applying ramps basef = f(:); basem = m(:); ## separate identical frequencies, but keep the midpoint idx = find (diff(f) == 0); f(idx) = f(idx) - ramp_n/grid_n/2; f(idx+1) = f(idx+1) + ramp_n/grid_n/2; f = [f(:);basef(idx)]'; ## make sure the grid points stay monotonic in [0,1] f(f<0) = 0; f(f>1) = 1; f = unique([f(:);basef(idx)(:)]'); ## preserve window shape even though f may have changed m = interp1(basef, basem, f); ## axis([-.1 1.1 -.1 1.1]) ## plot(f,m,'-xb;ramped;',basef,basem,'-or;original;'); pause; endif ## interpolate between grid points grid = interp1(f,m,linspace(0,1,grid_n+1)'); ## hold on; plot(linspace(0,1,grid_n+1),grid,'-+g;grid;'); hold off; pause; ## Transform frequency response into time response and ## center the response about n/2, truncating the excess if (rem(n,2) == 0) b = ifft([grid ; grid(grid_n:-1:2)]); mid = (n+1)/2; b = real ([ b([end-floor(mid)+1:end]) ; b(1:ceil(mid)) ]); else ## Add zeros to interpolate by 2, then pick the odd values below. b = ifft([grid ; zeros(grid_n*2,1) ;grid(grid_n:-1:2)]); b = 2 * real([ b([end-n+1:2:end]) ; b(2:2:(n+1))]); endif ## Multiplication in the time domain is convolution in frequency, ## so multiply by our window now to smooth the frequency response. ## Also, for matlab compatibility, we return return values in 1 row b = b(:)' .* window(:)'; endfunction %% Test that the grid size is rounded up to the next power of 2 %!test %! f = [0 0.6 0.6 1]; m = [1 1 0 0]; %! b9 = fir2 (30, f, m, 9); %! b16 = fir2 (30, f, m, 16); %! b17 = fir2 (30, f, m, 17); %! b32 = fir2 (30, f, m, 32); %! assert ( isequal (b9, b16)) %! assert ( isequal (b17, b32)) %! assert (~isequal (b16, b17)) %% Test expected magnitudes of passbands, stopbands, and cutoff frequencies %!test %! f = [0, 0.7, 0.7, 1]; m = [0, 0, 1, 1]; %! b = fir2 (50, f, m); %! h = abs (freqz (b, 1, [0, 0.7, 1], 2)); %! assert (h(1) <= 3e-3) %! assert (h(2) <= 1/sqrt (2)) %! assert (h(3), 1, 2e-3) %!test %! f = [0, 0.25, 0.25, 0.75, 0.75, 1]; m = [0, 0, 1, 1, 0, 0]; %! b = fir2 (50, f, m); %! h = abs (freqz (b, 1, [0, 0.25, 0.5, 0.75, 1], 2)); %! assert (h(1) <= 3e-3) %! assert (h(2) <= 1/sqrt (2)) %! assert (h(3), 1, 2e-3) %! assert (h(4) <= 1/sqrt (2)) %! assert (h(5) <= 3e-3) %!test %! f = [0, 0.45, 0.45, 0.55, 0.55, 1]; m = [1, 1, 0, 0, 1, 1]; %! b = fir2 (50, f, m); %! h = abs (freqz (b, 1, [0, 0.45, 0.5, 0.55, 1], 2)); %! assert (h(1), 1, 2e-3) %! assert (h(2) <= 1/sqrt (2)) %! assert (h(3) <= 1e-1) %! assert (h(4) <= 1/sqrt (2)) %! assert (h(5), 1, 2e-3) %!demo %! 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)); %! subplot(121); %! plot(f,m,';target response;',w/pi,abs(h),';filter response;'); %! subplot(122); %! plot(f,20*log10(m+1e-5),';target response (dB);',... %! w/pi,20*log10(abs(h)),';filter response (dB);'); %!demo %! f=[0, 0.3, 0.3, 0.6, 0.6, 1]; m=[0, 0, 1, 1/2, 0, 0]; %! plot(f,20*log10(m+1e-5),';target response;'); %! hold on; %! [h, w] = freqz(fir2(50,f,m,512,0)); %! plot(w/pi,20*log10(abs(h)),';filter response (ramp=0);'); %! [h, w] = freqz(fir2(50,f,m,512,25.6)); %! plot(w/pi,20*log10(abs(h)),';filter response (ramp=pi/20 rad);'); %! [h, w] = freqz(fir2(50,f,m,512,51.2)); %! plot(w/pi,20*log10(abs(h)),';filter response (ramp=pi/10 rad);'); %! hold off; %!demo %! % Classical Jakes spectrum %! % X represents the normalized frequency from 0 %! % to the maximum Doppler frequency %! asymptote = 2/3; %! X = linspace(0,asymptote-0.0001,200); %! Y = (1 - (X./asymptote).^2).^(-1/4); %! %! % The target frequency response is 0 after the asymptote %! X = [X, asymptote, 1]; %! Y = [Y, 0, 0]; %! %! plot(X,Y,'b;Target spectrum;'); %! hold on; %! [H,F]=freqz(fir2(20, X, Y)); %! plot(F/pi,abs(H),'c;Synthesized spectrum (n=20);'); %! [H,F]=freqz(fir2(50, X, Y)); %! plot(F/pi,abs(H),'r;Synthesized spectrum (n=50);'); %! [H,F]=freqz(fir2(200, X, Y)); %! plot(F/pi,abs(H),'g;Synthesized spectrum (n=200);'); %! hold off; %! title('Theoretical/Synthesized CLASS spectrum'); %! xlabel('Normalized frequency (Fs=2)'); %! ylabel('Magnitude'); signal-1.3.2/PaxHeaders.4544/DESCRIPTION0000644000000000000000000000013212530736314014161 xustar0030 mtime=1432599756.786408669 30 atime=1432599756.786408669 30 ctime=1432599756.854411378 signal-1.3.2/DESCRIPTION0000644000000000000000000000053612530736314014506 0ustar00rootroot00000000000000Name: Signal Version: 1.3.2 Date: 2015-05-25 Author: various authors Maintainer: Mike Miller Title: Signal Processing. Description: Signal processing tools, including filtering, windowing and display functions. Depends: octave (>= 3.8.0), control (>= 2.4.5) Autoload: no License: GPLv3+, public domain Url: http://octave.sf.net signal-1.3.2/PaxHeaders.4544/INDEX0000644000000000000000000000013212530736314013245 xustar0030 mtime=1432599756.786408669 30 atime=1432599756.786408669 30 ctime=1432599756.854411378 signal-1.3.2/INDEX0000644000000000000000000000331512530736314013570 0ustar00rootroot00000000000000signal >> Signal processing Signals buffer chirp cmorwavf diric gauspuls gmonopuls mexihat meyeraux morlet pulstran rectpuls sawtooth shanwavf sigmoid_train specgram square tripuls Filtering filtfilt filtic medfilt1 movingrms sgolayfilt sosfilt Filter Analysis freqs freqs_plot fwhm grpdelay impz zplane Filter Conversion convmtx polystab residued residuez sos2tf sos2zp ss2tf ss2zp tf2sos tf2ss tf2zp zp2sos zp2ss zp2tf IIR Filter Design besselap besself bilinear buttap butter buttord cheb cheb1ap cheb1ord cheb2ap cheb2ord cheby1 cheby2 ellip ellipap ellipord iirlp2mb impinvar invimpinvar ncauer pei_tseng_notch sftrans FIR Filter Design cl2bp fir1 fir2 firls kaiserord qp_kaiser remez sgolay Transforms bitrevorder cceps cplxreal czt dct dct2 dctmtx dftmtx digitrevorder dst dwt fht fwht hilbert idct idct2 idst ifht ifwht rceps Power Spectrum Analysis ar_psd cohere cpsd csd mscohere pburg pwelch pyulear tfe tfestimate xcorr xcorr2 xcov __power Window Functions barthannwin blackmanharris blackmannuttall bohmanwin boxcar chebwin flattopwin gaussian gausswin hann kaiser nuttallwin parzenwin rectwin triang tukeywin ultrwin welchwin window System Identification arburg aryule invfreq invfreqs invfreqz levinson Sample Rate Change data2fun decimate downsample interp resample upfirdn upsample Utility buffer clustersegment findpeaks fracshift marcumq primitive sampled2continuous schtrig upsamplefill wconv wkeep wrev zerocrossing signal-1.3.2/PaxHeaders.4544/COPYING0000644000000000000000000000013212530736314013506 xustar0030 mtime=1432599756.786408669 30 atime=1432599756.786408669 30 ctime=1432599756.854411378 signal-1.3.2/COPYING0000644000000000000000000010451312530736314014033 0ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . signal-1.3.2/PaxHeaders.4544/NEWS0000644000000000000000000000013212530736314013152 xustar0030 mtime=1432599756.786408669 30 atime=1432599756.786408669 30 ctime=1432599756.854411378 signal-1.3.2/NEWS0000644000000000000000000001346512530736314013504 0ustar00rootroot00000000000000Summary of important user-visible changes for signal 1.3.2: ---------------------------------------------------------- ** The package is no longer dependent on the general package. Summary of important user-visible changes for signal 1.3.1: ---------------------------------------------------------- ** The following window functions now accept a Matlab compatible option to select the periodic variant, useful for FFT applications: blackmanharris hann blackmannuttall nuttallwin ** The following filter design functions have improved and more consistent input parameter validation: buttord cheb2ord cheb1ord ellipord =============================================================================== signal-1.3.0 Release Date: 2014-01-26 Release Manager: Mike Miller =============================================================================== ** The following functions are new: digitrevorder upsamplefill primitive wconv ultrwin ** Several bugs have been fixed in the following functions: ellipord ifwht findpeaks remez fir1 resample fwht schtrig grpdelay zp2sos ** Replaced line continuation marker "\" by "..." to avoid deprecated syntax warning in Octave 3.8. ** The signal package now depends on Octave 3.8 or newer. The `ellipke' function is required, which used to be provided by the specfun package. Consequently, the signal package no longer depends on specfun. =============================================================================== signal-1.2.2 Release Date: 2013-03-25 Release Manager: Mike Miller =============================================================================== ** No change release to correct bad file permissions on previous release. =============================================================================== signal-1.2.1 Release Date: 2013-03-17 Release Manager: Mike Miller =============================================================================== ** The following functions are new: buttap cheb1ap cheb2ap ellipap findpeaks fwht ifwht ** Improved Matlab compatibility for the following window functions: barthannwin blackmanharris blackmannuttall chebwin flattopwin nuttallwin The changes include always returning a column vector, returning a valid window for a length argument of 1, and making all arguments after the length optional. ** Minor updates to documentation for the following functions: cpsd mscohere sos2tf sos2zp tfestimate zp2sos ** signal is no longer dependent on the optim package. =============================================================================== signal-1.2.0 Release Date: 2012-09-21 Release Manager: Carnë Draug =============================================================================== ** Improved Matlab compability for the function `fir2'. This changes include always returning vaues in a row (even when the smoothing window is a single column), the default values for grid_n and ramp_n, and returning an error when invalid values are used (instead of silently adjusting them). ** Fixed failing tests for the following functions: fir1 pei_tseng_notch residued ** The function `rceps' was fixed to work correctly with odd-length inputs. ** Bugfix in `xcorr2' introduced in 1.1.2 that would not accept "none" as scale option. ** `xcorr2' scaling option "coeff" was changed to return the normalized cross-correlation. ** The following functions are new: movingrms schtrig clustersegment ** signal is no longer dependent on the image package. ** signal is now dependent on the general package. =============================================================================== signal-1.1.3 Release Date: 2012-05-12 Release Manager: Carnë Draug =============================================================================== ** signal is no longer dependent on the audio package. ** signal is now dependent on the image package. ** The function `marcumq' was imported from the communications package and has been completely rewritten to improve performance and fix computational errors. ** Package is no longer automatically loaded. ** The functions `__ellip_ws' and `__ellip_ws_min' have been removed (they are now subfunctions of `ncauer'. ** The function `blackmanharris' was fixed to have even symmetry. =============================================================================== signal-1.1.2 Release Date: 2012-01-06 Release Manager: Lukas Reichlin =============================================================================== * Added the following filter conversion functions: ss2tf ss2zp tf2ss tf2zp zp2ss zp2tf =============================================================================== signal-1.1.1 Release Date: 2011-11-06 Release Manager: Juan Pablo Carbajal =============================================================================== * Following function now show help text correctly instead of copyright notice: downsample dst flattopwin fwhm idst square upsample * Apply pathc by Paul Dreik to cl2bp_lib.h. =============================================================================== signal-1.1.0 Release Date: 2011-11-04 Release Manager: Juan Pablo Carbajal =============================================================================== * Minor bug fixes in: blackmannuttall.m xcorr.m filtfilt.m invfreq.m invfreqs.m resample.m * New functions added: data2fun.m impinvar.m invimpinvar.m sigmoid_train.m pei_tseng_notch.m iirlp2mb.m * Not implemented functions removed from the documentation. * All demos are now working!