From 6ee77e5bd99d769e06535e29bbba001913ecb469 Mon Sep 17 00:00:00 2001 From: sguangyo <1360024032@qq.com> Date: Fri, 9 Aug 2019 21:26:43 +0800 Subject: [PATCH] add numpy op hanning, hamming, blackman --- python/mxnet/ndarray/numpy/_op.py | 275 +++++++++++++++++++++++- python/mxnet/numpy/multiarray.py | 274 +++++++++++++++++++++++- python/mxnet/symbol/numpy/_symbol.py | 276 ++++++++++++++++++++++++- src/operator/numpy/np_window_op.cc | 79 +++++++ src/operator/numpy/np_window_op.cu | 41 ++++ src/operator/numpy/np_window_op.h | 127 ++++++++++++ tests/python/unittest/test_numpy_op.py | 90 ++++++++ 7 files changed, 1159 insertions(+), 3 deletions(-) create mode 100644 src/operator/numpy/np_window_op.cc create mode 100644 src/operator/numpy/np_window_op.cu create mode 100644 src/operator/numpy/np_window_op.h diff --git a/python/mxnet/ndarray/numpy/_op.py b/python/mxnet/ndarray/numpy/_op.py index a129f738c566..5aef1d65dee0 100644 --- a/python/mxnet/ndarray/numpy/_op.py +++ b/python/mxnet/ndarray/numpy/_op.py @@ -27,7 +27,8 @@ from ..ndarray import NDArray __all__ = ['zeros', 'ones', 'add', 'subtract', 'multiply', 'divide', 'mod', 'power', 'tensordot', - 'linspace', 'expand_dims', 'tile', 'arange', 'split', 'concatenate', 'stack'] + 'linspace', 'expand_dims', 'tile', 'arange', 'split', 'concatenate', 'stack', 'hanning', + 'hamming', 'blackman'] @set_module('mxnet.ndarray.numpy') @@ -732,3 +733,275 @@ def get_list(arrays): arrays = get_list(arrays) return _npi.stack(*arrays, axis=axis, out=out) + + +@set_module('mxnet.ndarray.numpy') +def hanning(M, dtype=_np.float64, ctx=None): + r"""Return the Hanning window. + + The Hanning window is a taper formed by using a weighted cosine. + + Parameters + ---------- + M : int + Number of points in the output window. If zero or less, an + empty array is returned. + dtype : str or numpy.dtype, optional + An optional value type. Default is `numpy.float64`. Note that you need + select numpy.float32 or float64 in this operator. + ctx : Context, optional + An optional device context (default is the current default context). + + Returns + ------- + out : ndarray, shape(M,) + The window, with the maximum value normalized to one (the value + one appears only if `M` is odd). + + See Also + -------- + blackman, hamming + + Notes + ----- + The Hanning window is defined as + + .. math:: w(n) = 0.5 - 0.5cos\left(\frac{2\pi{n}}{M-1}\right) + \qquad 0 \leq n \leq M-1 + + The Hanning was named for Julius von Hann, an Austrian meteorologist. + It is also known as the Cosine Bell. Some authors prefer that it be + called a Hann window, to help avoid confusion with the very similar + Hamming window. + + Most references to the Hanning window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. + + References + ---------- + .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power + spectra, Dover Publications, New York. + .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", + The University of Alberta Press, 1975, pp. 106-108. + .. [3] Wikipedia, "Window function", + http://en.wikipedia.org/wiki/Window_function + .. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling, + "Numerical Recipes", Cambridge University Press, 1986, page 425. + + Examples + -------- + >>> np.hanning(12) + array([0.00000000e+00, 7.93732437e-02, 2.92292528e-01, 5.71157416e-01, + 8.27430424e-01, 9.79746513e-01, 9.79746489e-01, 8.27430268e-01, + 5.71157270e-01, 2.92292448e-01, 7.93731320e-02, 1.06192832e-13], dtype=float64) + + Plot the window and its frequency response: + + >>> import matplotlib.pyplot as plt + >>> window = np.hanning(51) + >>> plt.plot(window.asnumpy()) + [] + >>> plt.title("Hann window") + Text(0.5, 1.0, 'Hann window') + >>> plt.ylabel("Amplitude") + Text(0, 0.5, 'Amplitude') + >>> plt.xlabel("Sample") + Text(0.5, 0, 'Sample') + >>> plt.show() + """ + if dtype is None: + dtype = _np.float64 + if ctx is None: + ctx = current_context() + return _npi.hanning(M, dtype=dtype, ctx=ctx) + + +@set_module('mxnet.ndarray.numpy') +def hamming(M, dtype=_np.float64, ctx=None): + r"""Return the hamming window. + + The hamming window is a taper formed by using a weighted cosine. + + Parameters + ---------- + M : int + Number of points in the output window. If zero or less, an + empty array is returned. + dtype : str or numpy.dtype, optional + An optional value type. Default is `numpy.float64`. Note that you need + select numpy.float32 or float64 in this operator. + ctx : Context, optional + An optional device context (default is the current default context). + + Returns + ------- + out : ndarray, shape(M,) + The window, with the maximum value normalized to one (the value + one appears only if `M` is odd). + + See Also + -------- + blackman, hanning + + Notes + ----- + The Hamming window is defined as + + .. math:: w(n) = 0.54 - 0.46cos\left(\frac{2\pi{n}}{M-1}\right) + \qquad 0 \leq n \leq M-1 + + The Hamming was named for R. W. Hamming, an associate of J. W. Tukey + and is described in Blackman and Tukey. It was recommended for + smoothing the truncated autocovariance function in the time domain. + Most references to the Hamming window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. + + References + ---------- + .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power + spectra, Dover Publications, New York. + .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The + University of Alberta Press, 1975, pp. 109-110. + .. [3] Wikipedia, "Window function", + https://en.wikipedia.org/wiki/Window_function + .. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling, + "Numerical Recipes", Cambridge University Press, 1986, page 425. + + Examples + -------- + >>> np.hamming(12) + array([0.08 , 0.15302338, 0.34890913, 0.60546482, 0.84123599, + 0.98136679, 0.98136677, 0.84123585, 0.60546469, 0.34890905, + 0.15302328, 0.08 ], dtype=float64) + + Plot the window and its frequency response: + + >>> import matplotlib.pyplot as plt + >>> window = np.hamming(51) + >>> plt.plot(window.asnumpy()) + [] + >>> plt.title("hamming window") + Text(0.5, 1.0, 'hamming window') + >>> plt.ylabel("Amplitude") + Text(0, 0.5, 'Amplitude') + >>> plt.xlabel("Sample") + Text(0.5, 0, 'Sample') + >>> plt.show() + """ + if dtype is None: + dtype = _np.float64 + if ctx is None: + ctx = current_context() + return _npi.hamming(M, dtype=dtype, ctx=ctx) + + +@set_module('mxnet.ndarray.numpy') +def blackman(M, dtype=_np.float64, ctx=None): + r"""Return the Blackman window. + + The Blackman window is a taper formed by using the first three + terms of a summation of cosines. It was designed to have close to the + minimal leakage possible. It is close to optimal, only slightly worse + than a Kaiser window. + + Parameters + ---------- + M : int + Number of points in the output window. If zero or less, an + empty array is returned. + dtype : str or numpy.dtype, optional + An optional value type. Default is `numpy.float64`. Note that you need + select numpy.float32 or float64 in this operator. + ctx : Context, optional + An optional device context (default is the current default context). + + Returns + ------- + out : ndarray + The window, with the maximum value normalized to one (the value one + appears only if the number of samples is odd). + + See Also + -------- + bartlett, hamming, hanning, kaiser + + Notes + ----- + The Blackman window is defined as + + .. math:: w(n) = 0.42 - 0.5 \cos(2\pi n/{M-1}) + 0.08 \cos(4\pi n/{M-1}) + + Most references to the Blackman window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. It is known as a + "near optimal" tapering function, almost as good (by some measures) + as the kaiser window. + + References + ---------- + Blackman, R.B. and Tukey, J.W., (1958) The measurement of power spectra, + Dover Publications, New York. + + Oppenheim, A.V., and R.W. Schafer. Discrete-Time Signal Processing. + Upper Saddle River, NJ: Prentice-Hall, 1999, pp. 468-471. + + See Also + -------- + hamming, hanning + + Notes + ----- + The Blackman window is defined as + + .. math:: w(n) = 0.42 - 0.5 \cos(2\pi n/{M-1}) + 0.08 \cos(4\pi n/{M-1}) + + Most references to the Blackman window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. It is known as a + "near optimal" tapering function, almost as good (by some measures) + as the kaiser window. + + References + ---------- + Blackman, R.B. and Tukey, J.W., (1958) The measurement of power spectra, + Dover Publications, New York. + + Oppenheim, A.V., and R.W. Schafer. Discrete-Time Signal Processing. + Upper Saddle River, NJ: Prentice-Hall, 1999, pp. 468-471. + + Examples + -------- + >>> np.blackman(12) + array([-1.38777878e-17, 3.26064393e-02, 1.59903660e-01, 4.14397978e-01, + 7.36045260e-01, 9.67046812e-01, 9.67046772e-01, 7.36045039e-01, + 4.14397819e-01, 1.59903601e-01, 3.26063877e-02, 3.82194276e-14], dtype=float64) + + Plot the window and its frequency response: + + >>> import matplotlib.pyplot as plt + >>> window = np.blackman(51) + >>> plt.plot(window.asnumpy()) + [] + >>> plt.title("blackman window") + Text(0.5, 1.0, 'blackman window') + >>> plt.ylabel("Amplitude") + Text(0, 0.5, 'Amplitude') + >>> plt.xlabel("Sample") + Text(0.5, 0, 'Sample') + >>> plt.show() + """ + if dtype is None: + dtype = _np.float64 + if ctx is None: + ctx = current_context() + return _npi.blackman(M, dtype=dtype, ctx=ctx) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index 316d88ae0a81..9e1ce4cbb3b1 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -45,7 +45,7 @@ __all__ = ['ndarray', 'empty', 'array', 'zeros', 'ones', 'add', 'subtract', 'multiply', 'divide', 'mod', 'power', 'tensordot', 'linspace', 'expand_dims', 'tile', 'arange', 'split', - 'concatenate', 'stack'] + 'concatenate', 'stack', 'hanning', 'hamming', 'blackman'] # This function is copied from ndarray.py since pylint @@ -1898,3 +1898,275 @@ def stack(arrays, axis=0, out=None): stacked : ndarray The stacked array has one more dimension than the input arrays.""" return _mx_nd_np.stack(arrays, axis=axis, out=out) + + +@set_module('mxnet.numpy') +def hanning(M, dtype=_np.float64, ctx=None): + r"""Return the Hanning window. + + The Hanning window is a taper formed by using a weighted cosine. + + Parameters + ---------- + M : int + Number of points in the output window. If zero or less, an + empty array is returned. + dtype : str or numpy.dtype, optional + An optional value type. Default is `numpy.float64`. Note that you need + select numpy.float32 or float64 in this operator. + ctx : Context, optional + An optional device context (default is the current default context). + + Returns + ------- + out : ndarray, shape(M,) + The window, with the maximum value normalized to one (the value + one appears only if `M` is odd). + + See Also + -------- + blackman, hamming + + Notes + ----- + The Hanning window is defined as + + .. math:: w(n) = 0.5 - 0.5cos\left(\frac{2\pi{n}}{M-1}\right) + \qquad 0 \leq n \leq M-1 + + The Hanning was named for Julius von Hann, an Austrian meteorologist. + It is also known as the Cosine Bell. Some authors prefer that it be + called a Hann window, to help avoid confusion with the very similar + Hamming window. + + Most references to the Hanning window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. + + References + ---------- + .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power + spectra, Dover Publications, New York. + .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", + The University of Alberta Press, 1975, pp. 106-108. + .. [3] Wikipedia, "Window function", + http://en.wikipedia.org/wiki/Window_function + .. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling, + "Numerical Recipes", Cambridge University Press, 1986, page 425. + + Examples + -------- + >>> np.hanning(12) + array([0.00000000e+00, 7.93732437e-02, 2.92292528e-01, 5.71157416e-01, + 8.27430424e-01, 9.79746513e-01, 9.79746489e-01, 8.27430268e-01, + 5.71157270e-01, 2.92292448e-01, 7.93731320e-02, 1.06192832e-13], dtype=float64) + + Plot the window and its frequency response: + + >>> import matplotlib.pyplot as plt + >>> window = np.hanning(51) + >>> plt.plot(window.asnumpy()) + [] + >>> plt.title("Hann window") + Text(0.5, 1.0, 'Hann window') + >>> plt.ylabel("Amplitude") + Text(0, 0.5, 'Amplitude') + >>> plt.xlabel("Sample") + Text(0.5, 0, 'Sample') + >>> plt.show() + """ + if dtype is None: + dtype = _np.float64 + if ctx is None: + ctx = current_context() + return _mx_nd_np.hanning(M, dtype=dtype, ctx=ctx) + + +@set_module('mxnet.numpy') +def hamming(M, dtype=_np.float64, ctx=None): + r"""Return the hamming window. + + The hamming window is a taper formed by using a weighted cosine. + + Parameters + ---------- + M : int + Number of points in the output window. If zero or less, an + empty array is returned. + dtype : str or numpy.dtype, optional + An optional value type. Default is `numpy.float64`. Note that you need + select numpy.float32 or float64 in this operator. + ctx : Context, optional + An optional device context (default is the current default context). + + Returns + ------- + out : ndarray, shape(M,) + The window, with the maximum value normalized to one (the value + one appears only if `M` is odd). + + See Also + -------- + blackman, hanning + + Notes + ----- + The Hamming window is defined as + + .. math:: w(n) = 0.54 - 0.46cos\left(\frac{2\pi{n}}{M-1}\right) + \qquad 0 \leq n \leq M-1 + + The Hamming was named for R. W. Hamming, an associate of J. W. Tukey + and is described in Blackman and Tukey. It was recommended for + smoothing the truncated autocovariance function in the time domain. + Most references to the Hamming window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. + + References + ---------- + .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power + spectra, Dover Publications, New York. + .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The + University of Alberta Press, 1975, pp. 109-110. + .. [3] Wikipedia, "Window function", + https://en.wikipedia.org/wiki/Window_function + .. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling, + "Numerical Recipes", Cambridge University Press, 1986, page 425. + + Examples + -------- + >>> np.hamming(12) + array([0.08 , 0.15302338, 0.34890913, 0.60546482, 0.84123599, + 0.98136679, 0.98136677, 0.84123585, 0.60546469, 0.34890905, + 0.15302328, 0.08 ], dtype=float64) + + Plot the window and its frequency response: + + >>> import matplotlib.pyplot as plt + >>> window = np.hamming(51) + >>> plt.plot(window.asnumpy()) + [] + >>> plt.title("hamming window") + Text(0.5, 1.0, 'hamming window') + >>> plt.ylabel("Amplitude") + Text(0, 0.5, 'Amplitude') + >>> plt.xlabel("Sample") + Text(0.5, 0, 'Sample') + >>> plt.show() + """ + if dtype is None: + dtype = _np.float64 + if ctx is None: + ctx = current_context() + return _mx_nd_np.hamming(M, dtype=dtype, ctx=ctx) + + +@set_module('mxnet.numpy') +def blackman(M, dtype=_np.float64, ctx=None): + r"""Return the Blackman window. + + The Blackman window is a taper formed by using the first three + terms of a summation of cosines. It was designed to have close to the + minimal leakage possible. It is close to optimal, only slightly worse + than a Kaiser window. + + Parameters + ---------- + M : int + Number of points in the output window. If zero or less, an + empty array is returned. + dtype : str or numpy.dtype, optional + An optional value type. Default is `numpy.float64`. Note that you need + select numpy.float32 or float64 in this operator. + ctx : Context, optional + An optional device context (default is the current default context). + + Returns + ------- + out : ndarray + The window, with the maximum value normalized to one (the value one + appears only if the number of samples is odd). + + See Also + -------- + bartlett, hamming, hanning, kaiser + + Notes + ----- + The Blackman window is defined as + + .. math:: w(n) = 0.42 - 0.5 \cos(2\pi n/{M-1}) + 0.08 \cos(4\pi n/{M-1}) + + Most references to the Blackman window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. It is known as a + "near optimal" tapering function, almost as good (by some measures) + as the kaiser window. + + References + ---------- + Blackman, R.B. and Tukey, J.W., (1958) The measurement of power spectra, + Dover Publications, New York. + + Oppenheim, A.V., and R.W. Schafer. Discrete-Time Signal Processing. + Upper Saddle River, NJ: Prentice-Hall, 1999, pp. 468-471. + + See Also + -------- + hamming, hanning + + Notes + ----- + The Blackman window is defined as + + .. math:: w(n) = 0.42 - 0.5 \cos(2\pi n/{M-1}) + 0.08 \cos(4\pi n/{M-1}) + + Most references to the Blackman window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. It is known as a + "near optimal" tapering function, almost as good (by some measures) + as the kaiser window. + + References + ---------- + Blackman, R.B. and Tukey, J.W., (1958) The measurement of power spectra, + Dover Publications, New York. + + Oppenheim, A.V., and R.W. Schafer. Discrete-Time Signal Processing. + Upper Saddle River, NJ: Prentice-Hall, 1999, pp. 468-471. + + Examples + -------- + >>> np.blackman(12) + array([-1.38777878e-17, 3.26064393e-02, 1.59903660e-01, 4.14397978e-01, + 7.36045260e-01, 9.67046812e-01, 9.67046772e-01, 7.36045039e-01, + 4.14397819e-01, 1.59903601e-01, 3.26063877e-02, 3.82194276e-14], dtype=float64) + + Plot the window and its frequency response: + + >>> import matplotlib.pyplot as plt + >>> window = np.blackman(51) + >>> plt.plot(window.asnumpy()) + [] + >>> plt.title("blackman window") + Text(0.5, 1.0, 'blackman window') + >>> plt.ylabel("Amplitude") + Text(0, 0.5, 'Amplitude') + >>> plt.xlabel("Sample") + Text(0.5, 0, 'Sample') + >>> plt.show() + """ + if dtype is None: + dtype = _np.float64 + if ctx is None: + ctx = current_context() + return _mx_nd_np.blackman(M, dtype=dtype, ctx=ctx) diff --git a/python/mxnet/symbol/numpy/_symbol.py b/python/mxnet/symbol/numpy/_symbol.py index 5537e6305b83..fb14dc5bcd5a 100644 --- a/python/mxnet/symbol/numpy/_symbol.py +++ b/python/mxnet/symbol/numpy/_symbol.py @@ -30,7 +30,8 @@ from . import _internal as _npi __all__ = ['zeros', 'ones', 'add', 'subtract', 'multiply', 'divide', 'mod', 'power', 'tensordot', - 'linspace', 'expand_dims', 'tile', 'arange', 'split', 'concatenate', 'stack'] + 'linspace', 'expand_dims', 'tile', 'arange', 'split', 'concatenate', 'stack', 'hanning', + 'hamming', 'blackman'] def _num_outputs(sym): @@ -1362,4 +1363,277 @@ def get_list(arrays): return _npi.stack(*arrays, axis=axis, out=out) +@set_module('mxnet.symbol.numpy') +def hanning(M, dtype=_np.float64, ctx=None): + r"""Return the Hanning window. + + The Hanning window is a taper formed by using a weighted cosine. + + Parameters + ---------- + M : int + Number of points in the output window. If zero or less, an + empty array is returned. + dtype : str or numpy.dtype, optional + An optional value type. Default is `numpy.float64`. Note that you need + select numpy.float32 or float64 in this operator. + ctx : Context, optional + An optional device context (default is the current default context). + + Returns + ------- + out : _Symbol, shape(M,) + The window, with the maximum value normalized to one (the value + one appears only if `M` is odd). + + See Also + -------- + blackman, hamming + + Notes + ----- + The Hanning window is defined as + + .. math:: w(n) = 0.5 - 0.5cos\left(\frac{2\pi{n}}{M-1}\right) + \qquad 0 \leq n \leq M-1 + + The Hanning was named for Julius von Hann, an Austrian meteorologist. + It is also known as the Cosine Bell. Some authors prefer that it be + called a Hann window, to help avoid confusion with the very similar + Hamming window. + + Most references to the Hanning window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. + + References + ---------- + .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power + spectra, Dover Publications, New York. + .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", + The University of Alberta Press, 1975, pp. 106-108. + .. [3] Wikipedia, "Window function", + http://en.wikipedia.org/wiki/Window_function + .. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling, + "Numerical Recipes", Cambridge University Press, 1986, page 425. + + Examples + -------- + >>> np.hanning(12) + array([0.00000000e+00, 7.93732437e-02, 2.92292528e-01, 5.71157416e-01, + 8.27430424e-01, 9.79746513e-01, 9.79746489e-01, 8.27430268e-01, + 5.71157270e-01, 2.92292448e-01, 7.93731320e-02, 1.06192832e-13], dtype=float64) + + Plot the window and its frequency response: + + >>> import matplotlib.pyplot as plt + >>> window = np.hanning(51) + >>> plt.plot(window.asnumpy()) + [] + >>> plt.title("Hann window") + Text(0.5, 1.0, 'Hann window') + >>> plt.ylabel("Amplitude") + Text(0, 0.5, 'Amplitude') + >>> plt.xlabel("Sample") + Text(0.5, 0, 'Sample') + >>> plt.show() + """ + if dtype is None: + dtype = _np.float64 + if ctx is None: + ctx = current_context() + return _npi.hanning(M, dtype=dtype, ctx=ctx) + + +@set_module('mxnet.symbol.numpy') +def hamming(M, dtype=_np.float64, ctx=None): + r"""Return the hamming window. + + + The hamming window is a taper formed by using a weighted cosine. + + Parameters + ---------- + M : int + Number of points in the output window. If zero or less, an + empty array is returned. + dtype : str or numpy.dtype, optional + An optional value type. Default is `numpy.float64`. Note that you need + select numpy.float32 or float64 in this operator. + ctx : Context, optional + An optional device context (default is the current default context). + + Returns + ------- + out : _Symbol, shape(M,) + The window, with the maximum value normalized to one (the value + one appears only if `M` is odd). + + See Also + -------- + blackman, hanning + + Notes + ----- + The Hamming window is defined as + + .. math:: w(n) = 0.54 - 0.46cos\left(\frac{2\pi{n}}{M-1}\right) + \qquad 0 \leq n \leq M-1 + + The Hamming was named for R. W. Hamming, an associate of J. W. Tukey + and is described in Blackman and Tukey. It was recommended for + smoothing the truncated autocovariance function in the time domain. + Most references to the Hamming window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. + + References + ---------- + .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power + spectra, Dover Publications, New York. + .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The + University of Alberta Press, 1975, pp. 109-110. + .. [3] Wikipedia, "Window function", + https://en.wikipedia.org/wiki/Window_function + .. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling, + "Numerical Recipes", Cambridge University Press, 1986, page 425. + + Examples + -------- + >>> np.hamming(12) + array([0.08 , 0.15302338, 0.34890913, 0.60546482, 0.84123599, + 0.98136679, 0.98136677, 0.84123585, 0.60546469, 0.34890905, + 0.15302328, 0.08 ], dtype=float64) + + Plot the window and its frequency response: + + >>> import matplotlib.pyplot as plt + >>> window = np.hamming(51) + >>> plt.plot(window.asnumpy()) + [] + >>> plt.title("hamming window") + Text(0.5, 1.0, 'hamming window') + >>> plt.ylabel("Amplitude") + Text(0, 0.5, 'Amplitude') + >>> plt.xlabel("Sample") + Text(0.5, 0, 'Sample') + >>> plt.show() + """ + if dtype is None: + dtype = _np.float64 + if ctx is None: + ctx = current_context() + return _npi.hamming(M, dtype=dtype, ctx=ctx) + + +@set_module('mxnet.symbol.numpy') +def blackman(M, dtype=_np.float64, ctx=None): + r"""Return the Blackman window. + + The Blackman window is a taper formed by using the first three + terms of a summation of cosines. It was designed to have close to the + minimal leakage possible. It is close to optimal, only slightly worse + than a Kaiser window. + + Parameters + ---------- + M : int + Number of points in the output window. If zero or less, an + empty array is returned. + dtype : str or numpy.dtype, optional + An optional value type. Default is `numpy.float64`. Note that you need + select numpy.float32 or float64 in this operator. + ctx : Context, optional + An optional device context (default is the current default context). + + Returns + ------- + out : _Symbol + The window, with the maximum value normalized to one (the value one + appears only if the number of samples is odd). + + See Also + -------- + hamming, hanning + + Notes + ----- + The Blackman window is defined as + + .. math:: w(n) = 0.42 - 0.5 \cos(2\pi n/{M-1}) + 0.08 \cos(4\pi n/{M-1}) + + Most references to the Blackman window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. It is known as a + "near optimal" tapering function, almost as good (by some measures) + as the kaiser window. + + References + ---------- + Blackman, R.B. and Tukey, J.W., (1958) The measurement of power spectra, + Dover Publications, New York. + + Oppenheim, A.V., and R.W. Schafer. Discrete-Time Signal Processing. + Upper Saddle River, NJ: Prentice-Hall, 1999, pp. 468-471. + + See Also + -------- + hamming, hanning + + Notes + ----- + The Blackman window is defined as + + .. math:: w(n) = 0.42 - 0.5 \cos(2\pi n/{M-1}) + 0.08 \cos(4\pi n/{M-1}) + + Most references to the Blackman window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. It is known as a + "near optimal" tapering function, almost as good (by some measures) + as the kaiser window. + + References + ---------- + Blackman, R.B. and Tukey, J.W., (1958) The measurement of power spectra, + Dover Publications, New York. + + Oppenheim, A.V., and R.W. Schafer. Discrete-Time Signal Processing. + Upper Saddle River, NJ: Prentice-Hall, 1999, pp. 468-471. + + Examples + -------- + >>> np.blackman(12) + array([-1.38777878e-17, 3.26064393e-02, 1.59903660e-01, 4.14397978e-01, + 7.36045260e-01, 9.67046812e-01, 9.67046772e-01, 7.36045039e-01, + 4.14397819e-01, 1.59903601e-01, 3.26063877e-02, 3.82194276e-14], dtype=float64) + + Plot the window and its frequency response: + + >>> import matplotlib.pyplot as plt + >>> window = np.blackman(51) + >>> plt.plot(window.asnumpy()) + [] + >>> plt.title("blackman window") + Text(0.5, 1.0, 'blackman window') + >>> plt.ylabel("Amplitude") + Text(0, 0.5, 'Amplitude') + >>> plt.xlabel("Sample") + Text(0.5, 0, 'Sample') + >>> plt.show() + """ + if dtype is None: + dtype = _np.float64 + if ctx is None: + ctx = current_context() + return _npi.blackman(M, dtype=dtype, ctx=ctx) + + _set_np_symbol_class(_Symbol) diff --git a/src/operator/numpy/np_window_op.cc b/src/operator/numpy/np_window_op.cc new file mode 100644 index 000000000000..91338a134edc --- /dev/null +++ b/src/operator/numpy/np_window_op.cc @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/*! + * Copyright (c) 2019 by Contributors + * \file np_window_op.cc + * \brief CPU Implementation of unary op hanning, hamming, blackman window. + */ + +#include "np_window_op.h" + +namespace mxnet { +namespace op { + +DMLC_REGISTER_PARAMETER(NumpyWindowsParam); + +inline bool NumpyWindowsShape(const nnvm::NodeAttrs& attrs, + mxnet::ShapeVector* in_shapes, + mxnet::ShapeVector* out_shapes) { + const NumpyWindowsParam& param = nnvm::get(attrs.parsed); + CHECK_EQ(in_shapes->size(), 0U); + CHECK_EQ(out_shapes->size(), 1U); + CHECK(param.M.has_value()) << "missing 1 required positional argument: 'M'"; + int64_t out_size = param.M.value() <= 0 ? 0 : param.M.value(); + SHAPE_ASSIGN_CHECK(*out_shapes, 0, mxnet::TShape({static_cast(out_size)})); + return true; +} + +NNVM_REGISTER_OP(_npi_hanning) +.describe("Return the Hanning window." + "The Hanning window is a taper formed by using a weighted cosine.") +.set_num_inputs(0) +.set_num_outputs(1) +.set_attr_parser(ParamParser) +.set_attr("FInferShape", NumpyWindowsShape) +.set_attr("FInferType", InitType) +.set_attr("FCompute", NumpyWindowCompute) +.add_arguments(NumpyWindowsParam::__FIELDS__()); + +NNVM_REGISTER_OP(_npi_hamming) +.describe("Return the Hamming window." + "The Hamming window is a taper formed by using a weighted cosine.") +.set_num_inputs(0) +.set_num_outputs(1) +.set_attr_parser(ParamParser) +.set_attr("FInferShape", NumpyWindowsShape) +.set_attr("FInferType", InitType) +.set_attr("FCompute", NumpyWindowCompute) +.add_arguments(NumpyWindowsParam::__FIELDS__()); + +NNVM_REGISTER_OP(_npi_blackman) +.describe("Return the Blackman window." + "The Blackman window is a taper formed by using a weighted cosine.") +.set_num_inputs(0) +.set_num_outputs(1) +.set_attr_parser(ParamParser) +.set_attr("FInferShape", NumpyWindowsShape) +.set_attr("FInferType", InitType) +.set_attr("FCompute", NumpyWindowCompute) +.add_arguments(NumpyWindowsParam::__FIELDS__()); + +} // namespace op +} // namespace mxnet diff --git a/src/operator/numpy/np_window_op.cu b/src/operator/numpy/np_window_op.cu new file mode 100644 index 000000000000..d56a96e9282f --- /dev/null +++ b/src/operator/numpy/np_window_op.cu @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/*! + * Copyright (c) 2019 by Contributors + * \file np_window_op.cu + * \brief CPU Implementation of unary op hanning, hamming, blackman window. + */ + +#include "np_window_op.h" + +namespace mxnet { +namespace op { + +NNVM_REGISTER_OP(_npi_hanning) +.set_attr("FCompute", NumpyWindowCompute); + +NNVM_REGISTER_OP(_npi_hamming) +.set_attr("FCompute", NumpyWindowCompute); + +NNVM_REGISTER_OP(_npi_blackman) +.set_attr("FCompute", NumpyWindowCompute); + +} // namespace op +} // namespace mxnet diff --git a/src/operator/numpy/np_window_op.h b/src/operator/numpy/np_window_op.h new file mode 100644 index 000000000000..63c14546ec74 --- /dev/null +++ b/src/operator/numpy/np_window_op.h @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/*! + * Copyright (c) 2019 by Contributors + * \file np_window_op.h + * \brief CPU Implementation of unary op hanning, hamming, blackman window. + */ + +#ifndef MXNET_OPERATOR_NUMPY_NP_WINDOW_OP_H_ +#define MXNET_OPERATOR_NUMPY_NP_WINDOW_OP_H_ + +#include +#include +#include "../tensor/init_op.h" + +namespace mxnet { +namespace op { + +#ifdef __CUDA_ARCH__ +__constant__ const float PI = 3.14159265358979323846; +#else +const float PI = 3.14159265358979323846; +using std::isnan; +#endif + +struct NumpyWindowsParam : public dmlc::Parameter { + dmlc::optional M; + std::string ctx; + int dtype; + DMLC_DECLARE_PARAMETER(NumpyWindowsParam) { + DMLC_DECLARE_FIELD(M) + .set_default(dmlc::optional()) + .describe("Number of points in the output window. " + "If zero or less, an empty array is returned."); + DMLC_DECLARE_FIELD(ctx) + .set_default("") + .describe("Context of output, in format [cpu|gpu|cpu_pinned](n)." + "Only used for imperative calls."); + DMLC_DECLARE_FIELD(dtype) + .set_default(mshadow::kFloat64) + MXNET_ADD_ALL_TYPES + .describe("Data-type of the returned array."); + } +}; + +struct hanning_fwd { + template + MSHADOW_XINLINE static void Map(index_t i, index_t M, int req, DType* out) { + if (M == 1) { + KERNEL_ASSIGN(out[i], req, static_cast(1)); + } else { + KERNEL_ASSIGN(out[i], req, DType(0.5) - DType(0.5) * math::cos(DType(2 * PI * i / (M - 1)))); + } + } +}; + +struct hamming_fwd { + template + MSHADOW_XINLINE static void Map(index_t i, index_t M, int req, DType* out) { + if (M == 1) { + KERNEL_ASSIGN(out[i], req, static_cast(1)); + } else { + KERNEL_ASSIGN(out[i], req, + DType(0.54) - DType(0.46) * math::cos(DType(2 * PI * i / (M - 1)))); + } + } +}; + +struct blackman_fwd { + template + MSHADOW_XINLINE static void Map(index_t i, index_t M, int req, DType* out) { + if (M == 1) { + KERNEL_ASSIGN(out[i], req, static_cast(1)); + } else { + KERNEL_ASSIGN(out[i], req, DType(0.42) - DType(0.5) * math::cos(DType(2 * PI * i /(M - 1))) + + DType(0.08) * math::cos(DType(4 * PI * i /(M - 1)))); + } + } +}; + +template +void NumpyWindowCompute(const nnvm::NodeAttrs& attrs, + const OpContext& ctx, + const std::vector& inputs, + const std::vector& req, + const std::vector& outputs) { + using namespace mxnet_op; + mshadow::Stream *s = ctx.get_stream(); + const NumpyWindowsParam& param = nnvm::get(attrs.parsed); + if (param.M.has_value() && param.M.value() <= 0) return; + MSHADOW_TYPE_SWITCH(outputs[0].type_flag_, DType, { + if (window_select == 0) { + Kernel::Launch(s, outputs[0].Size(), static_cast(param.M.value()), + req[0], outputs[0].dptr()); + } else if (window_select == 1) { + Kernel::Launch(s, outputs[0].Size(), static_cast(param.M.value()), + req[0], outputs[0].dptr()); + } else if (window_select == 2) { + Kernel::Launch(s, outputs[0].Size(), static_cast(param.M.value()), + req[0], outputs[0].dptr()); + } else { + LOG(FATAL) << "window_select must be (0, 1, 2)"; + } + }); +} + +} // namespace op +} // namespace mxnet + +#endif // MXNET_OPERATOR_NUMPY_NP_WINDOW_OP_H_ diff --git a/tests/python/unittest/test_numpy_op.py b/tests/python/unittest/test_numpy_op.py index 6a1a6a6dfd5d..aa6b7202c008 100644 --- a/tests/python/unittest/test_numpy_op.py +++ b/tests/python/unittest/test_numpy_op.py @@ -931,6 +931,96 @@ def hybrid_forward(self, F, a, *args): assert same(mx_out.asnumpy(), np_out) +@with_seed() +@use_np +def test_np_hanning(): + class TestHanning(HybridBlock): + def __init__(self, M, dtype): + super(TestHanning, self).__init__() + self._M = M + self._dtype = dtype + + def hybrid_forward(self, F, x, *args, **kwargs): + return x + F.np.hanning(M=self._M, dtype=self._dtype) + configs = [-10, -3, -1, 0, 1, 6, 10, 20] + dtypes = ['float32', 'float64'] + + for config in configs: + for dtype in dtypes: + x = np.zeros(shape=(), dtype=dtype) + for hybridize in [False, True]: + net = TestHanning(M=config, dtype=dtype) + np_out = _np.hanning(M=config) + if hybridize: + net.hybridize() + mx_out = net(x) + assert_almost_equal(mx_out.asnumpy(), np_out, rtol=1e-3, atol=1e-5) + + mx_out = np.hanning(M=config, dtype=dtype) + np_out = _np.hanning(M=config) + assert_almost_equal(mx_out.asnumpy(), np_out, rtol=1e-3, atol=1e-5) + + +@with_seed() +@use_np +def test_np_hamming(): + class TestHamming(HybridBlock): + def __init__(self, M, dtype): + super(TestHamming, self).__init__() + self._M = M + self._dtype = dtype + + def hybrid_forward(self, F, x, *args, **kwargs): + return x + F.np.hamming(M=self._M, dtype=self._dtype) + configs = [-10, -3, -1, 0, 1, 6, 10, 20] + dtypes = ['float32', 'float64'] + + for config in configs: + for dtype in dtypes: + x = np.zeros(shape=(), dtype=dtype) + for hybridize in [False, True]: + net = TestHamming(M=config, dtype=dtype) + np_out = _np.hamming(M=config) + if hybridize: + net.hybridize() + mx_out = net(x) + assert_almost_equal(mx_out.asnumpy(), np_out, rtol=1e-3, atol=1e-5) + + mx_out = np.hamming(M=config, dtype=dtype) + np_out = _np.hamming(M=config) + assert_almost_equal(mx_out.asnumpy(), np_out, rtol=1e-3, atol=1e-5) + + +@with_seed() +@use_np +def test_np_blackman(): + class TestBlackman(HybridBlock): + def __init__(self, M, dtype): + super(TestBlackman, self).__init__() + self._M = M + self._dtype = dtype + + def hybrid_forward(self, F, x, *args, **kwargs): + return x + F.np.blackman(M=self._M, dtype=self._dtype) + configs = [-10, -3, -1, 0, 1, 6, 10, 20] + dtypes = ['float32', 'float64'] + + for config in configs: + for dtype in dtypes: + x = np.zeros(shape=(), dtype=dtype) + for hybridize in [False, True]: + net = TestBlackman(M=config, dtype=dtype) + np_out = _np.blackman(M=config) + if hybridize: + net.hybridize() + mx_out = net(x) + assert_almost_equal(mx_out.asnumpy(), np_out, rtol=1e-3, atol=1e-5) + + mx_out = np.blackman(M=config, dtype=dtype) + np_out = _np.blackman(M=config) + assert_almost_equal(mx_out.asnumpy(), np_out, rtol=1e-3, atol=1e-5) + + if __name__ == '__main__': import nose nose.runmodule()