如何理解CDMA?
推薦參考大神文章 https://blog.csdn.net/dog250/article/details/6420427
(碼分多址(CDMA)的本質-正交之美)
首先我們先看《計算機網絡(第七版)》(謝希仁)第57頁關於CDMA的有關介紹
……
為了不讓碼片序列不會造成互相干擾,需要讓碼片序列對應的碼片向量相互正交。
那什么是正交?
從概念上來講,兩個向量的對應元素乘積總和為 0,則這兩個向量正交。
如果換成”垂直“兩個字也許會更好理解一點。
在二維平面中,x軸和y軸相互正交。
在三維平面中,x軸、y軸、z軸相互正交。
那么正交會給我們帶來什么樣的性質呢?
拋開碼片序列不談,我們可以考慮下面的例子
現有兩個用戶x軸和y軸,我們要給x發送1,給y發送2
於是,我們將兩個數據進行合成,變為 [1,2]。
顯然,它能夠被x和y准確的識別,因為x、y只關心屬於他們的“特征”,或者說“分量”。對於x軸來說,只需簡單的用數據data · x軸單位向量即可識別出自己所需要的數據為1。
這個例子雖然和CDMA有一些小區別,但是道理很相似。
個人覺得正交的最大好處就在於互不影響
實例
這里我們先不關心碼片序列是如何編碼的,我們看真正的一個例子
首先我們需要明白兩個式子:
對於任何碼片向量S,我們有規格化內積為1,即\(\frac{1}{m}S\cdot S=1\)
對於任何兩個不同的碼片向量S、T,它們正交,即\(S\cdot T=0\)
假設我們已經知道了A、B的碼片序列分別為
A:00001111
B:01011010
則它們對應的碼片向量為
A:-1 -1 -1 -1 1 1 1 1
B:-1 1 -1 1 1 -1 1 -1
假設向用戶A發送數據010
向用戶B發送數據011
則用戶A的數據經過用戶A的碼片序列編碼后為
-A A -A
用戶B的數據經過用戶B的碼片序列編碼后為
-B B B
二者疊加后數據為
-A-B A+B -A+B
對於用戶A來說,要解析這一串數據,只需用數據內積自己的碼片向量,即data·A。
即 (-A-B)·A = -A·A - B·A = -8 - 0 = -8,規格化之后就是 -1,對應的比特位為0。
同理 (A+B)·A = A·A + B·A = 8 + 0 = 8,規格化之后就是 1,對應的比特位為1。
(-A+B)·A = -A·A + B·A = -8 + 0 = -8,規格化之后就是 -1,對應的比特位為0。
即,用戶A成功解析出了數據為010。
python代碼實現
import numpy as np
# 定義碼片序列,轉為碼片向量
A = np.array([-1,-1,-1,-1,1,1,1,1])
B = np.array([-1,1,-1,1,-1,1,-1,1])
C = np.array([-1,-1,1,1,1,1,-1,-1])
# 用seq給數據編碼
def encode(data,seq):
c = None
for i in data:
if int(i):
if c is not None:
c = np.vstack([c,seq])
else: c = seq
else:
if c is not None:
c = np.vstack([c,-seq])
else: c = -seq
return c
# 用seq給數據解碼
def decode(data,seq):
d = data @ seq / seq.size
d[d<0] = 0
d = d.astype(int)
return "".join([str(x) for x in d.tolist()])
EA = encode('01110',A)
EB = encode('01001',B)
EC = encode('11100',C)
data = EA + EB + EC
print("合成數據為:",data,sep='\n')
print(decode(data,A))
print(decode(data,B))
print(decode(data,C))
運行結果: