|
| 1 | +import ccsfg |
| 2 | +import FactorGraphGeneration as FG |
| 3 | +import ccsinnercode as ccsic |
| 4 | +import numpy as np |
| 5 | +from utils import * |
| 6 | +from slow_lib import * |
| 7 | +import tqdm |
| 8 | + |
| 9 | +# Initialize CCS-AMP Graph |
| 10 | +Graph = FG.Triadic8(16) |
| 11 | + |
| 12 | +# Simulation Parameters for LDPC |
| 13 | +Ka = 20 # Number of active users |
| 14 | +w = 128 # Payload size of each active user (per user message length) |
| 15 | +N = 38400 # Total number of channel uses (real d.o.f) |
| 16 | +listSize = Ka+2 # List size retained for each section after AMP converges |
| 17 | +numAmpIter = 8 # Number of AMP iterations |
| 18 | +numBPIter = 2 # Number of BP iterations to perform |
| 19 | +BPonOuterGraph = True # Indicates whether to perform BP on outer code. If 0, AMP uses Giuseppe's uninformative prior |
| 20 | +maxSims = 2 # Number of Simulations to Run |
| 21 | + |
| 22 | +EbNodB = 2.4 # Energy per bit in decibels |
| 23 | +EbNo = 10**(EbNodB/10) # Eb/No in linear scale |
| 24 | +P = 2*w*EbNo/N # transmit power |
| 25 | +std = 1 # Noise standard deviation |
| 26 | +errorRate = 0.0 # track error rate across simulations |
| 27 | + |
| 28 | + |
| 29 | + |
| 30 | +# Simulation Para for LLC |
| 31 | +windowSize =2 |
| 32 | +messageLen = 8 |
| 33 | +L = 16 |
| 34 | +Phat = N*P/L |
| 35 | +J = 16 |
| 36 | +parityLen = J-messageLen |
| 37 | +M = 2**J |
| 38 | +Pa = parityLen*L |
| 39 | +parityInvolved = get_parity_involvement_matrix(L,windowSize,messageLen) |
| 40 | +whichGMatrix = get_G_matrices(parityInvolved) |
| 41 | + |
| 42 | + |
| 43 | + |
| 44 | +# Run CCS-AMP maxSims times |
| 45 | +for idxsim in range(maxSims): |
| 46 | + print('Starting simulation %d of %d' % (idxsim + 1, maxSims)) |
| 47 | + |
| 48 | + # # Generate random messages for Ka active users |
| 49 | + txBits = np.random.randint(low=2, size=(Ka, w)) |
| 50 | + |
| 51 | + # Reset the graph |
| 52 | + Graph.reset() |
| 53 | + # Set up Inner Encoder/Decoder |
| 54 | + InnerCode = ccsic.BlockDiagonalInnerCode(N, P, std, Ka, Graph) |
| 55 | + # Outer LDPC Encoder |
| 56 | + txMsg = Graph.encodemessages(txBits) |
| 57 | + for msg in txMsg: |
| 58 | + Graph.testvalid(msg) |
| 59 | + x = np.sum(txMsg, axis=0) |
| 60 | + # Inner CS Encoder |
| 61 | + x = InnerCode.Encode(x) |
| 62 | + # Transmit x over channel |
| 63 | + y = (x + (np.random.randn(N, 1) * std)).reshape(-1, 1) |
| 64 | + # Inner CS Decoder |
| 65 | + xHt, tau_evolution = InnerCode.Decode(y, numAmpIter, BPonOuterGraph, numBPIter, Graph) |
| 66 | + # Outer LDPC Decoder (Message Disambiguation) |
| 67 | + txMsgHt = Graph.decoder(xHt, listSize) |
| 68 | + # Calculate PUPE |
| 69 | + errorRate += (Ka - FG.numbermatches(txMsg, txMsgHt)) / (Ka * maxSims) |
| 70 | + |
| 71 | + |
| 72 | + encoded_tx_message = slow_encode(txBits,Ka,L,J,Pa,w,messageLen,parityLen,parityInvolved,whichGMatrix) |
| 73 | + beta = convert_bits_to_sparse(encoded_tx_message,L,J,Ka) |
| 74 | + Ab, Az = sparc_codebook(L, M, N) |
| 75 | + innerOutput = Ab(beta) |
| 76 | + |
| 77 | + x = np.sqrt(Phat)*innerOutput # x is of size: (N, 1) |
| 78 | + z = np.random.randn(N, 1) # z is the Gaussian additive noise |
| 79 | + y = (x + z).reshape(-1, 1) |
| 80 | + |
| 81 | + p0 = 1-(1-1/M)**Ka |
| 82 | + estimated_beta = amp_prior_art(y, P, L, M, numAmpIter, Ab, Az, p0) |
| 83 | + sigValues, sigPos = get_sig_values_and_positions(estimated_beta, L, J, listSize) |
| 84 | + print(" -Phase 1 (decoding) now starts.") |
| 85 | + # tic = time.time() |
| 86 | + chosenRoot = 0 |
| 87 | + rxBits_llc, usedRootsIndex, listSizeOrder = slow_decoder(sigValues, sigPos, L, J, parityLen, messageLen, listSize, parityInvolved, whichGMatrix, windowSize, chosenRoot) |
| 88 | + # toc = time.time() |
| 89 | + # print(" | Time of LLC decode " + str(toc-tic)) |
| 90 | + if rxBits_llc.shape[0] > Ka: |
| 91 | + rxBits_llc = rxBits_llc[np.arange(Ka)] # As before, if we have >K paths, always choose the first K's. |
| 92 | + txBits_remained_llc = check_phase_1(txBits, rxBits_llc, "Linked-loop Code") |
| 93 | + |
| 94 | + rxBits_corrected_llc= slow_corrector(sigValues, sigPos,L,J,messageLen,parityLen,listSize,parityInvolved,usedRootsIndex,whichGMatrix,windowSize,listSizeOrder,chosenRoot) |
| 95 | + if txBits_remained_llc.shape[0] == w: |
| 96 | + txBits_remained_llc = txBits_remained_llc.reshape(1,-1) |
| 97 | + |
| 98 | + corrected = 0 |
| 99 | + if rxBits_corrected_llc.size: |
| 100 | + for i in range(txBits_remained_llc.shape[0]): |
| 101 | + incre = 0 |
| 102 | + incre = np.equal(txBits_remained_llc[i,:],rxBits_corrected_llc).all(axis=1).any() |
| 103 | + corrected += int(incre) |
| 104 | + print(" | In phase 2, Linked-loop code corrected " + str(corrected) + " true (one-outage) message out of " +str(rxBits_corrected_llc.shape[0]) ) |
| 105 | + else: |
| 106 | + print(" | Nothing was corrected") |
| 107 | + |
| 108 | + |
| 109 | +# Display Simulation Results |
| 110 | +print("Per user probability of error = %3.6f" % errorRate) |
0 commit comments