witwin.channel.montecarlo.bdpt
API reference for the bidirectional path tracing (BDPT) solver - Config, solve, Result and exported BDPTPathSamples.
The BDPT solver traces subpaths from the transmitters and from the receivers and connects them, weighting each connection with multiple importance sampling (MIS). It finds paths that are hard to hit from the transmitter side alone, at a higher cost per sample than Monte Carlo Basic.
from witwin.channel.montecarlo.bdpt import BDPTPathSamples, Config, Result, solveConfig#
Config(
samples=4096,
seed=0,
max_depth=3,
max_light_depth=None,
max_diffraction_order=1,
max_scattering_order=1,
coupled_paths=False,
coupled_candidate_limit=1_000_000,
components=frozenset({"los", "reflection", "diffraction"}),
coherent=False,
mis="power_heuristic",
power_heuristic_beta=2.0,
receiver_strategy="grid_area",
accumulation_strategy="auto",
sample_streams=1,
diagnostics=False,
export_paths=False,
max_exported_paths=None,
ad_mode="none",
workspace_limit_bytes=1 << 30,
)4096Number of samples per transmitter, positive.
0Random seed, at least 0.
3Maximum interactions of a complete connected path. Note the default is 3, not 1 as in the other solvers.
NoneMaximum depth of the transmitter-side subpath, at least 0. None uses max_depth.
10 or 1. With "diffraction" in components it must be 1.
1Maximum diffuse-scattering events per path, at least 1.
FalseTrace reflection-diffraction coupled paths. Requires max_depth >= 2 with "reflection" and "diffraction".
1000000Coupled-candidate bound, 1 to 1,000,000.
frozenset({'los', 'reflection', 'diffraction'})Non-empty subset of "los", "reflection", "diffraction", "transmission", "scattering". Scattering requires max_depth >= 1.
FalseFalse adds powers. True adds line-of-sight, reflection and diffraction contributions as complex phasors per transmitter, receiver and component. Not combinable with "transmission" or "scattering".
'power_heuristic'MIS weighting: "power_heuristic", "balance" or "none".
2.0Exponent of the power heuristic, positive.
'grid_area'Receiver sampling strategy: "grid_area" or "point_sphere".
'auto'How contributions are summed on the GPU: "auto", "atomic", "staged" or "compact". "auto" picks one.
1Number of independent random streams, positive.
FalseTrue fills Result.diagnostics and also publishes Result.variance.
FalseTrue fills Result.path_samples.
NoneLimit on exported sample rows, at least 0.
'none'"none", "jvp" or "vjp". Gradients are experimental; see Differentiability.
1073741824GPU workspace budget in bytes (1 GiB), or None. Exceeding it raises.
solve#
solve(scene, config, *, reference_frequency_hz) -> ResultThe world. It may contain point receivers or one ReceiverGrid, not both.
This module's Config.
Carrier frequency in hertz.
Returns a Result. Raises on an invalid configuration, an unsupported capability, workspace overflow or a native failure.
from witwin.channel.montecarlo import bdpt
result = bdpt.solve(
scene,
bdpt.Config(samples=65_536, max_depth=1, components={"los", "reflection"}, seed=1, diagnostics=True),
reference_frequency_hz=3.0e9,
)
print(result.path_gain.shape, result.variance.shape)Result#
| Field | Type and shape | Meaning |
|---|---|---|
path_gain | float32; (T, R) for point receivers, (T, columns, rows) for a ReceiverGrid | Estimated received power, including power_w. |
component_power | dict[str, Tensor] | Total power per component. "transmission" and "scattering" appear only when requested. |
component_maps | dict[str, Tensor] or None | Per-component (T, columns, rows) maps for a grid. |
variance | Tensor or None | Estimator variance, shaped like path_gain, when diagnostics=True. |
path_samples | BDPTPathSamples or None | Exported samples when export_paths=True. |
metadata | dict | Samples, seed, MIS, accumulation, build and execution records. |
diagnostics | dict or None | Shapes and counters when diagnostics=True. |
BDPTPathSamples#
Exactly N exported sample rows.
| Field | Shape | Meaning |
|---|---|---|
topology | (N, 4) | Encoded discrete path topology. |
contribution | (N,) | Sample contribution. |
pdf | (N,) | Sampling probability density. |
mis_weight | (N,) | MIS weight. |
component_id | (N,) | Component code. |
valid | (N,) | Row validity. |
tx_id, rx_id | (N,) | Transmitter and receiver of the sample. |
grid_linear_id | (N,) | Linear grid-sample index, or a sentinel for point receivers. |
light_depth, sensor_depth | (N,) | Depth of the transmitter-side and receiver-side subpaths. |
path_length_m | (N,) | Total path length in metres. |
The width of topology was 4 in a max_depth=1 solve; it can differ for other configurations.