Source code for imtoolkit.TASTCode

# Copyright (c) IMToolkit Development Team
# This toolkit is released under the MIT License, see LICENSE.txt

import numpy as np
from .Modulator import PSK, StarQAM


[docs]class TASTCode(object): """Differential space-time shift keying using threaded algebraic space-time (DSTSK-TAST) coding, which was proposed in [1]. Other relevant papers are found in [2,3]. - [1] C. Xu, P. Zhang, R. Rajashekar, N. Ishikawa, S. Sugiura, L. Wang, and L. Hanzo, ``Finite-cardinality single-RF differential space-time modulation for improving the diversity-throughput tradeoff,'' IEEE Trans. Commun. Press, vol. 67, no. 1, pp. 318--335, 2019. - [2] C. Xu, R. Rajashekar, N. Ishikawa, S. Sugiura, and L. Hanzo, ``Single-RF index shift keying aided differential space-time block coding,'' IEEE Trans. Signal Process., vol. 66, no. 3, pp. 773--788, 2018. - [3] C. Xu, P. Zhang, R. Rajashekar, N. Ishikawa, S. Sugiura, Z. Wang, and L. Hanzo, ````Near-perfect'' finite-cardinality generalized space-time shift keying,'' IEEE J. Sel. Areas Commun., in press. """ def __init__(self, M, Q, L, modtype = "SQAM"): """ Args: M (int): the number of transmit antennas. Q (int): the number of dispersion elements. L (int): the constellation size. modtype (str): the constellation type. """ self.M = M self.Nc = M * L * Q self.B = np.log2(self.Nc) if modtype == "SQAM": mod = StarQAM(L) La = mod.Nlevels Lp = mod.subConstellationSize elif modtype == "PSK": mod = PSK(L) La = 1 Lp = L apsksymbols = mod.symbols G = np.zeros((M, M), dtype=np.complex) G[0, M - 1] = 1 for m in range(M - 1): G[m + 1, m] = 1 msymbols = np.exp(1j * 2.0 * np.pi * np.arange(M) / (Lp * np.max([M, Q]))) u = self.getDiversityMaximizingFactors(M, Q, La, Lp) self.codes = np.zeros((M * L * Q, M, M), dtype=np.complex) for l in range(L): for m in range(M): for q in range(Q): qsymbols = np.exp(1j * 2.0 * np.pi * q * u * np.arange(M) / (L * Q)) self.codes[Q * M * l + m * Q + q] = np.matmul( apsksymbols[l] * msymbols[m] * np.linalg.matrix_power(G, m), np.diag(qsymbols))
[docs] def putRate(self): print("B / M = %d / %d = %d [bit/symbol]" % (self.B, self.M, self.B / self.M))
[docs] def getDiversityMaximizingFactors(self, M, Q, La, Lp): if M == 2 and Q == 1 and La == 1 and Lp == 2: # Rate = 1 u = [1, 1] elif M == 2 and Q == 2 and La == 1 and Lp == 2: # Rate = 1.5 u = [1, 3] elif M == 2 and Q == 4 and La == 1 and Lp == 2: # Rate = 2 u = [1, 3] elif M == 2 and Q == 2 and La == 1 and Lp == 8: # Rate = 2.5 # u = [1,7] [1, p. 22] # u = [3,13] [1, p. 26] u = [15, 5] elif M == 2 and Q == 2 and La == 2 and Lp == 8: # Rate = 3 # u = [3,13] # [1, p. 22] u = [2, 14] elif M == 2 and Q == 4 and La == 1 and Lp == 8: # Rate = 3 u = [1, 7] elif M == 2 and Q == 4 and La == 2 and Lp == 8: # Rate = 3.5 u = [29, 3] elif M == 2 and Q == 4 and La == 1 and Lp == 16: # Rate = 3.5 u = [21, 59] elif M == 2 and Q == 4 and La == 4 and Lp == 8: # Rate = 4, maxp = 0.080042 u = [29, 3] elif M == 2 and Q == 8 and La == 2 and Lp == 8: # Rate = 4, maxp = 0.0957012 u = [53, 27] elif M == 2 and Q == 16 and La == 1 and Lp == 8: # Rate = 4, maxp = 0.109983 u = [51, 81] elif M == 2 and Q == 8 and La == 1 and Lp == 16: # Rate = 4, maxp = 0.140074 u = [3, 117] elif M == 2 and Q == 4 and La == 4 and Lp == 16: # Rate = 4.5 u = [7, 57] elif M == 2 and Q == 8 and La == 4 and Lp == 16: # rate = 5, maxp = 0.0511476 u = [108, 52] elif M == 2 and Q == 16 and La == 4 and Lp == 8: # rate = 5, maxp = 0.04216 u = [39, 12] elif M == 2 and Q == 32 and La == 2 and Lp == 8: # rate = 5, maxp = 0.0483617 u = [242, 46] elif M == 2 and Q == 8 and La == 8 and Lp == 16: # Rate = 5.5 u = [3, 117] elif M == 2 and Q == 8 and La == 8 and Lp == 32: # Rate = 6 u = [11, 237] elif M == 4 and Q == 1 and La == 1 and Lp == 2: # Rate = 0.75 u = [1, 1, 1, 1] elif M == 4 and Q == 2 and La == 1 and Lp == 2: # Rate = 1 u = [1, 1, 3, 3] elif M == 4 and Q == 2 and La == 1 and Lp == 4: # Rate = 1.25 u = [1, 3, 7, 5] elif M == 4 and Q == 2 and La == 1 and Lp == 8: # Rate = 1.5 # u = [1,3,7,9] u = [1, 5, 11, 15] elif M == 4 and Q == 4 and La == 1 and Lp == 8: # Rate = 1.75 # u = [9,21,15,27] u = [5, 25, 11, 31] elif M == 4 and Q == 1 and La == 4 and Lp == 16: # rate = 2, maxp = 0.0712369 u = [0, 0, 0, 0] elif M == 4 and Q == 1 and La == 1 and Lp == 64: # rate = 2, maxp = 0.0490677 u = [0, 0, 0, 0] elif M == 4 and Q == 2 and La == 4 and Lp == 8: # rate = 2, maxp = 0.0969766 u = [2, 13, 3, 14] elif M == 4 and Q == 2 and La == 1 and Lp == 32: # rate = 2, maxp = 0.0980171 u = [59, 31, 49, 41] elif M == 4 and Q == 4 and La == 2 and Lp == 8: # rate = 2, maxp = 0.214639 u = [21, 3, 29, 11] elif M == 4 and Q == 4 and La == 1 and Lp == 16: # rate = 2, maxp = 0.19509 u = [37, 27, 11, 21] elif M == 4 and Q == 8 and La == 2 and Lp == 4: # rate = 2, maxp = 0.199766 u = [26, 9, 31, 14] elif M == 4 and Q == 8 and La == 1 and Lp == 8: # rate = 2, maxp = 0.312322 u = [15, 41, 57, 63] elif M == 4 and Q == 16 and La == 1 and Lp == 4: # rate = 2, maxp = 0.256578 u = [31, 61, 49, 59] elif M == 4 and Q == 32 and La == 1 and Lp == 2: # rate = 2, maxp = 0.312322 u = [51, 21, 5, 3] elif M == 4 and Q == 16 and La == 1 and Lp == 8: # Rate = 2.25 u = [21, 37, 91, 83] elif M == 4 and Q == 8 and La == 8 and Lp == 16: # rate = 3, maxp = 0.0260332 u = [114, 25, 14, 99] elif M == 4 and Q == 16 and La == 4 and Lp == 16: # rate = 3, maxp = 0.0546157 u = [97, 145, 236, 25] elif M == 4 and Q == 32 and La == 4 and Lp == 8: # rate = 3, maxp = 0.0557874 u = [196, 108, 252, 65] elif M == 4 and Q == 64 and La == 1 and Lp == 16: # Rate = 3 u = [633, 603, 559, 797] elif M == 8 and Q == 1 and La == 2 and Lp == 8: # rate = 0.875, maxp = 0.24203 u = [0, 0, 0, 0, 0, 0, 0, 0] elif M == 8 and Q == 2 and La == 2 and Lp == 4: # rate = 0.875, maxp = 0.298721 u = [1, 1, 7, 2, 7, 6, 1, 7] elif M == 8 and Q == 4 and La == 1 and Lp == 4: # rate = 0.875, maxp = 0.522137 u = [9, 11, 3, 7, 15, 13, 5, 1] elif M == 8 and Q == 2 and La == 2 and Lp == 8: # rate = 1, maxp = 0.24203 u = [9, 1, 1, 15, 14, 1, 15, 10] elif M == 8 and Q == 4 and La == 2 and Lp == 4: # rate = 1, maxp = 0.262553 u = [1, 11, 2, 11, 14, 5, 5, 15] elif M == 8 and Q == 8 and La == 1 and Lp == 4: # rate = 1, maxp = 0.375254 u = [25, 31, 15, 13, 7, 1, 17, 3] elif M == 16 and Q == 64 and La == 1 and Lp == 1: # rate = 0.625, maxp = 0 u = [63, 0, 18, 34, 62, 36, 37, 1, 26, 55, 37, 54, 46, 15, 39, 26] else: print("TASTCode.py does not support the given parameters M = %d, Q = %d, La = %d, and Lp = %d" % ( M, Q, La, Lp)) u = np.zeros(M) return np.array(u)