#QPSK - a simuation of QPSK moduling
def randomStepVal(amp=1.0):
if (random() >= 0.5):
return amp
else:
return 0
#given a list of tuple, and generate a piecewise function
def PiecewiseWithConsts(lst):
#Gather all const values, and generate a dict for it
constFuncs = dict()
for pair in lst:
if (not pair[1] in constFuncs):
constval = pair[1]
constFunc(x) = constval
constFuncs[pair[1]] = constFunc
funclist = [[(lst[0][0], lst[0][0]), constFuncs[lst[0][1]]]]
for pair in lst:
oldpair = funclist[-1][0];
funclist[-1][0] = (oldpair[0], pair[0])
funclist.append([(pair[0], pair[0] + 1), constFuncs[pair[1]]])
return Piecewise(funclist)
def randomStepSignal(T):
valdict = dict()
def f_stepSig(t):
smpT = floor(t / T) * T
if (smpT in valdict):
return valdict[smpT];
else:
valdict[smpT] = randomStepVal()
return valdict[smpT]
return f_stepSig
#IQ moduling
def module_IQ(mapped, w):
(f_I, f_Q) = mapped
def f_IQMod(t):
return f_I(t) * cos (w * t) - f_Q(t) * sin(w*t)
return f_IQMod
def mapBoolToValue(boolExp, trueValue, falseValue):
if (boolExp):
return trueValue
else:
return falseValue
def xor(a, b):
return int(a).__xor__(int(b))
def combSignalBits(sig, period, t, nBits):
val = 0;
sampT = floor(t / (period * nBits)) * (period * nBits) + period / 2.0
for i in range(nBits):
val = val | (Integer(sig(sampT + period * i)) << i)
return val
def IQMapper_ByList(valMap, indexer):
def f_I(t):
return valMap[indexer(t)][0]
def f_Q(t):
return valMap[indexer(t)][1]
return (f_I, f_Q)
#The QPSK mapper, give a signal function and it's period, return a
#The mapper using Gray Code to arrange values
def IQMapper_qpsk(sig, period):
amp = 1 / sqrt(2)
valueMap = [(amp, amp), (-amp, amp), (-amp, -amp), (amp, -amp)]
def combValue(t):
return combSignalBits(sig, period, t, 2)
return IQMapper_ByList(valueMap, combValue)
def IQMapper_8psk(sig, period):
C = cos(pi / 8)
S = sin(pi / 8)
valueMap = [(C, S), (S, C), (-S, C), (-C, S), (-C, -S), (-S, -C), (S, -C), (C, -S)]
def combValue(t):
return combSignalBits(sig, period, t, 3)
return IQMapper_ByList(valueMap, combValue)
def IQMapper_qam(sig, period):
A = 1.0 / sqrt(2.0)
A3 = A * 3.0
valueMap = [(A3, A3), (A, A3), (-A, A3), (-A3, A3), (-A3, A), (-A, A), (A, A), (A3, A),
(A3, -A), (A, -A), (-A, -A), (-A3, -A), (-A3, -A3), (-A, -A3), (A, -A3), (A3, -A3)]
def combValue(t):
return combSignalBits(sig, period, t, 4)
return IQMapper_ByList(valueMap, combValue)
def moduleSignal(sig, period, mapper, moduler, w = 0):
def sig_wrap(t):
return sig(t)
mapped = mapper(sig_wrap, period)
if (w == 0):
w = 2 * pi / period;
moduled = moduler(mapped, w)
lst = [sig_wrap]
for mp in mapped:
lst.append(mp)
lst.append(moduled)
return lst
T = 0.5
count = 64
sig = randomStepSignal(T)
plotFuncs = moduleSignal(sig, T, IQMapper_qpsk, module_IQ)
plotRange = (0.0, T * count)
plotFuncs += moduleSignal(sig, T, IQMapper_8psk, module_IQ)
plotFuncs += moduleSignal(sig, T, IQMapper_qam, module_IQ)
graphs = [plot(func, plotRange) for func in plotFuncs]
for g in graphs:
g.show(aspect_ratio = 1.0)