MATLAB
几个函数在Python
的简易实现
基本基于 numpy, 不进行参数类型检查
1. 误码率
直接比较(==)两个等形状矩阵的 对应位置元素不相同 的占比, 输入的两个矩阵为同一类型
import numpy as np
# Error rate of symbols
def get_Pe(demodu: np.ndarray, ans: np.ndarray) -> np.float64:
error_symbol_num = sum(demodu.reshape(-1) == ans.reshape(-1))
return 1 - error_symbol_num / len(demodu.reshape(-1))
2. 误比特率
两个输入矩阵必须为十进制的int
型!
demod_list
可自行拓展, 每个元素(比特构成的列表)的索引表示该二进制码元代表的十进制数字.
第 4, 5 行可以将十进制数字矩阵转化为一维比特数组 .
# Error rate of bits,and inputs should be np.array which is formed by 0~3
def get_BER(demodu: np.ndarray, ans: np.ndarray) -> np.float64:
demod_list = [[0, 0], [0, 1], [1, 0], [1, 1]]
demodu_bits = np.array([demod_list[idx] for idx in demodu.reshape(-1)]).reshape(-1)
ans_bits = np.array([demod_list[idx] for idx in ans.reshape(-1)]).reshape(-1)
return get_Pe(demodu_bits, ans_bits)
3. qam/psk 解调
可以自行拓展, 基于最小距离, 使用 np.vectorize
加速计算. 核心是比较当前码元和映射列表中每个元素的欧式距离. 输入矩阵为复数类型, 输出为同形状的十进制映射整形矩阵.
经 48000 个复数码元测试, 结果和MATLAB
的qamdemod
, pskdemod
函数的结果完全一致.
import numpy as np
def qamdemod(array: np.ndarray, maplist=None, init_phase=0) -> np.ndarray:
"""
Demodulate a array of complex numbers into decimal numbers.
Base on minimum distance criterion
:param array: np.ndarray, dtype == np.complex
The input array which is to be demodulated
:param maplist: list or np.ndarray, dtype == np.complex
The mapping list
:param init_phase: a float number
To correct the initial phase of the array
:return: np.ndarray, dtype == np.int
Demodulated result
"""
if maplist is None:
maplist = [1 + 0j, 0 + 1j, -1 + 0j, 0 - 1j]
maplist = np.array(maplist) * np.exp(+2 * np.pi * 1j * init_phase) # To correct the phase
# array = np.array(array) * np.exp(-2 * np.pi * 1j * init_phase) # Equivalent to the above line
# vectorized map function, faster than faster
vfunc = np.vectorize(lambda x:
np.argmin(np.abs(x - maplist)) # x will be broadcast automatically
)
demod = vfunc(array)
demod = demod.astype(np.int)
return demod
4. 简单测试例程
import numpy as np
test = np.array([[ 1.+0.j, 0.+1.j, -1.+0.j, 0.-1.j],
[ 0.5+0.6j, 0.+1.j, -1.+0.j, 0.-1.j]])
ans = np.array([[0, 1, 2, 3],
[0, 1, 2, 3]])
test_demodu = qamdemod(test)
pe = acc.get_Pe(test_demodu, ans)
BER = acc.get_BER(test_demodu, ans)
print(f" pe={pe}\nBER={BER}\ntest_demodu=\n{test_demodu}")
输出如下:
pe=0.125
BER=0.0625
test_demodu=
[[0 1 2 3]
[1 1 2 3]]
和MATLAB
对比如下, 可见结果一致.
npy
数据可以导出为mat
, 反之亦可