def SimAperture(self, sz, rad_x, rad_y=None, *, shape='cir'): ## Initialize ## # Create the Lateral meshes # xx, yy = np.meshgrid(*_MeshLat(*sz, shift=True)) # Determine boundaries # if ((shape.lower in ('cir', 'sqr')) or (rad_y is None)): # Isotropic, only first input # rad_y = rad_x # Transform the aperture into pixels, and un-normalize the sinc functions # rad_x /= USER.RES[0] / (np.pi / 2) rad_y /= USER.RES[1] / (np.pi / 2) # Check if lobes need to be puffed up a bit (I don't know why?) # #if((USER.KER_TYPE == PM.HELIX) and (USER.KER_Z > 1)): # rad_x *= 4/3 # rad_y *= 4/3 ## Calculate Aperture ## # We work with the Fourier transform directly to prevent edge effects # if (shape.lower() in ('cir', 'ell')): apr = sp.sinc(np.sqrt((xx / rad_x)**2 + (yy / rad_y)**2)) elif (shape.lower() in ('sqr', 'rec')): apr = sp.sinc(xx / rad_x) + sp.sinc(yy / rad_y) ## Output ## return apr
def slepian(M, width, sym=True): """Return the M-point slepian window. """ if (M * width > 27.38): raise ValueError("Cannot reliably obtain slepian sequences for" " M*width > 27.38.") if M < 1: return np.array([]) if M == 1: return np.ones(1, 'd') odd = M % 2 if not sym and not odd: M = M + 1 twoF = width / 2.0 alpha = (M - 1) / 2.0 m = np.arange(0, M) - alpha n = m[:, np.newaxis] k = m[np.newaxis, :] AF = twoF * special.sinc(twoF * (n - k)) [lam, vec] = linalg.eig(AF) ind = np.argmax(abs(lam), axis=-1) w = np.abs(vec[:, ind]) w = w / max(w) if not sym and not odd: w = w[:-1] return w
def slepian(M,width,sym=1): """Return the M-point slepian window. """ if (M*width > 27.38): raise ValueError, "Cannot reliably obtain slepian sequences for"\ " M*width > 27.38." if M < 1: return array([]) if M == 1: return ones(1,'d') odd = M % 2 if not sym and not odd: M = M+1 twoF = width/2.0 alpha = (M-1)/2.0 m = arange(0,M)-alpha n = m[:,newaxis] k = m[newaxis,:] AF = twoF*special.sinc(twoF*(n-k)) [lam,vec] = linalg.eig(AF) ind = argmax(abs(lam),axis=-1) w = abs(vec[:,ind]) w = w / max(w) if not sym and not odd: w = w[:-1] return w
def __calc_amplitude_on_meshgrid_one_harmonic(self, harmonic): x_2D = self.x_2D y_2D = self.y_2D r2_2D = self.gamma**2 * (x_2D**2 + y_2D**2) A = self.wiggler.aux_const + r2_2D Y = harmonic * self.wiggler.K_peak**2 / 4 / A X = 2 * harmonic * self.gamma * self.wiggler.K_peak * x_2D / A sum1 = 0 sum2 = 0 sum3 = 0 p = -self.bessel_cutoff jv2pm1 = jv(harmonic + 2 * p - 1, X) for p in range(-self.bessel_cutoff, self.bessel_cutoff + 1): jvpY = jv(p, Y) sum1 += jv(harmonic + 2 * p, X) * jvpY sum2 += jv2pm1 * jvpY jv2pp1 = jv(harmonic + 2 * p + 1, X) sum3 += jv2pp1 * jvpY jv2pm1 = jv2pp1 aux_factor = np.sqrt(self.alpha)*harmonic*self.gamma\ * self.wiggler.N_periods/ A bessel_part_x = aux_factor \ * (2*self.gamma*x_2D*sum1 - self.wiggler.K_peak*(sum2+sum3)) bessel_part_y = aux_factor * 2 * self.gamma * y_2D * sum1 dw_arr = self.lambda1_um / self.lambda_range - harmonic L = [(sinc(self.wiggler.N_periods * (harmonic * r2_2D + dw * A) / self.wiggler.aux_const)) / np.sqrt(l) * np.sqrt(st) for dw, l, st in zip( dw_arr, self.lambda_range, self.spectral_transmission)] L = np.asarray(L) return bessel_part_x * L, bessel_part_y * L
def firwin(N, cutoff, width=None, window='hamming'): """ FIR Filter Design using windowed ideal filter method. Parameters ---------- N -- order of filter (number of taps) cutoff -- cutoff frequency of filter (normalized so that 1 corresponds to Nyquist or pi radians / sample) width -- if width is not None, then assume it is the approximate width of the transition region (normalized so that 1 corresonds to pi) for use in kaiser FIR filter design. window -- desired window to use. See get_window for a list of windows and required parameters. Returns ------- h -- coefficients of length N fir filter. """ from signaltools import get_window if isinstance(width,float): A = 2.285*N*width + 8 if (A < 21): beta = 0.0 elif (A <= 50): beta = 0.5842*(A-21)**0.4 + 0.07886*(A-21) else: beta = 0.1102*(A-8.7) window=('kaiser',beta) win = get_window(window,N,fftbins=1) alpha = N//2 m = numpy.arange(0,N) h = win*special.sinc(cutoff*(m-alpha)) return h / numpy.sum(h,axis=0)
def sinc(X, Y): n = len(X) m = len(Y) res = np.zeros((n, m)) for i in range(n): for j in range(m): res[i][j] = sc.sinc(np.linalg.norm(X[i] - Y[j])) return res
def test04(self): """Test firwin2 when window=None.""" ntaps = 5 # Ideal lowpass: gain is 1 on [0,0.5], and 0 on [0.5, 1.0] freq = [0.0, 0.5, 0.5, 1.0] gain = [1.0, 1.0, 0.0, 0.0] taps = firwin2(ntaps, freq, gain, window=None, nfreqs=8193) alpha = 0.5 * (ntaps - 1) m = np.arange(0, ntaps) - alpha h = 0.5 * sinc(0.5 * m) assert_array_almost_equal(h, taps)
def firls(N, f, D=None): """Least-squares FIR filter. N -- filter length, must be odd f -- list of tuples of band edges Units of band edges are Hz with 0.5 Hz == Nyquist and assumed 1 Hz sampling frequency D -- list of desired responses, one per band """ if D is None: D = [1, 0] assert len(D) == len(f), "must have one desired response per band" assert N%2 == 1, 'filter length must be odd' L = (N-1)//2 k = np.arange(L+1) k.shape = (1, L+1) j = k.T R = 0 r = 0 for i, (f0, f1) in enumerate(f): R += np.pi*f1*sinc(2*(j-k)*f1) - np.pi*f0*sinc(2*(j-k)*f0) + \ np.pi*f1*sinc(2*(j+k)*f1) - np.pi*f0*sinc(2*(j+k)*f0) r += D[i]*(2*np.pi*f1*sinc(2*j*f1) - 2*np.pi*f0*sinc(2*j*f0)) a = np.dot(np.linalg.inv(R), r) a.shape = (-1,) h = np.zeros(N) h[:L] = a[:0:-1]/2. h[L] = a[0] h[L+1:] = a[1:]/2. return h
def slepian(M, width, sym=True): """Return a digital Slepian window. Used to maximize the energy concentration in the main lobe. Also called the digital prolate spheroidal sequence (DPSS). Parameters ---------- M : int Number of points in the output window. If zero or less, an empty array is returned. width : float Bandwidth sym : bool, optional When True, generates a symmetric window, for use in filter design. When False, generates a periodic window, for use in spectral analysis. Returns ------- w : ndarray The window, with the maximum value always normalized to 1 """ if (M * width > 27.38): raise ValueError("Cannot reliably obtain slepian sequences for" " M*width > 27.38.") if M < 1: return np.array([]) if M == 1: return np.ones(1, 'd') odd = M % 2 if not sym and not odd: M = M + 1 twoF = width / 2.0 alpha = (M - 1) / 2.0 m = np.arange(0, M) - alpha n = m[:, np.newaxis] k = m[np.newaxis, :] AF = twoF * special.sinc(twoF * (n - k)) [lam, vec] = linalg.eig(AF) ind = np.argmax(abs(lam), axis=-1) w = np.abs(vec[:, ind]) w = w / max(w) if not sym and not odd: w = w[:-1] return w
def zeta_squared_error(x1, x2, b): sum = 0 l = 1 c1 = -2. * numpy.pi / math.log(b) f = cmath.exp(complex(0, numpy.pi * (x1 + x2))) fn = f while True: oldsum = sum g = gamma_cache.get((c1, l)) if g is None: g = gamma(complex(1, c1 * l)) gamma_cache[(c1, l)] = g sum += g * fn * sinc(l * (x1 - x2)) if oldsum == sum: break l += 1 fn *= f return pow(sum.real, 2)
def run(): n = np.arange(-20, 21, 1) x = 0.5 * (sinc(n / 2))**2 print("x", x.shape) fig1 = plt.figure(1, figsize=(15, 8), dpi=98) fig1.add_subplot(211) plt.subplot(211, xlabel="n", ylabel="y") plt.grid("-.") plt.plot(n, x) plt.ylim(0, 0.6) plt.subplot(212, xlabel="n", ylabel="y") plt.stem(n, x) plt.ylim(0, 0.6) ts = 1 / 40 fig2 = plt.figure(2, figsize=(15, 8), dpi=98) fig2.add_subplot(111) plt.subplot(111) t = np.arange(-0.5, 1.5, ts) print("t", t.shape) fs = 1 / ts b = np.hstack((np.zeros((1, 20))[0], t[20:60], np.zeros((1, 20))[0])) print("b", b.shape) H = fft(b) / fs print("H", H.shape) df = fs / 80 f = np.arange(0, fs, df) - fs / 2 print("f", f.shape) plt.plot(b, f) H1 = fftshift(H) print("H1", H1.shape) y = x * H1[19:60] fig3 = plt.figure(3, figsize=(15, 8), dpi=98) fig3.add_subplot(111) plt.subplot(111) plt.stem(n, y, linefmt='r-', basefmt='r-', markerfmt='C3.') plt.ylim(-0.2, 0.3) fig1.savefig("./1.png") fig2.savefig("./2.png") fig3.savefig("./3.png") plt.show()
def convert(self, signal: Signal, step: int) -> Signal: old_sampling_period = (signal.samples[-1] - signal.samples[0]) / len( signal.samples) new_sampling_period = (signal.samples[-1] - signal.samples[0]) / self._sampling_rate.rate new_samples = [] new_x_values = self.get_signal_x_values(signal, new_sampling_period) for new_x in new_x_values: new_value = 0 old_x_values = self.get_arguments(signal) for old_index in range(len(old_x_values)): new_value += signal.samples[old_index] * sinc( new_x / old_sampling_period - old_index) new_samples.append(new_value) new_signal = deepcopy(signal) new_signal.samples = new_samples new_signal.sampling_frequency = self._sampling_rate.rate return new_signal
def digit_baseband(): Ts = 1 N_sample = 8 # 每个码元的抽样点数 dt = Ts / N_sample # 抽样时间间隔 N = 1000 # 码元数 T = 1 t = np.arange(0, N * N_sample * dt, dt) gt1 = np.ones((1, N_sample)) # NRZ非归零波形 gt2 = np.ones((1, N_sample // 2)) # RZ归零波形 gt2 = np.hstack((gt2, np.zeros((1, N_sample // 2)))) mt3 = sinc((t - 5) / Ts).reshape(1, -1) # sin(pi * t / Ts) / (pi * t / Ts) gt3 = mt3[0:10 * N_sample].reshape((1, -1)) d = (np.sign(np.random.randn(1, N)) + 1) / 2 data = sigexpand(d, N_sample) # 对序列间隔插入N_sample - 1个0 st1 = convolve(data, gt1) st2 = convolve(data, gt2) d = 2 * d - 1 #变成双极性序列 data = sigexpand(d, N_sample) st3 = convolve(data, gt3) f1, st1f = T2F(t, st1[:len(t)]) f2, st2f = T2F(t, st2[:len(t)]) f3, st3f = T2F(t, st3[:len(t)]) fig1 = plt.figure(1, figsize=(13, 8), dpi=98) fig1.add_subplot(321) plt.subplot(3, 2, 1, ylabel='单极性NRZ波形') plt.xlim(0, 20) # axis([0 20 - 1.5 1.5]); plt.ylim(-2, 2) # axis([0 20 - 1.5 1.5]); plt.grid("-.") plt.plot(t, st1[0][:len(t)]) fig1.add_subplot(322) plt.grid("-.") plt.xlim(-5, 5) # axis([0 20 - 1.5 1.5]); plt.ylim(-40, 10) plt.plot(f1, 10 * np.log10(abs(st1f)**2 / T)) fig1.add_subplot(323, ylabel='单极性RZ波形') plt.grid("-.") plt.xlim(0, 20) plt.ylim(-1.5, 1.5) plt.plot(t, st2[0][:len(t)]) fig1.add_subplot(324, ylabel='单极性RZ功率谱密度(dB/Hz)') plt.grid("-.") plt.xlim(-5, 5) plt.ylim(-40, 10) plt.plot(f2, 10 * np.log10(abs(st2f)**2 / T)) fig1.add_subplot(325, ylabel='双极性sinc波形', xlabel='t/Ts') plt.plot(t - 5, st3[0][:len(t)]) plt.grid("-.") plt.xlim(0, 20) plt.ylim(-2, 2) fig1.add_subplot(326, ylabel='sinc波形功率谱密度(dB/Hz)', xlabel='f*Ts') plt.grid("-.") plt.xlim(-5, 5) plt.ylim(-40, 10) plt.plot(f3[:-1], 10 * np.log10(abs(st3f)**2 / T)) plt.show()
def findfreqs(num, den, N): m = numpy.arange(0, N) h = win * special.sinc(cutoff * (m - alpha)) return h / numpy.sum(h, axis=0)
def firwin(self, numtaps, cutoff, window=None, pass_zero=True, scale=True, nyq=1.0, fs=None): """ FIR filter design using the window method. This is more or less the same as `scipy.signal.firwin` with the exception that an ndarray with the window values can be passed as an alternative to the window name. The parameters "width" (specifying a Kaiser window) and "fs" have been omitted, they are not needed here. This function computes the coefficients of a finite impulse response filter. The filter will have linear phase; it will be Type I if `numtaps` is odd and Type II if `numtaps` is even. Type II filters always have zero response at the Nyquist rate, so a ValueError exception is raised if firwin is called with `numtaps` even and having a passband whose right end is at the Nyquist rate. Parameters ---------- numtaps : int Length of the filter (number of coefficients, i.e. the filter order + 1). `numtaps` must be even if a passband includes the Nyquist frequency. cutoff : float or 1D array_like Cutoff frequency of filter (expressed in the same units as `nyq`) OR an array of cutoff frequencies (that is, band edges). In the latter case, the frequencies in `cutoff` should be positive and monotonically increasing between 0 and `nyq`. The values 0 and `nyq` must not be included in `cutoff`. window : ndarray or string string: use the window with the passed name from scipy.signal.windows ndarray: The window values - this is an addition to the original firwin routine. pass_zero : bool, optional If True, the gain at the frequency 0 (i.e. the "DC gain") is 1. Otherwise the DC gain is 0. scale : bool, optional Set to True to scale the coefficients so that the frequency response is exactly unity at a certain frequency. That frequency is either: - 0 (DC) if the first passband starts at 0 (i.e. pass_zero is True) - `nyq` (the Nyquist rate) if the first passband ends at `nyq` (i.e the filter is a single band highpass filter); center of first passband otherwise nyq : float, optional Nyquist frequency. Each frequency in `cutoff` must be between 0 and `nyq`. Returns ------- h : (numtaps,) ndarray Coefficients of length `numtaps` FIR filter. Raises ------ ValueError If any value in `cutoff` is less than or equal to 0 or greater than or equal to `nyq`, if the values in `cutoff` are not strictly monotonically increasing, or if `numtaps` is even but a passband includes the Nyquist frequency. See also -------- scipy.firwin """ cutoff = np.atleast_1d(cutoff) / float(nyq) # Check for invalid input. if cutoff.ndim > 1: raise ValueError("The cutoff argument must be at most " "one-dimensional.") if cutoff.size == 0: raise ValueError("At least one cutoff frequency must be given.") if cutoff.min() <= 0 or cutoff.max() >= 1: raise ValueError( "Invalid cutoff frequency {0}: frequencies must be " "greater than 0 and less than nyq.".format(cutoff)) if np.any(np.diff(cutoff) <= 0): raise ValueError("Invalid cutoff frequencies: the frequencies " "must be strictly increasing.") pass_nyquist = bool(cutoff.size & 1) ^ pass_zero if pass_nyquist and numtaps % 2 == 0: raise ValueError( "A filter with an even number of coefficients must " "have zero response at the Nyquist rate.") # Insert 0 and/or 1 at the ends of cutoff so that the length of cutoff # is even, and each pair in cutoff corresponds to passband. cutoff = np.hstack(([0.0] * pass_zero, cutoff, [1.0] * pass_nyquist)) # `bands` is a 2D array; each row gives the left and right edges of # a passband. bands = cutoff.reshape(-1, 2) # Build up the coefficients. alpha = 0.5 * (numtaps - 1) m = np.arange(0, numtaps) - alpha h = 0 for left, right in bands: h += right * sinc(right * m) h -= left * sinc(left * m) if type(window) == str: # Get and apply the window function. from scipy.signal.signaltools import get_window win = get_window(window, numtaps, fftbins=False) elif type(window) == np.ndarray: win = window else: logger.error( "The 'window' was neither a string nor a numpy array, it could not be evaluated." ) return None # apply the window function. h *= win # Now handle scaling if desired. if scale: # Get the first passband. left, right = bands[0] if left == 0: scale_frequency = 0.0 elif right == 1: scale_frequency = 1.0 else: scale_frequency = 0.5 * (left + right) c = np.cos(np.pi * m * scale_frequency) s = np.sum(h * c) h /= s return h
def __init__(self, a): """ a : bandwidth """ super(Sinc, self).__init__(domain=(-np.inf, np.inf)) self.timeFunc = lambda t: sinc(a*t)
def findfreqs(num, den, N): m = np.arange(0,N) h = win*special.sinc(cutoff*(m-alpha)) return h / np.sum(h,axis=0)
def firwin(numtaps, cutoff, width=None, window='hamming', pass_zero=True, scale=True, nyq=1.0): """ FIR filter design using the window method. This function computes the coefficients of a finite impulse response filter. The filter will have linear phase; it will be Type I if `numtaps` is odd and Type II if `numtaps` is even. Type II filters always have zero response at the Nyquist rate, so a ValueError exception is raised if firwin is called with `numtaps` even and having a passband whose right end is at the Nyquist rate. Parameters ---------- numtaps : int Length of the filter (number of coefficients, i.e. the filter order + 1). `numtaps` must be even if a passband includes the Nyquist frequency. cutoff : float or 1D array_like Cutoff frequency of filter (expressed in the same units as `nyq`) OR an array of cutoff frequencies (that is, band edges). In the latter case, the frequencies in `cutoff` should be positive and monotonically increasing between 0 and `nyq`. The values 0 and `nyq` must not be included in `cutoff`. width : float or None If `width` is not None, then assume it is the approximate width of the transition region (expressed in the same units as `nyq`) for use in Kaiser FIR filter design. In this case, the `window` argument is ignored. window : string or tuple of string and parameter values Desired window to use. See `scipy.signal.get_window` for a list of windows and required parameters. pass_zero : bool If True, the gain at the frequency 0 (i.e. the "DC gain") is 1. Otherwise the DC gain is 0. scale : bool Set to True to scale the coefficients so that the frequency response is exactly unity at a certain frequency. That frequency is either: 0 (DC) if the first passband starts at 0 (i.e. pass_zero is True); `nyq` (the Nyquist rate) if the first passband ends at `nyq` (i.e the filter is a single band highpass filter); center of first passband otherwise. nyq : float Nyquist frequency. Each frequency in `cutoff` must be between 0 and `nyq`. Returns ------- h : 1D ndarray Coefficients of length `numtaps` FIR filter. Raises ------ ValueError If any value in `cutoff` is less than or equal to 0 or greater than or equal to `nyq`, if the values in `cutoff` are not strictly monotonically increasing, or if `numtaps` is even but a passband includes the Nyquist frequency. Examples -------- Low-pass from 0 to f:: >>> firwin(numtaps, f) Use a specific window function:: >>> firwin(numtaps, f, window='nuttall') High-pass ('stop' from 0 to f):: >>> firwin(numtaps, f, pass_zero=False) Band-pass:: >>> firwin(numtaps, [f1, f2], pass_zero=False) Band-stop:: >>> firwin(numtaps, [f1, f2]) Multi-band (passbands are [0, f1], [f2, f3] and [f4, 1]):: >>>firwin(numtaps, [f1, f2, f3, f4]) Multi-band (passbands are [f1, f2] and [f3,f4]):: >>> firwin(numtaps, [f1, f2, f3, f4], pass_zero=False) See also -------- scipy.signal.firwin2 """ # The major enhancements to this function added in November 2010 were # developed by Tom Krauss (see ticket #902). cutoff = np.atleast_1d(cutoff) / float(nyq) # Check for invalid input. if cutoff.ndim > 1: raise ValueError("The cutoff argument must be at most one-dimensional.") if cutoff.size == 0: raise ValueError("At least one cutoff frequency must be given.") if cutoff.min() <= 0 or cutoff.max() >= 1: raise ValueError("Invalid cutoff frequency: frequencies must be greater than 0 and less than nyq.") if np.any(np.diff(cutoff) <= 0): raise ValueError("Invalid cutoff frequencies: the frequencies must be strictly increasing.") if width is not None: # A width was given. Find the beta parameter of the Kaiser window # and set `window`. This overrides the value of `window` passed in. atten = kaiser_atten(numtaps, float(width)/nyq) beta = kaiser_beta(atten) window = ('kaiser', beta) pass_nyquist = bool(cutoff.size & 1) ^ pass_zero if pass_nyquist and numtaps % 2 == 0: raise ValueError("A filter with an even number of coefficients must " "have zero response at the Nyquist rate.") # Insert 0 and/or 1 at the ends of cutoff so that the length of cutoff is even, # and each pair in cutoff corresponds to passband. cutoff = np.hstack(([0.0]*pass_zero, cutoff, [1.0]*pass_nyquist)) # `bands` is a 2D array; each row gives the left and right edges of a passband. bands = cutoff.reshape(-1,2) # Build up the coefficients. alpha = 0.5 * (numtaps-1) m = np.arange(0, numtaps) - alpha h = 0 for left, right in bands: h += right * sinc(right * m) h -= left * sinc(left * m) # Get and apply the window function. from signaltools import get_window win = get_window(window, numtaps, fftbins=False) h *= win # Now handle scaling if desired. if scale: # Get the first passband. left, right = bands[0] if left == 0: scale_frequency = 0.0 elif right == 1: scale_frequency = 1.0 else: scale_frequency = 0.5 * (left + right) c = np.cos(np.pi * m * scale_frequency) s = np.sum(h * c) h /= s return h
def firwin(numtaps, cutoff, width=None, window='hamming', pass_zero=True, scale=True, nyq=None, fs=None): """ FIR filter design using the window method. This function computes the coefficients of a finite impulse response filter. The filter will have linear phase; it will be Type I if `numtaps` is odd and Type II if `numtaps` is even. Type II filters always have zero response at the Nyquist frequency, so a ValueError exception is raised if firwin is called with `numtaps` even and having a passband whose right end is at the Nyquist frequency. Parameters ---------- numtaps : int Length of the filter (number of coefficients, i.e. the filter order + 1). `numtaps` must be odd if a passband includes the Nyquist frequency. cutoff : float or 1D array_like Cutoff frequency of filter (expressed in the same units as `fs`) OR an array of cutoff frequencies (that is, band edges). In the latter case, the frequencies in `cutoff` should be positive and monotonically increasing between 0 and `fs/2`. The values 0 and `fs/2` must not be included in `cutoff`. width : float or None, optional If `width` is not None, then assume it is the approximate width of the transition region (expressed in the same units as `fs`) for use in Kaiser FIR filter design. In this case, the `window` argument is ignored. window : string or tuple of string and parameter values, optional Desired window to use. See `scipy.signal.get_window` for a list of windows and required parameters. pass_zero : {True, False, 'bandpass', 'lowpass', 'highpass', 'bandstop'}, optional If True, the gain at the frequency 0 (i.e. the "DC gain") is 1. If False, the DC gain is 0. Can also be a string argument for the desired filter type (equivalent to ``btype`` in IIR design functions). .. versionadded:: 1.3.0 Support for string arguments. scale : bool, optional Set to True to scale the coefficients so that the frequency response is exactly unity at a certain frequency. That frequency is either: - 0 (DC) if the first passband starts at 0 (i.e. pass_zero is True) - `fs/2` (the Nyquist frequency) if the first passband ends at `fs/2` (i.e the filter is a single band highpass filter); center of first passband otherwise nyq : float, optional *Deprecated. Use `fs` instead.* This is the Nyquist frequency. Each frequency in `cutoff` must be between 0 and `nyq`. Default is 1. fs : float, optional The sampling frequency of the signal. Each frequency in `cutoff` must be between 0 and ``fs/2``. Default is 2. Returns ------- h : (numtaps,) ndarray Coefficients of length `numtaps` FIR filter. Raises ------ ValueError If any value in `cutoff` is less than or equal to 0 or greater than or equal to ``fs/2``, if the values in `cutoff` are not strictly monotonically increasing, or if `numtaps` is even but a passband includes the Nyquist frequency. See Also -------- firwin2 firls minimum_phase remez Examples -------- Low-pass from 0 to f: >>> from scipy import signal >>> numtaps = 3 >>> f = 0.1 >>> signal.firwin(numtaps, f) array([ 0.06799017, 0.86401967, 0.06799017]) Use a specific window function: >>> signal.firwin(numtaps, f, window='nuttall') array([ 3.56607041e-04, 9.99286786e-01, 3.56607041e-04]) High-pass ('stop' from 0 to f): >>> signal.firwin(numtaps, f, pass_zero=False) array([-0.00859313, 0.98281375, -0.00859313]) Band-pass: >>> f1, f2 = 0.1, 0.2 >>> signal.firwin(numtaps, [f1, f2], pass_zero=False) array([ 0.06301614, 0.88770441, 0.06301614]) Band-stop: >>> signal.firwin(numtaps, [f1, f2]) array([-0.00801395, 1.0160279 , -0.00801395]) Multi-band (passbands are [0, f1], [f2, f3] and [f4, 1]): >>> f3, f4 = 0.3, 0.4 >>> signal.firwin(numtaps, [f1, f2, f3, f4]) array([-0.01376344, 1.02752689, -0.01376344]) Multi-band (passbands are [f1, f2] and [f3,f4]): >>> signal.firwin(numtaps, [f1, f2, f3, f4], pass_zero=False) array([ 0.04890915, 0.91284326, 0.04890915]) """ # noqa: E501 # The major enhancements to this function added in November 2010 were # developed by Tom Krauss (see ticket #902). nyq = 0.5 * _get_fs(fs, nyq) cutoff = np.atleast_1d(cutoff) / float(nyq) # Check for invalid input. if cutoff.ndim > 1: raise ValueError("The cutoff argument must be at most " "one-dimensional.") if cutoff.size == 0: raise ValueError("At least one cutoff frequency must be given.") if cutoff.min() <= 0 or cutoff.max() >= 1: raise ValueError("Invalid cutoff frequency: frequencies must be " "greater than 0 and less than fs/2.") if np.any(np.diff(cutoff) <= 0): raise ValueError("Invalid cutoff frequencies: the frequencies " "must be strictly increasing.") if width is not None: # A width was given. Find the beta parameter of the Kaiser window # and set `window`. This overrides the value of `window` passed in. atten = kaiser_atten(numtaps, float(width) / nyq) beta = kaiser_beta(atten) window = ('kaiser', beta) if isinstance(pass_zero, str): if pass_zero in ('bandstop', 'lowpass'): if pass_zero == 'lowpass': if cutoff.size != 1: raise ValueError('cutoff must have one element if ' 'pass_zero=="lowpass", got %s' % (cutoff.shape,)) elif cutoff.size <= 1: raise ValueError('cutoff must have at least two elements if ' 'pass_zero=="bandstop", got %s' % (cutoff.shape,)) pass_zero = True elif pass_zero in ('bandpass', 'highpass'): if pass_zero == 'highpass': if cutoff.size != 1: raise ValueError('cutoff must have one element if ' 'pass_zero=="highpass", got %s' % (cutoff.shape,)) elif cutoff.size <= 1: raise ValueError('cutoff must have at least two elements if ' 'pass_zero=="bandpass", got %s' % (cutoff.shape,)) pass_zero = False else: raise ValueError('pass_zero must be True, False, "bandpass", ' '"lowpass", "highpass", or "bandstop", got ' '%s' % (pass_zero,)) pass_zero = bool(operator.index(pass_zero)) # ensure bool-like pass_nyquist = bool(cutoff.size & 1) ^ pass_zero if pass_nyquist and numtaps % 2 == 0: raise ValueError("A filter with an even number of coefficients must " "have zero response at the Nyquist frequency.") # Insert 0 and/or 1 at the ends of cutoff so that the length of cutoff # is even, and each pair in cutoff corresponds to passband. cutoff = np.hstack(([0.0] * pass_zero, cutoff, [1.0] * pass_nyquist)) # `bands` is a 2D array; each row gives the left and right edges of # a passband. bands = cutoff.reshape(-1, 2) # Build up the coefficients. alpha = 0.5 * (numtaps - 1) m = np.arange(0, numtaps) - alpha h = 0 for left, right in bands: h += right * sinc(right * m) h -= left * sinc(left * m) # Get and apply the window function. from .signaltools import get_window win = get_window(window, numtaps, fftbins=False) h *= win # Now handle scaling if desired. if scale: # Get the first passband. left, right = bands[0] if left == 0: scale_frequency = 0.0 elif right == 1: scale_frequency = 1.0 else: scale_frequency = 0.5 * (left + right) c = np.cos(np.pi * m * scale_frequency) s = np.sum(h * c) h /= s return h
import numpy as np from scipy import special import matplotlib.pylab as plt domain = np.linspace(0, 2 *np.pi, 512) sinc_write = special.sinc(domain) plt.plot(domain, sinc_write) plt.show()
def firwin(numtaps, cutoff, width=None, window='hamming', pass_zero=True, scale=True, nyq=None, fs=None): """ FIR filter design using the window method. This function computes the coefficients of a finite impulse response filter. The filter will have linear phase; it will be Type I if `numtaps` is odd and Type II if `numtaps` is even. Type II filters always have zero response at the Nyquist frequency, so a ValueError exception is raised if firwin is called with `numtaps` even and having a passband whose right end is at the Nyquist frequency. Parameters ---------- numtaps : int Length of the filter (number of coefficients, i.e. the filter order + 1). `numtaps` must be odd if a passband includes the Nyquist frequency. cutoff : float or 1-D array_like Cutoff frequency of filter (expressed in the same units as `fs`) OR an array of cutoff frequencies (that is, band edges). In the latter case, the frequencies in `cutoff` should be positive and monotonically increasing between 0 and `fs/2`. The values 0 and `fs/2` must not be included in `cutoff`. width : float or None, optional If `width` is not None, then assume it is the approximate width of the transition region (expressed in the same units as `fs`) for use in Kaiser FIR filter design. In this case, the `window` argument is ignored. window : string or tuple of string and parameter values, optional Desired window to use. See `scipy.signal.get_window` for a list of windows and required parameters. pass_zero : {True, False, 'bandpass', 'lowpass', 'highpass', 'bandstop'}, optional If True, the gain at the frequency 0 (i.e., the "DC gain") is 1. If False, the DC gain is 0. Can also be a string argument for the desired filter type (equivalent to ``btype`` in IIR design functions). .. versionadded:: 1.3.0 Support for string arguments. scale : bool, optional Set to True to scale the coefficients so that the frequency response is exactly unity at a certain frequency. That frequency is either: - 0 (DC) if the first passband starts at 0 (i.e. pass_zero is True) - `fs/2` (the Nyquist frequency) if the first passband ends at `fs/2` (i.e the filter is a single band highpass filter); center of first passband otherwise nyq : float, optional *Deprecated. Use `fs` instead.* This is the Nyquist frequency. Each frequency in `cutoff` must be between 0 and `nyq`. Default is 1. fs : float, optional The sampling frequency of the signal. Each frequency in `cutoff` must be between 0 and ``fs/2``. Default is 2. Returns ------- h : (numtaps,) ndarray Coefficients of length `numtaps` FIR filter. Raises ------ ValueError If any value in `cutoff` is less than or equal to 0 or greater than or equal to ``fs/2``, if the values in `cutoff` are not strictly monotonically increasing, or if `numtaps` is even but a passband includes the Nyquist frequency. See Also -------- firwin2 firls minimum_phase remez Examples -------- Low-pass from 0 to f: >>> from scipy import signal >>> numtaps = 3 >>> f = 0.1 >>> signal.firwin(numtaps, f) array([ 0.06799017, 0.86401967, 0.06799017]) Use a specific window function: >>> signal.firwin(numtaps, f, window='nuttall') array([ 3.56607041e-04, 9.99286786e-01, 3.56607041e-04]) High-pass ('stop' from 0 to f): >>> signal.firwin(numtaps, f, pass_zero=False) array([-0.00859313, 0.98281375, -0.00859313]) Band-pass: >>> f1, f2 = 0.1, 0.2 >>> signal.firwin(numtaps, [f1, f2], pass_zero=False) array([ 0.06301614, 0.88770441, 0.06301614]) Band-stop: >>> signal.firwin(numtaps, [f1, f2]) array([-0.00801395, 1.0160279 , -0.00801395]) Multi-band (passbands are [0, f1], [f2, f3] and [f4, 1]): >>> f3, f4 = 0.3, 0.4 >>> signal.firwin(numtaps, [f1, f2, f3, f4]) array([-0.01376344, 1.02752689, -0.01376344]) Multi-band (passbands are [f1, f2] and [f3,f4]): >>> signal.firwin(numtaps, [f1, f2, f3, f4], pass_zero=False) array([ 0.04890915, 0.91284326, 0.04890915]) """ # noqa: E501 # The major enhancements to this function added in November 2010 were # developed by Tom Krauss (see ticket #902). nyq = 0.5 * _get_fs(fs, nyq) cutoff = np.atleast_1d(cutoff) / float(nyq) # Check for invalid input. if cutoff.ndim > 1: raise ValueError("The cutoff argument must be at most " "one-dimensional.") if cutoff.size == 0: raise ValueError("At least one cutoff frequency must be given.") if cutoff.min() <= 0 or cutoff.max() >= 1: raise ValueError("Invalid cutoff frequency: frequencies must be " "greater than 0 and less than fs/2.") if np.any(np.diff(cutoff) <= 0): raise ValueError("Invalid cutoff frequencies: the frequencies " "must be strictly increasing.") if width is not None: # A width was given. Find the beta parameter of the Kaiser window # and set `window`. This overrides the value of `window` passed in. atten = kaiser_atten(numtaps, float(width) / nyq) beta = kaiser_beta(atten) window = ('kaiser', beta) if isinstance(pass_zero, str): if pass_zero in ('bandstop', 'lowpass'): if pass_zero == 'lowpass': if cutoff.size != 1: raise ValueError('cutoff must have one element if ' 'pass_zero=="lowpass", got %s' % (cutoff.shape,)) elif cutoff.size <= 1: raise ValueError('cutoff must have at least two elements if ' 'pass_zero=="bandstop", got %s' % (cutoff.shape,)) pass_zero = True elif pass_zero in ('bandpass', 'highpass'): if pass_zero == 'highpass': if cutoff.size != 1: raise ValueError('cutoff must have one element if ' 'pass_zero=="highpass", got %s' % (cutoff.shape,)) elif cutoff.size <= 1: raise ValueError('cutoff must have at least two elements if ' 'pass_zero=="bandpass", got %s' % (cutoff.shape,)) pass_zero = False else: raise ValueError('pass_zero must be True, False, "bandpass", ' '"lowpass", "highpass", or "bandstop", got ' '%s' % (pass_zero,)) pass_zero = bool(operator.index(pass_zero)) # ensure bool-like pass_nyquist = bool(cutoff.size & 1) ^ pass_zero if pass_nyquist and numtaps % 2 == 0: raise ValueError("A filter with an even number of coefficients must " "have zero response at the Nyquist frequency.") # Insert 0 and/or 1 at the ends of cutoff so that the length of cutoff # is even, and each pair in cutoff corresponds to passband. cutoff = np.hstack(([0.0] * pass_zero, cutoff, [1.0] * pass_nyquist)) # `bands` is a 2-D array; each row gives the left and right edges of # a passband. bands = cutoff.reshape(-1, 2) # Build up the coefficients. alpha = 0.5 * (numtaps - 1) m = np.arange(0, numtaps) - alpha h = 0 for left, right in bands: h += right * sinc(right * m) h -= left * sinc(left * m) # Get and apply the window function. from .signaltools import get_window win = get_window(window, numtaps, fftbins=False) h *= win # Now handle scaling if desired. if scale: # Get the first passband. left, right = bands[0] if left == 0: scale_frequency = 0.0 elif right == 1: scale_frequency = 1.0 else: scale_frequency = 0.5 * (left + right) c = np.cos(np.pi * m * scale_frequency) s = np.sum(h * c) h /= s return h
def calc_stimulus_frame(self, N_first: int = 0, N_frame: int = 10, N_end: int = 10, init: bool = False) -> np.ndarray: """ Calculate a data frame of stimulus `x` with a length of `N_frame` samples, starting with index `N_first` Parameters ---------- N_first: int index of first data point N_frame: int number of samples to be generated init: bool when init == True, initialize stimulus settings Returns ------- x: ndarray an array with `N` stimulus data points """ if init or N_first == 0: '''intialize title string, y-axis label and some variables''' # use radians for angle internally self.rad_phi1 = self.ui.phi1 / 180 * pi self.rad_phi2 = self.ui.phi2 / 180 * pi # check whether some amplitude is complex and set array type for xf # correspondingly. if (self.ui.ledDC.isVisible and type(self.ui.DC) == complex) or\ (self.ui.ledAmp1.isVisible and type(self.ui.A1) == complex) or\ (self.ui.ledAmp2.isVisible and type(self.ui.A2) == complex): self.xf = np.zeros(N_frame, dtype=complex) else: self.xf = np.zeros(N_frame, dtype=float) self.H_str = r'$y[n]$' # default self.title_str = "" if self.ui.stim == "none": self.title_str = r'Zero Input Response' self.H_str = r'$h_0[n]$' # ------------------------------------------------------------------ elif self.ui.stim == "dirac": self.title_str = r'Impulse Response' self.H_str = r'$h[n]$' elif self.ui.stim == "sinc": self.title_str = r'Sinc Impulse' elif self.ui.stim == "gauss": self.title_str = r'Gaussian Impulse' elif self.ui.stim == "rect": self.title_str = r'Rect Impulse' # ------------------------------------------------------------------ elif self.ui.stim == "step": if self.ui.chk_step_err.isChecked(): self.title_str = r'Settling Error $\epsilon$' self.H_str = r'$h_{\epsilon, \infty} - h_{\epsilon}[n]$' else: self.title_str = r'Step Response' self.H_str = r'$h_{\epsilon}[n]$' # ------------------------------------------------------------------ elif self.ui.stim == "cos": self.title_str = r'Cosine Stimulus' elif self.ui.stim == "sine": self.title_str = r'Sinusoidal Stimulus' elif self.ui.stim == "exp": self.title_str = r'Complex Exponential Stimulus' elif self.ui.stim == "diric": self.title_str = r'Periodic Sinc Stimulus' # ------------------------------------------------------------------ elif self.ui.stim == "chirp": self.title_str = self.ui.chirp_type.capitalize() + ' Chirp Stimulus' # ------------------------------------------------------------------ elif self.ui.stim == "triang": if self.ui.but_stim_bl.isChecked(): self.title_str = r'Bandlim. Triangular Stimulus' else: self.title_str = r'Triangular Stimulus' elif self.ui.stim == "saw": if self.ui.but_stim_bl.isChecked(): self.title_str = r'Bandlim. Sawtooth Stimulus' else: self.title_str = r'Sawtooth Stimulus' elif self.ui.stim == "square": if self.ui.but_stim_bl.isChecked(): self.title_str = r'Bandlimited Rect. Stimulus' else: self.title_str = r'Rect. Stimulus' elif self.ui.stim == "comb": self.title_str = r'Bandlim. Comb Stimulus' # ------------------------------------------------------------------ elif self.ui.stim == "am": self.title_str = ( r'AM Stimulus: $A_1 \sin(2 \pi n f_1 + \varphi_1)' r'\cdot A_2 \sin(2 \pi n f_2 + \varphi_2)$') elif self.ui.stim == "pmfm": self.title_str = ( r'PM / FM Stimulus: $A_1 \sin(2 \pi n f_1' r'+ \varphi_1 + A_2 \sin(2 \pi n f_2 + \varphi_2))$') # ------------------------------------------------------------------ elif self.ui.stim == "formula": self.title_str = r'Formula Defined Stimulus' # ================================================================== if self.ui.noise == "gauss": self.title_str += r' + Gaussian Noise' elif self.ui.noise == "uniform": self.title_str += r' + Uniform Noise' elif self.ui.noise == "prbs": self.title_str += r' + PRBS Noise' elif self.ui.noise == "mls": self.title_str += r' + max. length sequence' elif self.ui.noise == "brownian": self.title_str += r' + Brownian Noise' # ================================================================== if self.ui.ledDC.isVisible and self.ui.DC != 0: self.title_str += r' + DC' # ---------------------------------------------------------------------- N_last = N_first + N_frame n = np.arange(N_first, N_last) # T_S = fb.fil[0]['T_S'] self.T1_idx = int(np.round(self.ui.T1)) # calculate stimuli x[n] ============================================== if self.ui.stim == "none": self.xf.fill(0) # ---------------------------------------------------------------------- elif self.ui.stim == "dirac": self.xf.fill(0) # = np.zeros(N_frame, dtype=A_type) if N_first <= self.T1_idx < N_last: self.xf[self.T1_idx - N_first] = self.ui.A1 # ---------------------------------------------------------------------- elif self.ui.stim == "sinc": self.xf = self.ui.A1 * sinc(2 * (n - self.ui.T1) * self.ui.f1)\ + self.ui.A2 * sinc(2 * (n - self.ui.T2) * self.ui.f2) # ---------------------------------------------------------------------- elif self.ui.stim == "gauss": self.xf = self.ui.A1 * sig.gausspulse( (n - self.ui.T1), fc=self.ui.f1, bw=self.ui.BW1) +\ self.ui.A2 * sig.gausspulse( (n - self.ui.T2), fc=self.ui.f2, bw=self.ui.BW2) # ---------------------------------------------------------------------- elif self.ui.stim == "rect": n_rise = int(self.T1_idx - np.floor(self.ui.TW1/2)) n_min = max(n_rise, 0) n_max = min(n_rise + self.ui.TW1, N_end) self.xf = self.ui.A1 * np.where((n >= n_min) & (n < n_max), 1, 0) # ---------------------------------------------------------------------- elif self.ui.stim == "step": if self.T1_idx < N_first: # step before current frame self.xf.fill(self.ui.A1) if N_first <= self.T1_idx < N_last: # step in current frame self.xf[0:self.T1_idx - N_first].fill(0) self.xf[self.T1_idx - N_first:].fill(self.ui.A1) elif self.T1_idx >= N_last: # step after current frame self.xf.fill(0) # ---------------------------------------------------------------------- elif self.ui.stim == "cos": self.xf =\ self.ui.A1 * np.cos(2*pi * n * self.ui.f1 + self.rad_phi1) +\ self.ui.A2 * np.cos(2*pi * n * self.ui.f2 + self.rad_phi2) # ---------------------------------------------------------------------- elif self.ui.stim == "sine": self.xf =\ self.ui.A1 * np.sin(2*pi * n * self.ui.f1 + self.rad_phi1) +\ self.ui.A2 * np.sin(2*pi * n * self.ui.f2 + self.rad_phi2) # ---------------------------------------------------------------------- elif self.ui.stim == "exp": self.xf =\ self.ui.A1 * np.exp(1j * (2 * pi * n * self.ui.f1 + self.rad_phi1)) +\ self.ui.A2 * np.exp(1j * (2 * pi * n * self.ui.f2 + self.rad_phi2)) # ---------------------------------------------------------------------- elif self.ui.stim == "diric": self.xf = self.ui.A1 * diric( (4 * pi * (n-self.ui.T1) * self.ui.f1 + self.rad_phi1*2) / self.ui.TW1, self.ui.TW1) # ---------------------------------------------------------------------- elif self.ui.stim == "chirp": if self.ui.T2 == 0: # sig.chirp is buggy, T_sim cannot be larger than T_end T_end = N_end # frequency sweep over complete interval else: T_end = self.ui.T2 # frequency sweep till T2 self.xf = self.ui.A1 * sig.chirp( n, self.ui.f1, T_end, self.ui.f2, method=self.ui.chirp_type, phi=self.rad_phi1) # ---------------------------------------------------------------------- elif self.ui.stim == "triang": if self.ui.but_stim_bl.isChecked(): self.xf = self.ui.A1 * triang_bl(2*pi * n * self.ui.f1 + self.rad_phi1) else: self.xf = self.ui.A1 * sig.sawtooth( 2*pi * n * self.ui.f1 + self.rad_phi1, width=0.5) # ---------------------------------------------------------------------- elif self.ui.stim == "saw": if self.ui.but_stim_bl.isChecked(): self.xf = self.ui.A1 * sawtooth_bl(2*pi * n * self.ui.f1 + self.rad_phi1) else: self.xf = self.ui.A1 * sig.sawtooth(2*pi * n * self.ui.f1 + self.rad_phi1) # ---------------------------------------------------------------------- elif self.ui.stim == "square": if self.ui.but_stim_bl.isChecked(): self.xf = self.ui.A1 * rect_bl( 2 * pi * n * self.ui.f1 + self.rad_phi1, duty=self.ui.stim_par1) else: self.xf = self.ui.A1 * sig.square( 2 * pi * n * self.ui.f1 + self.rad_phi1, duty=self.ui.stim_par1) # ---------------------------------------------------------------------- elif self.ui.stim == "comb": self.xf = self.ui.A1 * comb_bl(2 * pi * n * self.ui.f1 + self.rad_phi1) # ---------------------------------------------------------------------- elif self.ui.stim == "am": self.xf = self.ui.A1 * np.sin(2*pi * n * self.ui.f1 + self.rad_phi1)\ * self.ui.A2 * np.sin(2*pi * n * self.ui.f2 + self.rad_phi2) # ---------------------------------------------------------------------- elif self.ui.stim == "pmfm": self.xf = self.ui.A1 * np.sin( 2 * pi * n * self.ui.f1 + self.rad_phi1 + self.ui.A2 * np.sin(2*pi * n * self.ui.f2 + self.rad_phi2)) # ---------------------------------------------------------------------- elif self.ui.stim == "formula": param_dict = {"A1": self.ui.A1, "A2": self.ui.A2, "f1": self.ui.f1, "f2": self.ui.f2, "phi1": self.ui.phi1, "phi2": self.ui.phi2, "BW1": self.ui.BW1, "BW2": self.ui.BW2, "f_S": fb.fil[0]['f_S'], "n": n, "j": 1j} self.xf = safe_numexpr_eval(self.ui.stim_formula, (N_frame,), param_dict) else: logger.error('Unknown stimulus format "{0}"'.format(self.ui.stim)) return None # ---------------------------------------------------------------------- # Add noise to stimulus noi = 0 if self.ui.noise == "none": pass elif self.ui.noise == "gauss": noi = self.ui.noi * np.random.randn(N_frame) elif self.ui.noise == "uniform": noi = self.ui.noi * (np.random.rand(N_frame)-0.5) elif self.ui.noise == "prbs": noi = self.ui.noi * 2 * (np.random.randint(0, 2, N_frame)-0.5) elif self.ui.noise == "mls": # max_len_seq returns `sequence, state`. The state is not stored here, # hence, an identical sequence is created every time. noi = self.ui.noi * 2 * (sig.max_len_seq(int(np.ceil(np.log2(N_frame))), length=N_frame, state=None)[0] - 0.5) elif self.ui.noise == "brownian": # brownian noise noi = np.cumsum(self.ui.noi * np.random.randn(N_frame)) else: logger.error('Unknown kind of noise "{}"'.format(self.ui.noise)) if type(self.ui.noi) == complex: self.xf = self.xf.astype(complex) + noi else: self.xf += noi # Add DC to stimulus when visible / enabled if self.ui.ledDC.isVisible: if type(self.ui.DC) == complex: self.xf = self.xf.astype(complex) + self.ui.DC else: self.xf += self.ui.DC return self.xf[:N_frame]
def __init__(self, a): super(Sinc, self).__init__(domain=(-np.inf, np.inf)) self.calc = lambda t: sinc(a*t)
import numpy from matplotlib import pyplot from ex3a_funcs import fraunhofer, single_slit from scipy.special import sinc lam = 500e-9 d = 100e-6 D = 1 L = 5e-3 N = 2**9 A = single_slit(L, d, N) y, I = fraunhofer(A, L, N) pyplot.clf() pyplot.plot(y * d, I, '--', label='Computed') pyplot.plot(y * d, sinc(d * y)**2, label='Theoretical') pyplot.xlabel('$y d / (\lambda D)$') pyplot.ylabel('$I/I_0$') pyplot.legend() pyplot.savefig('core_task1.pdf')
def slepian(M, width, sym=True): """Return a digital Slepian (DPSS) window. Used to maximize the energy concentration in the main lobe. Also called the digital prolate spheroidal sequence (DPSS). Parameters ---------- M : int Number of points in the output window. If zero or less, an empty array is returned. width : float Bandwidth sym : bool, optional When True, generates a symmetric window, for use in filter design. When False, generates a periodic window, for use in spectral analysis. Returns ------- w : ndarray The window, with the maximum value always normalized to 1 Examples -------- Plot the window and its frequency response: >>> from scipy import signal >>> from scipy.fftpack import fft, fftshift >>> import matplotlib.pyplot as plt >>> window = signal.slepian(51, width=0.3) >>> plt.plot(window) >>> plt.title("Slepian (DPSS) window (BW=0.3)") >>> plt.ylabel("Amplitude") >>> plt.xlabel("Sample") >>> plt.figure() >>> A = fft(window, 2048) / (len(window)/2.0) >>> freq = np.linspace(-0.5, 0.5, len(A)) >>> response = 20 * np.log10(np.abs(fftshift(A / abs(A).max()))) >>> plt.plot(freq, response) >>> plt.axis([-0.5, 0.5, -120, 0]) >>> plt.title("Frequency response of the Slepian window (BW=0.3)") >>> plt.ylabel("Normalized magnitude [dB]") >>> plt.xlabel("Normalized frequency [cycles per sample]") """ if (M * width > 27.38): raise ValueError("Cannot reliably obtain slepian sequences for" " M*width > 27.38.") if M < 1: return np.array([]) if M == 1: return np.ones(1, 'd') odd = M % 2 if not sym and not odd: M = M + 1 twoF = width / 2.0 alpha = (M - 1) / 2.0 m = np.arange(0, M) - alpha n = m[:, np.newaxis] k = m[np.newaxis, :] AF = twoF * special.sinc(twoF * (n - k)) [lam, vec] = linalg.eig(AF) ind = np.argmax(abs(lam), axis=-1) w = np.abs(vec[:, ind]) w = w / max(w) if not sym and not odd: w = w[:-1] return w
def interpolant(t): return np.sum(signal*sinc((t - ts)/dt))