Source code for Constellations.BaseConstellation

# This file is part of NFDMLab.
#
# NFDMLab is free software; you can redistribute it and/or
# modify it under the terms of the version 2 of the GNU General
# Public License as published by the Free Software Foundation.
#
# NFDMLab is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with NFDMLab; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# 02111-1307 USA
#
# Contributors:
# Sander Wahls (TU Delft) 2018

from abc import ABC, abstractmethod
import numpy as np
from QualityAssessment import ConstellationDiagram
from Helpers import checked_get

[docs]class BaseConstellation(ABC): """Base class for constellations such as QAM or PSK. Notes ----- * Other constellations should be derived from this class. They need to initialize self._alphabet, which is returned by the alphabet property, self._bit_matrix, which is returned by the bit_matrix property, and self._str, which is returned by the str property. * Bits are represented by the numbers zero and one. """ @property def alphabet(self): """numpy.array (complex) : Vector of constellation points. The number of points has to be a power of two.""" return checked_get(self, "_alphabet", np.ndarray) @property def bit_matrix(self): """numpy.array(int) : Matrix of bit patterns. The size of the matrix should be N x M, where N is the size of the alphabet and M is the number of bits per symbol. The n-th row of the matrix contains the bit pattern of the n-th symbol in the alphabet. The allowed values in the matrix are zero and one.""" return checked_get(self, "_bit_matrix", np.ndarray) @property def name(self): """str : Identifcation string for the constellation, should also specify parameters.""" return checked_get(self, "_name", str)
[docs] def size(self): """int : Number of elements in the alphabet.""" return np.size(self.alphabet)
[docs] def idx2symbol(self, idx): """Translates a vector of indices into a vector of symbols. Parameters ---------- idx : numpy.array(integer) Vector of indices. Returns ------- numpy.array(complex) A array with the same length as idx whose n-th element is self.alphabet[idx[n]]. """ ni = np.size(idx) symbols = np.zeros(ni, dtype=complex) for i in range(0, ni): symbols[i] = self.alphabet[idx[i]] return symbols
[docs] def symbol2idx(self, symbols): """Translates a vector of symbols into a vector of indices. Parameters ---------- symbols : numpy.array(complex) Vector of symbols. Returns ------- numpy.array(integer) A vector with the same length as symbols whose n-th element is the integer number i=i(n) in 0,...,numpy.size(symbols)-1 that minimizes the Eucledian distance \|symbols[n] - self.alphabet[i]\|. """ ns = np.size(symbols) idx = np.zeros(ns, dtype=int) for i in range(0, ns): dists = np.abs(symbols[i] - self.alphabet) idx[i] = np.argmin(dists) return idx
[docs] def idx2bits(self, idx): """Translates a vector of indices into a bit pattern. Parameters ---------- idx : numpy.array(complex) Vector of indices Returns ------- numpy.array(complex) Vector of bits """ if np.size(idx)==1: return self.bit_matrix[idx, :] bits = np.zeros((np.size(idx), np.size(self.bit_matrix, 1)), dtype=int) for i in range(0, np.size(idx)): bits[i,:] = self.bit_matrix[idx[i], :] return bits
[docs] def show(self, new_fig=False): """Shows the constellation alphabet together with the bit patterns. Parameters ---------- new_fig : bool Always creates a new figure if True, reuses existing figures if False. Returns ------- Figure matplotlib figure handle (only if new_fig=True) """ constellation_diagram = ConstellationDiagram(self) return constellation_diagram.plot(np.array([]), show_bits=True, title=self.name, new_fig=new_fig)
[docs] def gray_code(self, m, n): """Gray code bit matrix. Parameters ---------- m : int n : int Returns ------- numpy.array(int) Matrix as described in the bit_matrix property. The number of bit patterns (rows) is m*n. The number of bits per pattern (columns) is ceil(log2(m*n)). """ bit_matrix = np.array([[0], [1]], dtype=int) for i in range(0, int(np.ceil(np.log2(m*n)))-1): r = np.size(bit_matrix, 0) tmp1 = np.hstack((np.zeros((r, 1), dtype=int), bit_matrix)) tmp2 = np.hstack((np.ones((r, 1), dtype=int), np.flipud(bit_matrix))) bit_matrix = np.vstack((tmp1, tmp2)) for i in range(1, m+1, 2): bit_matrix[i*n:(i+1)*n, :] = np.flipud(bit_matrix[i*n:(i+1)*n, :]) return bit_matrix