Skip to content

johnzja/RydbergComms

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Communication Simulator for Rydberg Atomic Receivers

This repository contains Python simulation utilities and MATLAB research codes for Rydberg atomic receivers. The top-level workflow is split into three parts: A Flask-based web visualizer for asynchronous quantum-receiver simulation, a Python single-carrier simulator that can be reused programmatically, and paper-oriented MATLAB codes for reproduction of my paper on dynamic transfer functions of Rydberg atomic receivers.

Author: Jieao Zhu from Tsinghua University, using Copilot as my AI coding agent

Web Visualizer

The web visualizer (Fig.1) is a lightweight Flask application defined in app.py. It provides a browser-based front end for launching Rydberg atomic receiver simulations, monitoring background jobs, and visualizing the generated transmit and receive waveforms.

Rydberg simulator website

Fig.1 Website of Rydberg atomic receiver simulation

Fig.2 Waveform panels and console of the Rydberg atomic simulator

Overview

  • app.py is the entry point of the web service.
  • templates/index.html and static/js/app.js implement the browser UI.
  • The request flow is:
    1. Generate a random transmit IF waveform.
    2. Choose the simulation backend (cpp or cuda).
    3. Launch the quantum receiver simulation in a background worker.
    4. Poll the job status and render the returned waveforms and constellation data.
  • The asynchronous worker is implemented in python/web_sc_worker.py, while the simulation logic lives in python/web_single_carrier.py.
  • The reusable classes for waveform generation are implemented in python/utils/sim_SingleCarrier.py and python/utils/sim_OFDM.py.
  • The reusable classes for C++/CUDA-based quantum simulation are implemented in python/utils/transient_quantum.py.

Build

The web visualizer can use either the C++ RK4 backend or the CUDA backend. Build the optional kernels from the repository root:

make cpp
make cuda

The build scripts place the binaries under python/utils/bin/.

On Windows, the CUDA build may need a valid host compiler path via CUDAHOSTCXX. The CUDA shared library must export cudaThermalSim, which is already handled by python/utils/build_cu.sh.

Run and Deploy

Start the web service from the repository root with:

python app.py

The service listens on 0.0.0.0:5000 by default, so it can be opened locally in a browser or accessed from another machine on the same network when the firewall allows it.

If the C++ or CUDA backend is unavailable, the web API will return an error until the corresponding binary has been built.

Fig.3 Speedup of CUDA-based simulator v.s. traditional C++-based simulator

Two Access Paths for the Rydberg Simulation Service

Path A: External Computer via HTTP Requests

When the Flask service is running on the simulation server, an external computer can call the API at http://<server-ip>:5000.

Recommended request sequence:

  1. POST /api/generate_tx to generate a transmit IF waveform and obtain seed.
  2. POST /api/start_simulation with the same waveform parameters and seed.
  3. GET /api/simulation_status/<job_id> until status becomes completed.

Required JSON parameters:

API Required parameters Optional parameters Notes
/api/generate_tx zc_length, symbol_count seed If seed is omitted, the server generates one.
/api/start_simulation zc_length, symbol_count, seed, engine gpu_index engine must be cpp or cuda; gpu_index is required when engine=cuda.
/api/simulation_status/<job_id> job_id (path parameter) offset (query parameter) offset is used for incremental log pulling.

Example client script from an external computer:

import requests
import time

BASE = "http://192.168.1.100:5000"

# 1) Generate TX waveform
tx_req = {
  "zc_length": 139,
  "symbol_count": 100,
}
tx_rsp = requests.post(f"{BASE}/api/generate_tx", json=tx_req, timeout=30)
tx_rsp.raise_for_status()
tx_payload = tx_rsp.json()
seed = tx_payload["seed"]

# 2) Start simulation
sim_req = {
  "zc_length": 139,
  "symbol_count": 100,
  "seed": seed,
  "engine": "cpp",  # use "cuda" with an extra gpu_index field
}
start_rsp = requests.post(f"{BASE}/api/start_simulation", json=sim_req, timeout=30)
start_rsp.raise_for_status()
job_id = start_rsp.json()["job_id"]

# 3) Poll status
offset = 0
while True:
  stat_rsp = requests.get(f"{BASE}/api/simulation_status/{job_id}", params={"offset": offset}, timeout=30)
  stat_rsp.raise_for_status()
  stat = stat_rsp.json()
  offset = stat.get("next_offset", offset)
  if stat["status"] == "completed":
    result = stat["result"]
    print("MSE(dB):", result["mse_db"])
    break
  if stat["status"] == "failed":
    raise RuntimeError(stat.get("error", "Simulation failed"))
  time.sleep(1.0)

Path B: Local Computer via sim_SingleCarrier.py Pipeline

On the local machine, you can directly build the single-carrier link without HTTP by reusing the chain in python/study_sc.py.

The pipeline is:

  1. Generate symbols and IF waveform with SingleCarrier in python/utils/sim_SingleCarrier.py.
  2. Up-convert to IF and map to incident E-field.
  3. Resample to RK grid (dt=1e-9) and run TransientQuantumSimulator.run(...).
  4. Convert probe response to real IF waveform.
  5. Down-convert and demodulate with demodSingleCarrierWaveform(...).
  6. Compute constellation MSE.

Minimal local example (aligned with study_sc.py):

import numpy as np
from scipy.signal import resample_poly, butter, lfilter

from utils.sim_SingleCarrier import SingleCarrier
from utils.transient_quantum import TransientQuantumSimulator, SimConfig, configure_raqr

Fs_sym = 100e3
Fs_IF = 2e6
IF_freq = 60e3
NinfoSyms = 100

np.random.seed(114514)
sc = SingleCarrier(Fs_sym, Fs_IF, rollOffFactor=0.2, paddingZeros=10)
tx_syms = np.array([sc.Symbols[i] for i in np.random.randint(0, len(sc.Symbols), size=NinfoSyms)])
tx_if = sc.modSingleCarrierWaveform(tx_syms)
tx_if *= np.exp(1j * 2.0 * np.pi * (IF_freq / Fs_IF) * np.arange(len(tx_if)))

raqr = configure_raqr("Transit")
Pt_dBm, distance_m, eta0 = 10.0, 120.0, 376.73
Eamp = np.sqrt((10 ** (Pt_dBm / 10.0) * 1e-3 * 10 ** (2.15 / 10.0) * 2.0 * eta0) / (4.0 * np.pi * distance_m ** 2))

dt = 1e-9
rk_fs = 1.0 / dt
rk_wave = resample_poly(tx_if, int(round(rk_fs / Fs_IF)), 1)
t_arr = np.arange(0.0, len(rk_wave) * dt, dt)

sim_cfg = SimConfig(Temperature=300.0, Nt=len(t_arr), dt=dt, T=len(t_arr) * dt, t_arr=t_arr)
sim = TransientQuantumSimulator(verbose=False)
resp = sim.run(raqr, sim_cfg, raqr.A_LO + Eamp * rk_wave, init_method="SteadyState", Nd=1501, n_jobs=-1, use_cpp_rk=True, device="cpu", prefer_threadpool=True, speed_grade=1)

rx_probe_linear = 10 ** (resp.probeResponse / 10.0)
rx_probe_linear = rx_probe_linear[500:-500]
rx_if_real = resample_poly(rx_probe_linear, 1, int(round(rk_fs / Fs_IF)))[50:-50]
rx_if_real -= np.mean(rx_if_real)

b, a = butter(8, 1.2 * Fs_sym / Fs_IF, btype="low")
rx_if_cplx = lfilter(b, a, rx_if_real * np.exp(-1j * 2 * np.pi * (IF_freq / Fs_IF) * np.arange(len(rx_if_real))))
rx_syms = sc.demodSingleCarrierWaveform(rx_if_cplx, NrxSymbols=NinfoSyms, verbose=0)

mse_db = 10.0 * np.log10(np.mean(np.abs(tx_syms - rx_syms) ** 2))
print("MSE(dB):", mse_db)

You can also run the full reference script directly:

python -u ./python/study_sc.py  # Run the speed benchmark of single-carrier simulators 

Paper Information and Simulation Package for Reproduction

Apart from building a Rydberg simulation website, this code package is also meant for reproducing the results of the following paper [1]:

[1] J. Zhu and L. Dai, "General signal model and capacity limit for Rydberg quantum information system," IEEE Trans. Wireless Commun., vol. 25, no. 12, pp. 8292-8307, Dec. 2025.


If you use this simulation code package in any way, please cite the original paper [1] above.

The author in charge of this simulation code package is: Jieao Zhu (email: zja21@mails.tsinghua.edu.cn ; johnzja@qq.com).

Reference: We highly respect reproducible research, so we try to provide the simulation codes for our published papers. More information can be found at: http://oa.ee.tsinghua.edu.cn/dailinglong/publications/publications.html, or at the IEEE website:

https://ieeexplore.ieee.org/document/11278503.

Please note that the MATLAB R2025a is used for this simulation code package, and there may be some incompatibility problems among different MATLAB versions.

Copyright reserved by the Broadband Communications and Signal Processing Laboratory (led by Dr. Linglong Dai), Department of Electronic Engineering, Tsinghua University, Beijing 100084, China.


Abstract of the paper:

Abstract—Rydberg atomic receivers represent a transformative approach to achieving high-sensitivity, broadband, and miniaturized radio frequency (RF) reception. However, existing static signal models for Rydberg atomic receivers rely on the steady-state assumption of atomic quantum states, which cannot fully describe the signal reception process of dynamic signals. To fill in this gap, in this paper, we present a general model to compute the dynamic signal response of Rydberg atomic receivers in closed form. Specifically, by applying small-signal perturbation techniques to the quantum master equation, we derive closed-form Laplace domain transfer functions that characterize the receiver’s dynamic responses to time-varying signal fields. To gain more insights into the quantum-based RF-photocurrent conversion process, we further introduce the concept of quantum transconductance that describes the quantum system as an equivalent classical system. By applying quantum transconductance, we quantify the influence of in-band blackbody radiation (BBR) noise on the atomic receiver sensitivity. Extensive simulations for Rydberg atomic receivers validate the proposed signal model, and demonstrate the possibility of quantum receivers to outperform classical electronic receivers through the improvement of quantum transconductance.


MATLAB Code for Paper [1]

MATLAB script Description Paper figure
./matlab/sim_ptResp_transit.m Draws the probe transmission (pt) as a function of $E_{\rm LO}$ , taking into consideration the Doppler broadening and the transit broadening effects.
./matlab/sim_gqFreqResp.m Draws the quantum transconductance $g_q$ as a function of $E_{\rm LO}$ and $f_{\rm IF}$. Fig. 9
./matlab/study_DCtransfer.m Draws the probe response as a function of $E_{\rm LO}$. Fig. 2
./matlab/sim_noise.m Draws the quantum transconductance and output noise PSD as a function of $f_{\rm IF}$ ; Draws the noise factors as a function of the photodiode bias resistor $R_{s}$. Fig. 5 and Fig. 7
./matlab/wfsims/sim_singleCarrier.m Performs single-carrier transmission test for Rydberg atomic receivers. Fig. 6 and Fig. 11
./matlab/sim_QuantumTransConductance.m Draws the zero-pole plot and frequency response of the quantum transconductance $g_q(s)$ at atomic temperature $T=0,{\rm K}$. Fig. 10
./matlab/sim_RydbergMIMO.m Performs Rydberg-MIMO capacity simulation, compared with conventional RF receivers with antenna mutual coupling. Fig. 12

Enjoy the reproducible research!

About

A website-frontend CUDA-based waveform-level communication simulator for Rydberg atomic receivers

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors