Ejemplo n.º 1
0
def transmission(x, L, K, N, M, Ncp, Nt, Nr, SNR):
    ''' 
    x: 发送端的发送信号
    L: 信道长度
    K: 稀疏度
    N: 子载波数
    M: 每帧的OFDM符号数
    Ncp: 循环前缀长度
    Nt: 发送天线数
    Nr: 接收天线数
    SNR: 信噪比
    '''
    ''' 时域/频域的信道响应'''
    h = zeros((Nr, Nt, L), dtype=np.complex)
    H = zeros((Nr, Nt, N), dtype=np.complex)
    for r in range(Nr):
        for t in range(Nt):
            h[r, t, :] = channel(L, K)  # 第r个接收天线,与第t个发送天线的1个符号周期内的信道脉冲响应
            H[r, t, :] = dot(fftMatrix(N, L), h[r, t, :])  # 信道频率响应
    ''' 傅里叶正变换矩阵 '''
    W = fftMatrix((N + Ncp), L)  # 傅里叶正变换矩阵,即:使稀疏的h变为不稀疏的H的基
    W_M = W  # 对于慢时变信道,在M个符号周期内,H保持不变。相当于对W做M次重复
    for i in range(M - 1):
        W_M = np.r_[W_M, W]

    for t in range(Nt):
        ''' 第t个天线的发送数据 '''
        x_t = x[:, t]
        ''' 将时域的发送信号,变换到频域 '''
        X_t = fft(x_t)
        ''' 测量矩阵 '''
        X_t = diag(
            X_t)  # 将发送信号作为观测矩阵的对角元素,X=diag(X(0),X(1),...,X(N-1))是N*N的子载波矩阵

        if t == 0:
            X_wave = dot(X_t, W_M)
        else:
            X_wave = np.c_[X_wave, dot(X_t, W_M)]
    ''' X_wave与Nr*Nr单位矩阵的克罗内克积 '''
    Kronecker = kron(eye(Nr, Nr), X_wave)
    ''' Nt*Nr*L的信道脉冲响应向量 '''
    for r in range(Nr):
        for t in range(Nt):
            h_rt = h[r, t, :].reshape(-1, 1)  # 第r个接收天线,与第t个发送天线的1个符号周期内的信道脉冲响应
            if r == 0 and t == 0:
                h_vector = h_rt
            else:
                h_vector = np.r_[h_vector, h_rt]
    ''' 理想信道传输 '''
    Y = dot(Kronecker, h_vector)
    ''' AWGN '''
    Y = awgn(Y, SNR)

    y = Y.reshape(-1, Nr)
    y = ifft(y, axis=0)

    return h, H, y
Ejemplo n.º 2
0
def transmission(x, SNR=dSNR, L=dL, K=dK, N=dN, Ncp=dNcp):
    ''' 
    x:   发送端的发送信号
    SNR: 信噪比
    L:   信道长度
    K:   稀疏度
    N:   子载波数
    Ncp: 循环前缀长度
    '''
    ''' 时域的信道脉冲响应'''
    h = channel(L, K)
    ''' 信道频率响应H '''
    W = fftMatrix(N, L)  # 傅里叶正变换矩阵,即:使稀疏的h变为不稀疏的H的基
    H = dot(W, h)  # 频率的冲激响应
    H.shape = (N, 1)
    ''' 不考虑循环前缀在信道中的传输 '''
    x = x[:, Ncp:]
    x = x.reshape(N)
    # 将发送信号作为观测矩阵的对角元素,X=diag(X(0),X(1),...,X(N-1))是N*N的子载波矩阵
    X = fft(x)
    ''' 测量矩阵 '''
    X = diag(X)
    ''' 理想信道传输 '''
    X_H = dot(X, H)
    ''' 添加高斯白噪声,得接收信号向量Y '''
    Y = awgn(X_H, SNR)  # 加入复高斯白噪声,得到接收到的信号(频域表示)
    #No = Y-X_H                  # Y = X*H + No

    y = ifft(Y, axis=0)
    y = y.reshape(1, N)
    y = np.c_[y[:, -Ncp:], y]

    return h, H, y
Ejemplo n.º 3
0
def receiver(y,
             pos,
             etype=detype,
             pos_type=dpos_type,
             L=dL,
             K=dK,
             N=dN,
             Ncp=dNcp,
             modulate=dmodulate):
    '''
    y:        接收信号
    pos:      导频图样
    etype:    'CS' 或 'LS'
    pos_type: 'from_pos':使用传入的参数 pos 作为导频图样
              其他(数字类型):与 pos 相比,猜对了其中【数字】个导频位置。用于:非法用户随机猜测导频位置,此时传入的pos为发送端的导频图样
    L:        信道长度
    K:        稀疏度
    N:        子载波数
    Ncp:      循环前缀长度
    modulate: 星座调制
    '''

    P = size(pos)
    if pos_type != 'from_pos':
        right_num = int(pos_type)
        pos = guess_pos(N, P, pos, right_num)
    ''' 移除循环前缀'''
    y = y[:, Ncp:]
    ''' 串并转换 '''
    y = y.reshape(N, 1)
    ''' FFT '''
    Y = fft(y, axis=0)
    ''' 并串转换 '''
    pass
    ''' 导频选择矩阵 '''
    I = eye(N, N)  # NxN的单位矩阵
    S = I[pos, :]  # PxN的导频选择矩阵,从NxN的单位矩阵选取与导频位置对应的P行,用于从N个子载波中选择出P个导频位置
    ''' 提取导频 '''
    Yp = dot(S, Y)  # Px1的导频位置的接受信号向量
    #Xp = dot( dot(S,X), transpose(S) )  # PxP的斜对角阵,对角线元素是导频位置的X。如果导频位置设为1,则Xp实际上就是PxP的单位矩阵
    Xp = eye(P, P)
    W = fftMatrix(N, L)  # 傅里叶正变换矩阵,即:使稀疏的h变为不稀疏的H的基
    Wp = dot(S, W)  # PxL的矩阵,从W中选取与导频位置对应的P行

    if etype == 'CS':
        ''' CS信道估计'''
        # s   = Phi*Psi*x
        # Y   = X  * W *h + N
        #     = X  * H    + N
        # hat_H = omp(K,s,Phi,Psi)
        #   ==>   s   = Y
        #   ==>   Phi = X
        #   ==>   Psi = W

        # Xp*Wp作为密钥。若Xp是单位矩阵,则Xp*Wp=Wp,密钥取决于Wp。
        # 而Wp又是从W中选取的与导频位置对应的P行,所以密钥取决于导频位置pos
        re_h = OMP(K, Yp, Xp, Wp)  # OMP是时域估计算法,估计得到时域的h
        re_H = dot(W, re_h)  # 傅里叶变换,得到频域的H
    elif etype == 'LS':
        ''' LS信道估计 '''
        Hp_ls = dot(inv(Xp), Yp)  # LS、MMSE是频域估计算法,得到导频处的Hp
        re_H = interpolation(Hp_ls, pos, N)  # 根据导频处Hp进行插值,恢复信道的H
        re_h = dot(ifftMatrix(L, N), re_H)  # 傅里叶逆变换,得到时域的h
    ''' 信道均衡 '''
    Y = Y / re_H
    ''' 移除导频 '''
    Y = remove_OFDM_pilot(Y, pos)
    ''' 星座点归一化 '''
    diagram = Y * normal_coef[modulate]
    ''' BPSK/QPSK/16QAM解调 '''
    bits = diagram_demod(diagram, modulate)
    ''' 解交织 '''
    bits = interlace_decode(bits, 2, size(bits) / 2)
    ''' viterbi译码 '''
    bits = viterbi_decode(bits)

    return re_h, re_H, bits, diagram
Ejemplo n.º 4
0
def receiver(y,
             L,
             K,
             N,
             M,
             Ncp,
             Nt,
             Nr,
             pos,
             demodulate_type,
             etype="CS",
             pos_type="from_pos"):
    '''
    y: 接收信号
    L: 信道长度
    K: 稀疏度
    N: 子载波数
    M: 每帧的OFDM符号数
    Ncp: 循环前缀长度
    Nt: 发送天线数
    Nr: 接收天线数
    pos: 导频图样
    demodulate_type: 调制方式。1 -> BPSK,  2 -> QPSK,  4 -> 16QAM
    etype: 'CS' 或 'LS'
    pos_type:
        'from_pos':使用传入的参数 pos 作为导频图样
        其他(数字类型):与 pos 相比,猜对了其中【数字】个导频位置。用于:非法用户随机猜测导频位置,此时传入的pos为发送端的导频图样
    '''

    P = size(pos)
    if pos_type != 'from_pos':
        right_num = int(pos_type)
        pos = guess_pos(N, P, pos, right_num)
    ''' CS/LS重构的信道响应 '''
    re_h = zeros((Nr, Nt, L, M), dtype=np.complex)
    re_H = zeros((Nr, Nt, N, M), dtype=np.complex)
    ''' 接收天线接收的数据'''
    Y = zeros((N, M, Nr), dtype=np.complex)  # N*M*Nr,利用第三维表示不同天线接收的OFDM符号

    for r in range(Nr):
        ''' 第r个天线的接收数据 '''
        y_r = y[:, r]
        ''' 串并转换 '''
        y_r = y_r.reshape(-1, M)
        ''' 移除循环前缀'''
        y_r = y_r[Ncp:, :]
        ''' FFT '''
        Y_r = fft(y_r, axis=0)
        Y[:, :, r] = Y_r
        ''' 估计第t个发送天线与第r个发送天线之间的h_rt'''
        for t in range(Nt):
            ''' 第t个天线上的导频图样'''
            pos_t = pos[:, t]
            ''' 导频选择矩阵 '''
            P = size(pos_t)
            I = eye(N, N)  # NxN的单位矩阵
            S = I[
                pos_t, :]  # PxN的导频选择矩阵,从NxN的单位矩阵选取与导频位置对应的P行,用于从N个子载波中选择出P个导频位置
            ''' 提取导频 '''
            Yp = dot(S, Y_r)  # Px1的导频位置的接受信号向量
            #Xp = dot( dot(S,X), transpose(S) ) # PxP的斜对角阵,对角线元素是导频位置的X。如果导频位置设为1,则Xp实际上就是PxP的单位矩阵
            Xp = eye(P, P)
            W = fftMatrix(N, L)  # 傅里叶正变换矩阵,即:使稀疏的h变为不稀疏的H的基
            Wp = dot(S, W)  # PxL的矩阵,从W中选取与导频位置对应的P行

            if etype == 'CS':
                ''' CS信道估计'''
                # X_wave作为密钥。若Xp是单位矩阵,则Xp*Wp=Wp,密钥取决于Wp。
                # 而Wp又是从W中选取的与导频位置对应的P行,所以密钥取决于导频位置pos
                for m in range(M):  # 第m个符号的CS重构的h。对于慢衰落信道,不同符号的重构h应该大致相同
                    re_h[r, t, :,
                         m] = OMP(K, Yp[:, m], Xp,
                                  Wp).reshape(L)  # OMP是时域估计算法,估计得到时域的h
                    re_H[r, t, :, m] = dot(W, re_h[r, t, :, m])  # 傅里叶变换,得到频域的H

            elif etype == 'LS':
                ''' LS信道估计 '''
                Hp_ls = dot(inv(Xp), Yp)  # LS、MMSE是频域估计算法,得到导频处的Hp
                for m in range(M):  # 对第m个符号的Hp进行插值
                    re_H[r, t, :, m] = interpolation(Hp_ls[:, m], pos_t,
                                                     N)  # 根据导频处Hp进行插值,恢复信道的H
                    re_h[r, t, :, m] = dot(ifftMatrix(L, N),
                                           re_H[r, t, :, m])  # 傅里叶逆变换,得到时域的h
    ''' 空时解码 '''
    Y = STBC_decode(Y, re_H, N, M, Nt, Nr)
    ''' 移除导频 '''
    Y = remove_MIMO_pilot(Y, pos)
    ''' 并串转换 '''
    diagram = Y.reshape(-1)
    ''' 星座点归一化 '''
    diagram = diagram * normal_coef[demodulate_type]
    ''' BPSK/QPSK/16QAM解调 '''
    bits = diagram_demod(diagram, demodulate_type)
    ''' 解交织 '''
    bits = interlace_decode(bits, 8, size(bits) / 8)
    ''' viterbi译码 '''
    bits = viterbi_decode(bits)

    return re_h, re_H, bits, diagram