def fftconvolve3(in1, in2=None, in3=None, mode="full"): """ Convolve two N-dimensional arrays using FFT. See convolve. For use with arma (old version: in1=num in2=den in3=data * better for consistency with other functions in1=data in2=num in3=den * note in2 and in3 need to have consistent dimension/shape since I'm using max of in2, in3 shapes and not the sum copied from scipy.signal.signaltools, but here used to try out inverse filter does not work or I cannot get it to work 2010-10-23 looks ok to me for 1d, from results below with padded data array (fftp) but it does not work for multidimensional inverse filter (fftn) original signal.fftconvolve also uses fftn """ if (in2 is None) and (in3 is None): raise ValueError('at least one of in2 and in3 needs to be given') s1 = np.array(in1.shape) if in2 is not None: s2 = np.array(in2.shape) else: s2 = 0 if in3 is not None: s3 = np.array(in3.shape) s2 = max(s2, s3) # try this looks reasonable for ARMA #s2 = s3 complex_result = (np.issubdtype(in1.dtype, np.complex) or np.issubdtype(in2.dtype, np.complex)) size = s1 + s2 - 1 # Always use 2**n-sized FFT fsize = 2**np.ceil(np.log2(size)) #convolve shorter ones first, not sure if it matters if in2 is not None: IN1 = fft.fftn(in2, fsize) if in3 is not None: IN1 /= fft.fftn(in3, fsize) # use inverse filter # note the inverse is elementwise not matrix inverse # is this correct, NO does not seem to work for VARMA IN1 *= fft.fftn(in1, fsize) fslice = tuple([slice(0, int(sz)) for sz in size]) ret = fft.ifftn(IN1)[fslice].copy() del IN1 if not complex_result: ret = ret.real if mode == "full": return ret elif mode == "same": if np.product(s1, axis=0) > np.product(s2, axis=0): osize = s1 else: osize = s2 return trim_centered(ret, osize) elif mode == "valid": return trim_centered(ret, abs(s2 - s1) + 1)
def fftconvolve3(in1, in2=None, in3=None, mode="full"): """Convolve two N-dimensional arrays using FFT. See convolve. for use with arma (old version: in1=num in2=den in3=data * better for consistency with other functions in1=data in2=num in3=den * note in2 and in3 need to have consistent dimension/shape since I'm using max of in2, in3 shapes and not the sum copied from scipy.signal.signaltools, but here used to try out inverse filter doesn't work or I can't get it to work 2010-10-23 looks ok to me for 1d, from results below with padded data array (fftp) but it doesn't work for multidimensional inverse filter (fftn) original signal.fftconvolve also uses fftn """ if (in2 is None) and (in3 is None): raise ValueError('at least one of in2 and in3 needs to be given') s1 = np.array(in1.shape) if not in2 is None: s2 = np.array(in2.shape) else: s2 = 0 if not in3 is None: s3 = np.array(in3.shape) s2 = max(s2, s3) # try this looks reasonable for ARMA #s2 = s3 complex_result = (np.issubdtype(in1.dtype, np.complex) or np.issubdtype(in2.dtype, np.complex)) size = s1+s2-1 # Always use 2**n-sized FFT fsize = 2**np.ceil(np.log2(size)) #convolve shorter ones first, not sure if it matters if not in2 is None: IN1 = fft.fftn(in2, fsize) if not in3 is None: IN1 /= fft.fftn(in3, fsize) # use inverse filter # note the inverse is elementwise not matrix inverse # is this correct, NO doesn't seem to work for VARMA IN1 *= fft.fftn(in1, fsize) fslice = tuple([slice(0, int(sz)) for sz in size]) ret = fft.ifftn(IN1)[fslice].copy() del IN1 if not complex_result: ret = ret.real if mode == "full": return ret elif mode == "same": if np.product(s1,axis=0) > np.product(s2,axis=0): osize = s1 else: osize = s2 return trim_centered(ret,osize) elif mode == "valid": return trim_centered(ret,abs(s2-s1)+1)
def fftconvolveinv(in1, in2, mode="full"): """Convolve two N-dimensional arrays using FFT. See convolve. copied from scipy.signal.signaltools, but here used to try out inverse filter doesn't work or I can't get it to work 2010-10-23: looks ok to me for 1d, from results below with padded data array (fftp) but it doesn't work for multidimensional inverse filter (fftn) original signal.fftconvolve also uses fftn """ s1 = np.array(in1.shape) s2 = np.array(in2.shape) complex_result = (np.issubdtype(in1.dtype, np.complex) or np.issubdtype(in2.dtype, np.complex)) size = s1 + s2 - 1 # Always use 2**n-sized FFT fsize = 2**np.ceil(np.log2(size)) IN1 = fft.fftn(in1, fsize) #IN1 *= fftn(in2,fsize) #JP: this looks like the only change I made IN1 /= fft.fftn(in2, fsize) # use inverse filter # note the inverse is elementwise not matrix inverse # is this correct, NO doesn't seem to work for VARMA fslice = tuple([slice(0, int(sz)) for sz in size]) ret = fft.ifftn(IN1)[fslice].copy() del IN1 if not complex_result: ret = ret.real if mode == "full": return ret elif mode == "same": if np.product(s1, axis=0) > np.product(s2, axis=0): osize = s1 else: osize = s2 return trim_centered(ret, osize) elif mode == "valid": return trim_centered(ret, abs(s2 - s1) + 1)
def fftconvolveinv(in1, in2, mode="full"): """Convolve two N-dimensional arrays using FFT. See convolve. copied from scipy.signal.signaltools, but here used to try out inverse filter doesn't work or I can't get it to work 2010-10-23: looks ok to me for 1d, from results below with padded data array (fftp) but it doesn't work for multidimensional inverse filter (fftn) original signal.fftconvolve also uses fftn """ s1 = np.array(in1.shape) s2 = np.array(in2.shape) complex_result = (np.issubdtype(in1.dtype, np.complex) or np.issubdtype(in2.dtype, np.complex)) size = s1+s2-1 # Always use 2**n-sized FFT fsize = 2**np.ceil(np.log2(size)) IN1 = fft.fftn(in1,fsize) #IN1 *= fftn(in2,fsize) #JP: this looks like the only change I made IN1 /= fft.fftn(in2,fsize) # use inverse filter # note the inverse is elementwise not matrix inverse # is this correct, NO doesn't seem to work for VARMA fslice = tuple([slice(0, int(sz)) for sz in size]) ret = fft.ifftn(IN1)[fslice].copy() del IN1 if not complex_result: ret = ret.real if mode == "full": return ret elif mode == "same": if np.product(s1,axis=0) > np.product(s2,axis=0): osize = s1 else: osize = s2 return trim_centered(ret,osize) elif mode == "valid": return trim_centered(ret,abs(s2-s1)+1)
x = np.arange(60).reshape((3, 20)).T a3f = np.array([[[0.5, 1.], [1., 0.5]], [[0.5, 1.], [1., 0.5]]]) a3f = np.ones((2, 3, 3)) nlags = a3f.shape[0] ntrim = nlags // 2 y0 = signal.convolve(x, a3f[:, :, 0], mode='valid') y1 = signal.convolve(x, a3f[:, :, 1], mode='valid') yf = signal.convolve(x[:, :, None], a3f) y = yf[:, 1, :] # yvalid = yf[ntrim:-ntrim, yf.shape[1] // 2, :] #same result with fftconvolve #signal.fftconvolve(x[:,:,None],a3f).shape #signal.fftconvolve(x[:,:,None],a3f)[:,1,:] print(trim_centered(y, x.shape)) # this raises an exception: #print(trim_centered(yf, (x.shape).shape) assert_equal(yvalid[:, 0], y0.ravel()) assert_equal(yvalid[:, 1], y1.ravel()) def arfilter(x, a): '''apply an autoregressive filter to a series x x can be 2d, a can be 1d, 2d, or 3d Parameters ---------- x : array_like data array, 1d or 2d, if 2d then observations in rows
[[0.5, 1.], [1., 0.5]]]) a3f = np.ones((2,3,3)) nlags = a3f.shape[0] ntrim = nlags//2 y0 = signal.convolve(x,a3f[:,:,0], mode='valid') y1 = signal.convolve(x,a3f[:,:,1], mode='valid') yf = signal.convolve(x[:,:,None],a3f) y = yf[:,1,:] # yvalid = yf[ntrim:-ntrim,yf.shape[1]//2,:] #same result with fftconvolve #signal.fftconvolve(x[:,:,None],a3f).shape #signal.fftconvolve(x[:,:,None],a3f)[:,1,:] print trim_centered(y, x.shape) # this raises an exception: #print trim_centered(yf, (x.shape).shape) assert_equal(yvalid[:,0], y0.ravel()) assert_equal(yvalid[:,1], y1.ravel()) def arfilter(x, a): '''apply an autoregressive filter to a series x x can be 2d, a can be 1d, 2d, or 3d Parameters ---------- x : array_like data array, 1d or 2d, if 2d then observations in rows a : array_like
[[0.5, 1.], [1., 0.5]]]) a3f = np.ones((2,3,3)) nlags = a3f.shape[0] ntrim = nlags//2 y0 = signal.convolve(x,a3f[:,:,0], mode='valid') y1 = signal.convolve(x,a3f[:,:,1], mode='valid') yf = signal.convolve(x[:,:,None],a3f) y = yf[:,1,:] # yvalid = yf[ntrim:-ntrim,yf.shape[1]//2,:] #same result with fftconvolve #signal.fftconvolve(x[:,:,None],a3f).shape #signal.fftconvolve(x[:,:,None],a3f)[:,1,:] print(trim_centered(y, x.shape)) # this raises an exception: #print(trim_centered(yf, (x.shape).shape) assert_equal(yvalid[:,0], y0.ravel()) assert_equal(yvalid[:,1], y1.ravel()) def arfilter(x, a): '''apply an autoregressive filter to a series x x can be 2d, a can be 1d, 2d, or 3d Parameters ---------- x : array_like data array, 1d or 2d, if 2d then observations in rows
x = np.arange(60).reshape((3, 20)).T a3f = np.array([[[0.5, 1.], [1., 0.5]], [[0.5, 1.], [1., 0.5]]]) a3f = np.ones((2, 3, 3)) nlags = a3f.shape[0] ntrim = nlags // 2 y0 = signal.convolve(x, a3f[:, :, 0], mode='valid') y1 = signal.convolve(x, a3f[:, :, 1], mode='valid') yf = signal.convolve(x[:, :, None], a3f) y = yf[:, 1, :] # yvalid = yf[ntrim:-ntrim, yf.shape[1] // 2, :] #same result with fftconvolve #signal.fftconvolve(x[:,:,None],a3f).shape #signal.fftconvolve(x[:,:,None],a3f)[:,1,:] print trim_centered(y, x.shape) # this raises an exception: #print trim_centered(yf, (x.shape).shape) assert_equal(yvalid[:, 0], y0.ravel()) assert_equal(yvalid[:, 1], y1.ravel()) from scikits.statsmodels.tsa.filters import arfilter #copied/moved to statsmodels.tsa.filters def arfilter_old(x, a): '''apply an autoregressive filter to a series x x can be 2d, a can be 1d, 2d, or 3d Parameters