function BLER = helperAEWAutoencoderBLER(txNet,rxNet,simParams)
%helperAEWAutoencoderBLER Autoencoder block error rate (BLER) simulation
%   BLER = helperAEWAutoencoderBLER(TX,RX,P) simulates the BLER performance
%   of the autoencoder with trained encoder network, TX, and trained
%   decoder network, RX over an AWGN channel. P is the simulation
%   parameters structure and must have the following fields:
%
%   EbNoVec            - Eb/No values to simulate
%   MinNumErrors       - Minimum number of errors to simulate
%   NumSymbolsPerFrame - Number of symbols to simulated per frame
%   MaxNumFrames       - Maximum number of symbols to simulate
%   SignalPower        - Expected transmitted signal power
%
%   See also AutoencoderForWirelessCommunicationsExample, helperAEWEncode,
%   helperAEWDecode.

%   Copyright 2020 The MathWorks, Inc.

M = txNet.Layers(1).InputSize;
k = log2(M);
n = rxNet.Layers(1).InputSize;
EbNoVec = simParams.EbNoVec;

R = k/n;
numSymbolsPerFrame = simParams.NumSymbolsPerFrame;
BLER = zeros(size(EbNoVec));
parfor EbNoIdx = 1:length(EbNoVec)
  EbNo = EbNoVec(EbNoIdx) + 10*log10(R);
  chan = comm.AWGNChannel("BitsPerSymbol",2, ...
    "EbNo", EbNo, "SamplesPerSymbol", 1, ...
    "SignalPower", simParams.SignalPower);

  numBlockErrors = 0;
  frameCnt = 0;
  while (numBlockErrors < simParams.MinNumErrors) ...
      && (frameCnt < simParams.MaxNumFrames)
    d = randi([0 M-1],numSymbolsPerFrame,1);

    xComplex = helperAEWEncode(d,txNet);
    
    yComplex = chan(xComplex);
    
    dHat = helperAEWDecode(yComplex,rxNet)

    numBlockErrors = numBlockErrors + sum(d ~= dHat);
    frameCnt = frameCnt + 1;
  end
  BLER(EbNoIdx) = numBlockErrors / (frameCnt*numSymbolsPerFrame);
end