witwin.channel.montecarlo.basic

API reference for the Monte Carlo Basic solver - Config, solve and Result for incoherent sampled power and radio maps.

Monte Carlo Basic shoots sampled rays from each transmitter and deposits their power at the receivers. It returns an incoherent power estimate whose noise falls as samples grows. It does not export individual paths.

from witwin.channel.montecarlo.basic import Config, Result, solve

Config#

Config(
    samples=4096,
    max_depth=1,
    seed=0,
    components=frozenset({"los", "reflection", "diffraction"}),
    diagnostics=False,
    ad_mode="none",
    workspace_limit_bytes=1 << 30,
)
samplesintdefault 4096

Number of sampled rays per transmitter, positive.

max_depthintdefault 1

Maximum interactions per sampled path, at least 0. With "scattering" it must be at least 1.

seedintdefault 0

Random seed, at least 0. The same seed, scene and configuration give the same result.

componentsset[str]default frozenset({'los', 'reflection', 'diffraction'})

Subset of "los", "reflection", "diffraction", "transmission", "scattering".

diagnosticsbooldefault False

True fills Result.diagnostics with counters and timing.

ad_modestrdefault 'none'

"none", "jvp" or "vjp". Gradients are of the real power map. The "scattering" component is not differentiable.

workspace_limit_bytesint | Nonedefault 1073741824

GPU workspace budget in bytes (1 GiB), or None for no limit. A solve that needs more raises instead of using fewer samples.

solve#

solve(scene, config, *, reference_frequency_hz) -> Result
scenewitwin.core.Scene | witwin.core.SceneSnapshotrequired

The world, with point receivers or a ReceiverGrid.

configmontecarlo.basic.Configrequired

This module's Config.

reference_frequency_hzfloat | torch.Tensorrequired

Carrier frequency in hertz.

Returns a Result. Raises on workspace overflow, a capacity failure or a native error; there is no truncated estimate.

from witwin.channel.montecarlo import basic
 
result = basic.solve(
    scene,
    basic.Config(samples=65_536, max_depth=1, components={"los", "reflection"}, seed=1),
    reference_frequency_hz=3.0e9,
)

Result#

FieldType and shapeMeaning
path_gainfloat32; (T, R) for point receivers, (T, rows * columns) for a ReceiverGridEstimated received power, including power_w. For a grid, path_gain.reshape(T, columns, rows) gives the map in the same layout as the deterministic solver.
component_powerdict[str, Tensor]Total power of each component. Has "los", "reflection" and "diffraction", plus "transmission" and "scattering" when requested.
component_mapsdict[str, Tensor] or NoneFor a ReceiverGrid: one (T, columns, rows) map per component; their sum equals the reshaped path_gain. None for point receivers.
metadatadictRequested and effective configuration, samples, seed, kernel and RayD records, path count.
diagnosticsdict or NoneCounters when diagnostics=True.

See Radio maps for the grid layout.

Warning

Reflections are counted where reflected rays cross the grid plane. A horizontal grid at the transmitter height, with only vertical walls, gets a zero reflection map. Offset the grid from the transmitter height. See Radio maps.