import numpy as np

# 16QAM constellation:
#                Q
#  1011    1001  |   0001  0011
#  1010    1000  |   0000  0010
#---------------------------------> I
#  1110    1100  |   0100  0110
#  1111    1101  |   0101  0111
def _16QAM_table():
    table = np.empty(16, 'complex')
    QAM16_LEVEL_1 = 1/np.sqrt(10)
    QAM16_LEVEL_2 = 3/np.sqrt(10)
    table[0]  = QAM16_LEVEL_1 + 1j * QAM16_LEVEL_1
    table[1]  = QAM16_LEVEL_1 + 1j * QAM16_LEVEL_2
    table[2]  = QAM16_LEVEL_2 + 1j * QAM16_LEVEL_1
    table[3]  = QAM16_LEVEL_2 + 1j * QAM16_LEVEL_2
    table[4]  = QAM16_LEVEL_1 - 1j * QAM16_LEVEL_1
    table[5]  = QAM16_LEVEL_1 - 1j * QAM16_LEVEL_2
    table[6]  = QAM16_LEVEL_2 - 1j * QAM16_LEVEL_1
    table[7]  = QAM16_LEVEL_2 - 1j * QAM16_LEVEL_2
    table[8]  = -QAM16_LEVEL_1 + 1j * QAM16_LEVEL_1
    table[9]  = -QAM16_LEVEL_1 + 1j * QAM16_LEVEL_2
    table[10] = -QAM16_LEVEL_2 + 1j * QAM16_LEVEL_1
    table[11] = -QAM16_LEVEL_2 + 1j * QAM16_LEVEL_2
    table[12] = -QAM16_LEVEL_1 - 1j * QAM16_LEVEL_1
    table[13] = -QAM16_LEVEL_1 - 1j * QAM16_LEVEL_2
    table[14] = -QAM16_LEVEL_2 - 1j * QAM16_LEVEL_1
    table[15] = -QAM16_LEVEL_2 - 1j * QAM16_LEVEL_2
    return table

def nrSymbolDemodulate(input, mod, nVar = 1e-10, DecisionType = 'soft'):
    output = np.empty(0, 'float')

    for symbol in input:
        if mod == 'BPSK':
            output = np.append(output, np.real(symbol) + np.imag(symbol))
        elif mod == 'QPSK':
            output = np.append(output, np.real(symbol))
            output = np.append(output, np.imag(symbol))
        elif mod == 'QAM16':
            output = np.append(output, np.real(symbol))
            output = np.append(output, np.imag(symbol))
            output = np.append(output, -(np.abs(np.real(symbol)) - 2/np.sqrt(10)))
            output = np.append(output, -(np.abs(np.imag(symbol)) - 2/np.sqrt(10)))

    if DecisionType == 'soft':
        output /= nVar / np.exp(1)
        if mod == 'QAM16':
            output /= 2
    else:
        output = output < 0
    return output
    