Skip to content

sensitivity: n_samples=0 produces silent NaN output instead of ValueError #1371

@brendancol

Description

@brendancol

Summary

sensitivity(..., method="monte_carlo", n_samples=0) returns a raster of zeros (with a numpy RuntimeWarning) instead of raising ValueError. Negative n_samples also passes through silently.

Cat 3 sibling of the NaN-weight bug fixed in #1312. Both came out of the same mcda audit; the audit notes in sweep-security-state.csv flag this one as "sensitivity n_samples=0 divides by zero".

Reproducer

import numpy as np
import xarray as xr
from xrspatial.mcda.sensitivity import sensitivity

data = np.random.rand(5, 5).astype(np.float32)
ds = xr.Dataset({
    "a": xr.DataArray(data, dims=["y", "x"]),
    "b": xr.DataArray(data * 2, dims=["y", "x"]),
})
result = sensitivity(ds, {"a": 0.5, "b": 0.5},
                     method="monte_carlo", n_samples=0)
# Expected: ValueError naming n_samples
# Actual: RuntimeWarning, then a DataArray of zeros

Root cause

In _monte_carlo, the sample loop runs range(n_samples). With n_samples=0 the loop body never executes, so running_m2 stays at zero, and variance = running_m2 / n_samples is 0/0 -> NaN. The downstream np.where(running_mean != 0, ...) masks the NaN as 0.0, so the caller gets a clean-looking zero raster with no indication anything went wrong. Negative n_samples falls through the same way (range(-1) is empty).

Fix

Validate n_samples >= 1 in the public sensitivity() entry point, raise ValueError naming the parameter. One is the meaningful minimum; test_single_sample_zero_cv already covers n_samples=1.

One fix per PR, per the security-sweep convention.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions