Skip to content

ANRGUSC/BBE

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BBE: Bayesian Bandit Encoder

BBE is a simulation framework for closed-loop selection between interleaved and non-interleaved error-control coding over a bursty interference channel.

The transmitter chooses between two realizations of the same code:

  • Arm A: a non-interleaved random linear code
  • Arm B: the same code with cross-codeword block interleaving

The receiver uses GRAND—Guessing Random Additive Noise Decoding—with a replaceable noise model. Aggregate receiver statistics are fed back to a channel learner at the transmitter. As the interference estimate improves, the receiver can replace its generic decoding model with a learned hidden Markov model. This changes the relative reliability and latency of the two arms, and a discounted Thompson sampler adapts the transmitter’s choice.

The repository accompanies the technical report:

B. Krishnamachari, “Closed-Loop Bayesian Bandit Encoder with GRAND Receiver for a Bursty Interference Channel,” technical report, in preparation, 2026.

What this repository demonstrates

The code supports experiments in which:

  1. a channel contains an unknown number of asynchronous on/off interferers;
  2. the receiver collects compact statistics from decoded packets;
  3. a transmitter-side learner estimates interference amplitudes and timing;
  4. the estimate is used to update the receiver’s GRAND query ordering;
  5. a bandit selects between interleaved and non-interleaved transmission;
  6. the preferred arm may change after receiver adaptation.

The implementation is modular: codes, channels, GRAND noise models, estimators, bandit policies, feedback statistics, and utility predictors can be replaced independently.

Quick start

BBE requires Python 3.11 or later.

git clone https://github.com/ANRGUSC/BBE.git
cd BBE
python -m venv .venv
source .venv/bin/activate
pip install -e .

Main dependencies include:

  • NumPy
  • SciPy
  • scikit-learn
  • Matplotlib
  • PyYAML

A minimal simulation can be run from Python:

from bbe.config import (
    SimConfig,
    GrandConfig,
    LearnerConfig,
    BanditConfig,
)
from bbe.sim.simulator import Simulator

cfg = SimConfig(
    seed=0,
    n_packets=20_000,
    grand=GrandConfig(
        noise_model="learned",
        max_queries=100_000,
    ),
    learner=LearnerConfig(
        kind="bayes",
        placement="tx",
    ),
    bandit=BanditConfig(
        kind="ts",  # alternatives: "informed", "fixed"
    ),
)

metrics = Simulator(cfg).run()

Simulator.run() returns a metrics recorder holding per-packet outcomes (arm, success, abandonment, query count, reward) and per-feedback-period estimator snapshots.

Closed-loop operation

At each decision point, the simulator performs the following steps:

  1. The bandit selects the non-interleaved or interleaved arm.
  2. The selected encoder produces one or more codewords.
  3. The channel adds AWGN and asynchronous burst interference.
  4. GRAND decodes using the active noise-model ordering.
  5. The receiver updates aggregate deviation and burst-run statistics.
  6. Feedback statistics are periodically sent to the learner.
  7. The learner updates the estimated channel model.
  8. The estimate may retune the receiver’s GRAND noise model.
  9. ACK/NACK outcomes update the bandit reward.
  10. In the model-informed policy, predicted arm utilities are also supplied to the sampler.
flowchart LR
    subgraph TX ["Transmitter side"]
        BANDIT["bandit/<br/>fixed | discounted TS | model-informed TS"]
        LEARNER["learner/<br/>run-mean estimator | oracle"]
        PRED["sim/utility_predictor.py<br/>Monte Carlo utility prediction"]
    end

    subgraph CODES ["codes/"]
        RLC["rlc.py<br/>random linear code<br/>packed syndrome"]
        IL["interleaver.py<br/>cross-codeword block interleaver"]
    end

    CH["channel/<br/>AWGN + asynchronous<br/>on/off interferers"]

    subgraph RX ["Receiver side"]
        DEC["grand/decoder.py<br/>GRANDAB query loop"]
        NM["grand/noise_models/<br/>iid | Markov | ORBGRAND | learned HMM"]
        STATS["feedback/stats.py<br/>deviation and burst-run statistics"]
    end

    BANDIT -->|"arm choice"| RLC
    RLC --> IL
    RLC --> CH
    IL --> CH
    CH -->|"received samples"| DEC
    NM -->|"query order"| DEC
    DEC -->|"decoded deviations"| STATS
    STATS -->|"aggregate feedback"| LEARNER
    LEARNER -->|"channel estimate"| NM
    LEARNER -->|"channel estimate"| PRED
    PRED -->|"predicted utilities"| BANDIT
    DEC -.->|"ACK/NACK reward"| BANDIT
Loading

Repository layout

src/bbe/
├── config.py
│   Experiment configuration dataclasses.
│
├── rng.py
│   Per-component random-number streams, including support for
│   common-random-number comparisons.
│
├── codes/
│   ├── rlc.py
│   │   Random linear code with bit-packed incremental syndrome checks.
│   └── interleaver.py
│       Cross-codeword block interleaver.
│
├── channel/
│   AWGN plus asynchronous on/off interferers, including channel
│   synthesis from learned parameter estimates.
│
├── grand/
│   ├── decoder.py
│   │   GRANDAB decoding loop with a configurable query budget.
│   └── noise_models/
│       Candidate-noise orderings:
│       - iid Hamming-weight order
│       - Gilbert–Elliott-style Markov order
│       - ORBGRAND
│       - learned HMM posteriors with SGRAND-style ordering
│
├── feedback/
│   Receiver-side statistics collection and compact feedback messages.
│
├── learner/
│   Run-mean interference estimator with truncation-bias inversion,
│   together with an oracle estimator for controlled experiments.
│
├── bandit/
│   Arm-selection policies:
│   - fixed policy
│   - discounted Normal-Gamma Thompson sampling
│   - model-informed Thompson sampling
│
└── sim/
    Simulator loop, arm bindings, metrics, and Monte Carlo utility
    prediction.

Reference configuration

The configuration studied in the accompanying report uses:

  • BPSK modulation
  • a fixed RLC(128, 105) on both arms
  • a depth-16 cross-codeword interleaver on Arm B
  • AWGN plus three hidden on/off interferers
  • aggregate receiver feedback every fixed number of packets
  • a learned HMM-based GRAND ordering on the non-interleaved arm
  • discounted Thompson sampling for arm selection

The learner runs at the transmitter using aggregate receiver feedback. Its estimate is used in two places:

  • to update the receiver’s GRAND noise model;
  • to predict per-arm utilities for the model-informed bandit.

BBE system diagram

Main configurable components

GRAND noise model

GrandConfig(
    noise_model="learned",
    max_queries=100_000,
)

Supported noise-model choices include:

  • generic iid ordering;
  • Markov burst ordering;
  • ORBGRAND;
  • learned HMM ordering.

The query budget controls GRANDAB abandonment and therefore trades decoding work against block error rate.

Channel learner

LearnerConfig(
    kind="bayes",
    placement="tx",
)

The run-mean learner estimates interference structure from thresholded deviation-run statistics. An oracle learner is also available for separating estimation error from decoder performance.

Bandit policy

BanditConfig(kind="ts")

Available policies include:

  • "fixed" — always use a configured arm;
  • "ts" — discounted Thompson sampling from observed rewards;
  • "informed" — Thompson sampling augmented with confidence-weighted, model-predicted utilities.

Extending BBE

The simulator is designed around interchangeable components. Typical extensions include:

  • adding a new code or interleaver under codes/;
  • implementing a new channel model under channel/;
  • adding a GRAND query ordering under grand/noise_models/;
  • replacing the run-mean estimator under learner/;
  • adding a bandit or contextual policy under bandit/;
  • defining new receiver feedback statistics under feedback/;
  • adding new experiment metrics or utility models under sim/.

When adding a component, keep randomness on its own stream through bbe.rng. This makes paired comparisons and common-random-number experiments easier to reproduce.

Reproducibility notes

Simulation behavior is controlled by SimConfig and its nested component configurations. Set seed explicitly for reproducible runs:

cfg = SimConfig(
    seed=0,
    n_packets=20_000,
    # ...
)

For fair comparisons between algorithms, use the same seed and channel realization where possible. The repository’s per-component RNG streams are intended to keep unrelated implementation changes from perturbing every random draw in an experiment.

Scope

BBE is a research simulator rather than a deployment-ready communications stack. The reference experiments use a synthetic on/off interference model and idealized control feedback. Runtime, feedback overhead, delayed acknowledgments, and integration with a complete PHY/MAC stack require separate evaluation.

Citation

@techreport{krishnamachari2026bbe,
  author      = {Bhaskar Krishnamachari},
  title       = {Closed-Loop Bayesian Bandit Encoder with GRAND Receiver
                 for a Bursty Interference Channel},
  institution = {University of Southern California},
  note        = {In preparation},
  year        = {2026}
}

License

This repository is released under the PolyForm Noncommercial License 1.0.0.

Noncommercial use, including academic research and teaching, is permitted. Commercial use is not permitted under this license. Contact the author to discuss commercial licensing.

About

Bayesian Bandit Encoder: closed-loop code selection over a learned interference channel with GRAND decoding

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages