Receiver thermal noise, converter stages, and automatic gain control¶
Validated with documented limitations.
1. Current component boundary¶
The public receiver path is composed from separate graph nodes:
receiver_thermal_noiseaccepts a one-dimensional complex-voltage signal and the facts emitted by the same checkedreceiver_input_boundary. Those facts carry receiver identity, receiver-input measurement plane, effective noise bandwidth (ENBW), noise figure, impedance, link identity, and sample grid.converter_scaling→converter_rounding→converter_clipping→converter_reconstructionmakes voltage scale, integer rounding, component code rails, and voltage reconstruction independently visible.automatic_gain_controlis a causal gain loop. It publishes the gain at every sample and does not limit the waveform. A separatereceiver_voltage_limiter(rail_v=...)provides an analog voltage rail.
The graph ordering contract places receiver equivalent-input noise before receiver analog processing, conversion, and receiver digital processing. See the node API for the binding contract.
2. Thermal-noise quantity and units¶
For reference temperature T, ENBW B, linear noise figure
F = 10^(noise_figure_db / 10), and receiver impedance R, the node computes
P_noise_W = max(k_B T B F, minimum_noise_power_w)
variance_V2 = P_noise_W R
variance_I_V2 = variance_V2 / 2
variance_Q_V2 = variance_V2 / 2
E[|I + jQ|^2] = variance_V2
The watts and volts-squared outputs are therefore equal only when R = 1 Ω.
The implementation draws independent real and imaginary standard-normal Torch
tensors, scales each rail by sqrt(variance_V2 / 2), and publishes both
noise_power_w and noise_variance_v2.
The following current tests are the evidence:
tests/unit/nodes/test_receiver_measurement_noise_contract.py::test_thermal_noise_facts_and_variance_follow_ktbfrusesB = 1 MHz,NF = 6 dB, andR = 50 Ω; it checksnoise_power_w = k_B T B F,noise_variance_v2 = noise_power_w × 50, and the exact facts used.tests/unit/nodes/test_thermal_noise_transform.py::test_thermal_noise_reports_ktbf_power_and_complex64checks the same watts-to-volts-squared conversion and complex64 output atB = 20 MHzandR = 50 Ω.tests/unit/nodes/test_noise_plane_port.py::test_physical_thermal_noise_closes_against_receiver_ktbfchecks that the published noise plane is exactly the realization added to the receiver-input signal and that its empirical complex variance agrees with the publishedk T B F Rvariance within the test’s finite-sample tolerance.tests/unit/nodes/test_thermal_noise_transform.py::test_thermal_noise_reports_numerical_floorchecks the explicit floor and itsnoise_floor_appliedevidence.
ENBW is not silently repaired. ReceiverMeasurementParams requires a finite,
strictly positive effective_noise_bandwidth_hz; zero and non-finite values are
schema errors. Nominal receiver bandwidth remains a separate fact. The
thermal node also refuses rank-zero or multi-receiver tensors because the
current contract supplies evidence for exactly one receiver.
3. Seeded realization and custody¶
Noise draws use the supplied torch.Generator. Current deterministic and
custody evidence includes:
tests/unit/nodes/test_awgn_transform.py::test_awgn_node_keyed_generator_is_exactly_deterministicchecks equal output for equal seeds and unequal output for a different seed.tests/unit/nodes/test_noise_plane_port.py::test_published_plane_is_the_realization_that_was_addedcheckssignal_out - signal_inagainst the published noise tensor.tests/unit/nodes/test_noise_plane_port.py::test_a_second_draw_would_be_caught_by_that_bounddemonstrates that substituting another seeded realization fails that equality oracle.tests/unit/nodes/test_receiver_input_boundary.py::test_endpoint_conditioning_measurement_boundary_and_noise_publish_to_real_sdschecks persistence of receiver, link, grid, and noise evidence.
This section makes no distribution-fit claim beyond the explicit empirical variance oracle above.
4. Converter behavior¶
The converter rounds I and Q independently to ties-to-even integer codes,
clips each component to its code rail, then reconstructs volts using the
realized scale. This is component clipping, not radial magnitude limiting.
For b = enob_bits, the positive code rail is 2^(b-1) - 1 and fixed-scale
volts per code are full_scale_v / (2^(b-1) - 1). When full_scale_v is
None, scaling is synthetic per leading row and uses the largest absolute I
or Q component in that row.
Current evidence is in tests/unit/nodes/test_converter_stages.py:
test_converter_stages_use_row_scale_ties_to_even_and_component_railschecks the complete staged chain against the shared quantization kernel.test_converter_autorange_is_per_row_and_signal_is_unchangedandtest_converter_autorange_preserves_every_leading_row_axischeck row-local autoranging without altering the scaling-stage signal.test_component_clipping_is_not_radial_limitingdistinguishes component rails from a magnitude limiter.test_converter_chain_preserves_exact_waveform_value_typechecks exact type and qualifier custody through reconstruction.The mixed-scale and mixed-source-custody negatives in that file refuse evidence assembled from different converter instances.
No SQNR sweep or IEEE-conformance tolerance is claimed here. The retained PNGs
under noise_quantize_agc/figures/ were generated for a retired receiver-stage
implementation and are historical artifacts, not evidence for the current
split converter nodes.
5. Automatic-gain-control behavior¶
For each leading row and each sample, the implementation uses Torch tensors in a Python loop over the final time axis:
compute post-gain magnitude
g |x|;select
tau_attackabove the positive voltage target andtau_decayotherwise;update gain by the causal single-pole step;
clamp gain to
[0, max_gain]; andmultiply the current complex sample by the updated gain.
There is no NumPy processing in the implementation and no torchaudio filter. No runtime-per-sample number is asserted because no current benchmark is part of this validation.
Current evidence is:
tests/unit/nodes/test_agc_transform.py::test_agc_converges_to_target_and_exposes_gain_trajectorychecks convergence of a constant-envelope input and the published gain.tests/unit/nodes/test_agc_transform.py::test_agc_composed_with_a_limiter_clamps_and_keeps_receivers_independentchecks independent receiver rows and proves that limiting belongs to the separate receiver limiter.tests/unit/nodes/test_receiver_measurement_noise_contract.py::test_agc_target_is_voltage_and_non_voltage_signals_are_refusedchecks that the target is volts and dimensionless IQ is rejected.tests/unit/nodes/test_signal_chain_ordering.py::test_agc_before_equivalent_input_noise_is_refusedchecks the receiver-stage ordering constraint.
On a strictly zero sample, the denominator guard substitutes one only for the
update calculation; the sample remains zero and gain can rise only as far as
max_gain. tests/unit/nodes/test_link_budget_defaults.py::test_the_shipped_agc_default_still_bounds_a_signal_free_interval
and test_agc_rejects_an_initial_gain_above_its_rail cover that bounded state.
6. Limits¶
The thermal node represents one equivalent receiver noise figure. It does not model a Friis cascade; authors must supply an already-reduced equivalent figure in receiver measurement evidence.
Thermal noise currently supports one receiver
[time]tensor. Per-receiver evidence for a higher-rank tensor is intentionally not inferred.Converter autoranging is synthetic normalization, not evidence of a calibrated hardware full scale. Use explicit
full_scale_vfor a declared voltage rail.The AGC is correctness-tested but not performance-benchmarked here.
The historical figures are not used to support current numerical claims and should not be regenerated as if they exercised the split public nodes.
7. References¶
J. B. Johnson, “Thermal Agitation of Electricity in Conductors,” Physical Review 32 (1928), 97–109, DOI: 10.1103/PhysRev.32.97.
H. Nyquist, “Thermal Agitation of Electric Charge in Conductors,” Physical Review 32 (1928), 110–113, DOI: 10.1103/PhysRev.32.110.
CODATA 2018 fundamental constants:
k_B = 1.380649 × 10⁻²³ J/Kexactly.D. M. Pozar, Microwave Engineering, 4th ed., §10.3, for equivalent receiver noise figure and Friis cascades.