#
# Transmission Line Simulator
# 
# Author(s): <NAME>
# Created: Aug-28-2017
#

# Copied from scipy so I don't have to import the whole scipy library.

import numpy as np

def gaussian(M, std, sym=True):
    """Return a Gaussian window.
    Parameters
    ----------
    M : int
        Number of points in the output window. If zero or less, an empty
        array is returned.
    std : float
        The standard deviation, sigma.
    sym : bool, optional
        When True (default), 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 normalized to 1 (though the value 1
        does not appear if `M` is even and `sym` is True).
    Notes
    -----
    The Gaussian window is defined as
    .. math::  w(n) = e^{ -\frac{1}{2}\left(\frac{n}{\sigma}\right)^2 }
    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.gaussian(51, std=7)
    >>> plt.plot(window)
    >>> plt.title(r"Gaussian window ($\sigma$=7)")
    >>> 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(r"Frequency response of the Gaussian window ($\sigma$=7)")
    >>> plt.ylabel("Normalized magnitude [dB]")
    >>> plt.xlabel("Normalized frequency [cycles per sample]")
    """
    if _len_guards(M):
        return np.ones(M)
    M, needs_trunc = _extend(M, sym)

    n = np.arange(0, M) - (M - 1.0) / 2.0
    sig2 = 2 * std * std
    w = np.exp(-n ** 2 / sig2)

    return _truncate(w, needs_trunc)


def _len_guards(M):
    """Handle small or incorrect window lengths"""
    if int(M) != M or M < 0:
        raise 'Window length M must be a non-negative integer'
    return M <= 1


def _extend(M, sym):
    """Extend window by 1 sample if needed for DFT-even symmetry"""
    if not sym:
        return M + 1, True
    else:
        return M, False


def _truncate(w, needed):
    """Truncate window by 1 sample if needed for DFT-even symmetry"""
    if needed:
        return w[:-1]
    else:
        return w

#
# Transmission Line Simulator
# 
# Author(s): <NAME>
# Created: Aug-28-2017
#

# Copied from scipy so I don't have to import the whole scipy library.

import numpy as np

def gaussian(M, std, sym=True):
    """Return a Gaussian window.
    Parameters
    ----------
    M : int
        Number of points in the output window. If zero or less, an empty
        array is returned.
    std : float
        The standard deviation, sigma.
    sym : bool, optional
        When True (default), 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 normalized to 1 (though the value 1
        does not appear if `M` is even and `sym` is True).
    Notes
    -----
    The Gaussian window is defined as
    .. math::  w(n) = e^{ -\frac{1}{2}\left(\frac{n}{\sigma}\right)^2 }
    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.gaussian(51, std=7)
    >>> plt.plot(window)
    >>> plt.title(r"Gaussian window ($\sigma$=7)")
    >>> 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(r"Frequency response of the Gaussian window ($\sigma$=7)")
    >>> plt.ylabel("Normalized magnitude [dB]")
    >>> plt.xlabel("Normalized frequency [cycles per sample]")
    """
    if _len_guards(M):
        return np.ones(M)
    M, needs_trunc = _extend(M, sym)

    n = np.arange(0, M) - (M - 1.0) / 2.0
    sig2 = 2 * std * std
    w = np.exp(-n ** 2 / sig2)

    return _truncate(w, needs_trunc)


def _len_guards(M):
    """Handle small or incorrect window lengths"""
    if int(M) != M or M < 0:
        raise 'Window length M must be a non-negative integer'
    return M <= 1


def _extend(M, sym):
    """Extend window by 1 sample if needed for DFT-even symmetry"""
    if not sym:
        return M + 1, True
    else:
        return M, False


def _truncate(w, needed):
    """Truncate window by 1 sample if needed for DFT-even symmetry"""
    if needed:
        return w[:-1]
    else:
        return w

# # Transmission Line Simulator # # Author(s): <NAME> # Created: Aug-28-2017 # # Copied from scipy so I don't have to import the whole scipy library. Return a Gaussian window.     Parameters     ----------     M : int         Number of points in the output window. If zero or less, an empty         array is returned.     std : float         The standard deviation, sigma.     sym : bool, optional         When True (default), 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 normalized to 1 (though the value 1         does not appear if `M` is even and `sym` is True).     Notes     -----     The Gaussian window is defined as     .. math::  w(n) = e^{ -\frac{1}{2}\left(\frac{n}{\sigma}\right)^2 }     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.gaussian(51, std=7)     >>> plt.plot(window)     >>> plt.title(r"Gaussian window ($\sigma$=7)")     >>> 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(r"Frequency response of the Gaussian window ($\sigma$=7)")     >>> plt.ylabel("Normalized magnitude [dB]")     >>> plt.xlabel("Normalized frequency [cycles per sample]") Handle small or incorrect window lengths Extend window by 1 sample if needed for DFT-even symmetry Truncate window by 1 sample if needed for DFT-even symmetry