Beispiel #1
0
def apply_filter_py(E, os, wxy):
    """
    Apply the equaliser filter taps to the input signal.

    Parameters
    ----------

    E      : array_like
        input signal to be equalised

    os     : int
        oversampling factor

    wxy    : tuple(array_like, array_like,optional)
        filter taps for the x and y polarisation

    Returns
    -------

    Eest   : array_like
        equalised signal
    """
    # equalise data points. Reuse samples used for channel estimation
    # this seems significantly faster than the previous method using a segment axis
    E = np.atleast_2d(E)
    pols = E.shape[0]
    Ntaps = wxy[0].shape[1]
    X1 = segment_axis(E[0], Ntaps, Ntaps - os)
    X = X1
    ww = wxy[0].flatten()

    # Case for a butterfly-configured EQ
    if pols > 1:
        for pol in range(1, pols):
            X_P = segment_axis(E[pol], Ntaps, Ntaps - os)
            X = np.hstack([X, X_P])
            ww = np.vstack([ww, wxy[pol].flatten()])

        # Compute the output
        Eest = np.dot(X, ww.transpose())

        # Extract the error (per butterfly entry)
        Eest_tmp = Eest[:, 0]
        for pol in range(1, pols):
            Eest_tmp = np.vstack([Eest_tmp, Eest[:, pol]])
        Eest = Eest_tmp

    # Single mode EQ
    else:
        Eest = np.dot(X, ww.transpose())
        Eest = np.atleast_2d(Eest)

    return Eest
Beispiel #2
0
def viterbiviterbi(E, N, M):
    """
    Viterbi-Viterbi blind phase recovery for an M-PSK signal

    Parameters
    ----------
    E : array_like
        the electric field of the signal
    N : int
        number of samples to average over
    M : int
        order of the M-PSK

    Returns
    -------
    Eout : array_like
        Field with compensated phases
    """
    E2d = np.atleast_2d(E)
    Eout = np.zeros_like(E2d)
    L = E2d.shape[1]
    for i in range(E2d.shape[0]):
        Et = E2d[i]
        L = len(Et)
        phi = np.angle(Et)
        E_raised = np.exp(1.j * phi)**M
        sa = segment_axis(E_raised, N, N - 1)
        phase_est = np.sum(sa, axis=1)
        phase_est = np.unwrap(np.angle(phase_est))
        phase_est = (phase_est - np.pi) / M
        if N % 2:
            Eout[i, (N - 1) // 2:L -
                 (N - 1) // 2] = E2d[i, (N - 1) // 2:L -
                                     (N - 1) // 2] * np.exp(-1.j * phase_est)
        else:
            Eout[i, N // 2 - 1:L -
                 (N // 2)] = E2d[i, N // 2 - 1:L -
                                 (N // 2)] * np.exp(-1.j * phase_est)
    #if M == 4: # QPSK needs pi/4 shift
    # need a shift by pi/M for constellation points to not be on the axis
    if E.ndim == 1:
        return Eout.flatten(), phase_est.flatten()
    else:
        return Eout, phase_est
Beispiel #3
0
def apply_filter_py(E, os, wxy, modes=None):
    """
    Apply the equaliser filter taps to the input signal.

    Parameters
    ----------

    E      : array_like
        input signal to be equalised

    os     : int
        oversampling factor

    wxy    : tuple(array_like, array_like,optional)
        filter taps for the x and y polarisation
    
    modes : array_like, optional
        mode numbers over which to apply the filters

    Returns
    -------

    Eest   : array_like
        equalised signal
    """
    # equalise data points. Reuse samples used for channel estimation
    # this seems significantly faster than the previous method using a segment axis
    # TODO something fails still in this function
    E = np.atleast_2d(E)
    Ntaps = wxy.shape[-1]
    nmodes_max = wxy.shape[0]
    if modes is None:
        modes = np.arange(nmodes_max)
        nmodes = nmodes_max
    else:
        modes = np.atleast_1d(modes)
        assert np.max(
            modes
        ) < nmodes_max, "largest mode number is larger than shape of signal"
        nmodes = modes.sizeX = X1
    X = segment_axis(E[modes[0]], Ntaps, Ntaps - os)
    ww = wxy[0].flatten()
    # Case for a butterfly-configured EQ
    if nmodes_max > 1:
        for pol in range(1, nmodes):
            X_P = segment_axis(E[modes[pol]], Ntaps, Ntaps - os)
            X = np.hstack([X, X_P])
            ww = np.vstack([ww, wxy[modes[pol]].flatten()])

        # Compute the output
        Eest = np.dot(X, ww.transpose())

        # Extract the error (per butterfly entry)
        Eest_tmp = Eest[:, 0]
        for pol in range(1, nmodes):
            Eest_tmp = np.vstack([Eest_tmp, Eest[:, modes[pol]]])
        Eest = Eest_tmp

    # Single mode EQ
    else:
        Eest = np.dot(X, ww.transpose())
        Eest = np.atleast_2d(Eest)

    return Eest