将各种调制方式的代码集中一下,随时更新,应该大部分都是 python

文章目录

常见概念

以 OFDM 为例

symbol > 子载波 = 码元 > 比特
每一个symbol包含多个子载波,每个子载波嵌入一个码元,每个码元包含多个比特

导频 pilot 与 符号 symbol 同级别 ,每隔几个 symbol 插入一个 pilot


更新,pilot也可以与子载波同级别,导频有很多种插入法


循环前缀 CP 与 子载波 同级别,每个symbol的最后n个子载波复制了然后插入到开头作为CP
比如一个 symbol [1, 2, 3, 4, 5], 假设 CP 为2,那么加入CP后变为 [4, 5, 1, 2, 3, 4, 5]

OFDM

输入的待调制信号一般用一个矩阵表示[M, N]
其中,M(行数)表示 symbol数量,N(列数)表示一个symbol中的码元数量(一个码元可能有n位,即2**n进制)

比如说5个symbol,每个symbol 有4个码元,且码元是四进制的(值为 00, 01, 10, 11, 也就是 0, 1, 2 ,3),那么这个矩阵就为

0 1 2 3
1 0 2 3
3 1 0 2
2 1 0 3
1 3 0 2

主要步骤:
(1)QAM调制,也就是用复数代替原码元的实数比如 4QAM就是用[1 + 0j, 0 + 1j, -1 + 0j, 0 - 1j]代替[0, 1, 2, 3](替换顺序是一一对应的,规定好的)
(2)对每个symbol,也就是张量[M, N]的第二个纬度作 ifft,将频域转为时域

'''1. Data pre-processing'''

# Read the integer data. Serial data.
""" reshape(-1)意思是reshape成一维张量,至于具体数量由python自己算,有多少就是多少 """
original_64_test = np.loadtxt("./data_sets/labels64_test.csv", delimiter=",").astype(np.int).reshape(-1)
original_64_train = np.load("./data_sets/labels64_train.npy").astype(np.int).reshape(-1)
# Mapping int to complex. Real 4QAM modulation.
mQAM_list = [1 + 0j, 0 + 1j, -1 + 0j, 0 - 1j]
after_mapping = np.array([mQAM_list[orig] for orig in original_64_test])  # original_64_train
# Serial to parallel
to_ifft = after_mapping.reshape([-1, 64])

'''2. OFDM-modulation (IFFT)'''

# IFFT by row
""" 对每一行作 ifft """
after_ifft = np.fft.ifft(to_ifft, axis=-1)  # Axis over which to compute the inverse DFT. The last axis(,64) is used.
# Parseval's theorem, been checked by the 0th symbol.
assert abs(sum(abs(to_ifft[0])**2)/64 - sum(abs(after_ifft[0])**2)) < 0.0001

'''3. CP(Cyclic Prefix)'''

# Concatenating numpy arrays horizontally
''' 在每个 QFDM symbol 前面都加上自己的末尾16个码元 '''
""" 这里 axis=1 和 axis=-1 一样的 """
after_cp = np.concatenate((after_ifft[:, -16:], after_ifft), axis=1)
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐