Skip to content

Array-reduce builtins (MEAN, STDDEV) produce NaN on empty views #388

@bpowers

Description

@bpowers

Problem

Array-reduce builtins (MEAN, STDDEV, etc.) return NaN or infinity when applied to an empty view (size = 0) instead of a defined fallback value.

In the VM, the ArrayMean opcode computes sum / count. When count is 0 (empty view), this produces NaN. ArrayStddev has the same division-by-zero issue.

This matters for dynamic-range subscripts where runtime bounds can produce empty views (i.e., start > end).

VM vs. interpreter inconsistency

The interpreter may return 0.0 for the same empty-view case, creating a behavioral inconsistency between the two execution backends. The same model can produce different results depending on which backend runs it.

Why it matters

  • Correctness: NaN propagates through downstream calculations, silently corrupting simulation results. A defined fallback (e.g., 0.0) is more predictable.
  • Consistency: The VM and interpreter should agree on behavior for all inputs, including edge cases.
  • Robustness: Dynamic-range subscripts are a supported feature; empty views at runtime are a valid (if unusual) state, not a bug in the model.

Components affected

  • simlin-engine -- VM bytecode execution (vm.rs, ArrayMean/ArrayStddev opcodes)
  • simlin-engine -- interpreter (if it handles the same case differently)

Possible approaches

  1. Guard the division: if count == 0, return 0.0 (or another defined sentinel) instead of performing the division. Apply to both ArrayMean and ArrayStddev.
  2. Align the interpreter to match the VM's chosen behavior (or vice versa) so both backends are consistent.
  3. Check what Vensim and Stella do for MEAN/STDDEV of an empty array and match their semantics if there is a de facto standard.

Discovery context

Identified during review of array subscript range handling on the position-and-mean branch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions