{
  "category": "Statistical functions",
  "display_name": "PROB",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.PROB",
  "implementation_state": {
    "answer_bank": null,
    "detail": "Recorded: 8 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 8 recorded answers",
    "workbook_corpus": {
      "cells": 8,
      "matched": 8
    }
  },
  "implementations": [
    {
      "commit": "9e1884369a678158dd82d3d74188daf986995e87",
      "flavour": "excel-compatibility-candidate",
      "language": "Rust",
      "name": "CalcFunc",
      "own_code": [
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/statistics.rs#L412-L418",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/statistics.rs#L504-L517",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/ported/lookup_prob_frequency_family.rs#L16-L46"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/statistics.rs#L412-L418",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 8 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.PROB.json",
  "name": "PROB",
  "notes": [],
  "schema": "efh.function-reference/v1",
  "section_order": [
    "what-it-does",
    "try-it",
    "quirks",
    "how-to-implement",
    "version-differences",
    "alternatives"
  ],
  "sections": {
    "alternatives": "\n### Relationships\n\n- **[FREQUENCY](FUNC.FREQUENCY.md)** is `PROB`'s empirical twin. `FREQUENCY` counts observations\n  falling into bins; `PROB` sums a *given* probability vector over an interval. Feed\n  `FREQUENCY`'s counts through a division by the sample size and you have a `prob_range` that\n  `PROB` will accept.\n- **[BINOM.DIST](FUNC.BINOM.DIST.md), [POISSON.DIST](FUNC.POISSON.DIST.md),\n  `HYPGEOM.DIST`** are the named discrete distributions. Their cumulative\n  forms answer the same question `PROB` answers, but from a parameterized family rather than from\n  a tabulated one. `PROB` is what you use when the distribution came from data or from a model\n  Excel does not name.\n- **`SUMIFS`** computes the same sum with the interval expressed as criteria:\n  `SUMIFS(prob, x, \">=\"&a, x, \"<=\"&b)`. What `SUMIFS` will not do is check that `prob` is a\n  probability vector — which is `PROB`'s entire added value and the source of both of its\n  `#NUM!` conditions.\n- Readers confuse `PROB` with `PERCENTILE`/`QUARTILE`, which invert an *empirical* distribution\n  built from raw observations rather than reading a supplied probability vector.\n\n\n",
    "how-to-implement": "\n### Numerical notes\n\n\n`PROB` looks arithmetically trivial and is not, for one reason: it contains an equality test\nagainst `1` in disguise.\n\nThe accumulation itself is a plain left-to-right sum of at most `n` doubles, each in `[0, 1]`.\nThere is no cancellation — every term is non-negative — so the relative error of the returned\nmass is bounded by roughly `n` units in the last place of the running total, which is the best\nbehaviour a naive sum ever has. Compensated summation (Kahan, or the doubly compensated variants\nanalysed in Higham, *Accuracy and Stability of Numerical Algorithms*, chapter 4) would tighten\nthat to a constant, and would be worth having only for very long support vectors.\n\nThe validation sum is the delicate part. `sum(p_i)` is computed the same naive way and then\ncompared against `1`. Three separate things now depend on floating-point detail:\n\n1. **Whether the input is representable at all.** Probability vectors that are exact in decimal\n   are usually not exact in binary64. Ten copies of `0.1` do not sum to `1`; neither do three\n   copies of `1/3`. A function that tested equality literally would reject most hand-written\n   distributions, which is why a tolerance exists.\n3. **The tolerance width itself.** It is a free parameter with observable consequences at the\n   boundary. Widening it admits vectors that are not distributions; narrowing it rejects vectors\n   that are. There is no principled value, only a chosen one, and Microsoft's documentation\n   supplies none.\n\nThe accumulated interval mass and the validation sum are also computed independently, so `PROB`\nover the whole support is not guaranteed to return exactly `1` even when the validation passed.\nAn implementation that wanted that identity would have to return the validation sum itself when\nthe interval covers every atom, which no source suggests Excel does.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nReturns `Number` in `[0, 1]`.\n\n- **No atom falls in the interval.** The sum over an empty index set is `0`. `PROB` returns zero,\n  not an error and not `#N/A`. A caller cannot distinguish \"the interval genuinely has zero mass\"\n  from \"the interval missed every atom\" — they are the same statement about the distribution.\n- **Errors in the vectors** propagate as themselves.\n\n\n",
    "sources": "- Microsoft, *PROB function* —\n  <https://support.microsoft.com/en-us/office/prob-function-9ac30561-c81c-4259-8253-34f0a238fc49>\n  (signature, the omitted-`upper_limit` point-probability rule, the `#N/A` unequal-count\n  condition, and the two `#NUM!` conditions on `prob_range`). Retrieval was blocked by the\n  upstream host for this page; the documented behaviour above is stated as documented behaviour\n  and should be re-checked against the page.\n- Handbook `data/functions/FUNC.PROB.json`, `data/presence/FUNC.PROB.json` (arity, classification\n  axes, implementing module and its sibling surfaces).\n- Handbook [coercion and lifting](../model/02-coercion-and-lifting.md) — the direct-argument\n  versus range-scan split that `PROB`'s strict collection sits outside of.\n- N. J. Higham, *Accuracy and Stability of Numerical Algorithms*, 2nd ed., chapter 4 (summation\n  error bounds and compensated summation) — the analysis behind the summation-order remark.\n\n",
    "version-differences": "No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.",
    "what-it-does": "\n`PROB(x_range, prob_range, lower_limit, [upper_limit])` treats its two vector arguments as a\n**finite discrete probability distribution** and returns the mass that distribution assigns to a\nclosed interval.\n\nWrite the paired vectors as `(x_1, p_1), …, (x_n, p_n)`. They define the discrete measure\n\n    mu  =  sum_{i=1..n}  p_i * delta_{x_i}\n\non the real line, where `delta_x` is the unit point mass at `x`. `PROB` returns\n\n    PROB(x, p, a, b)  =  mu([a, b])  =  sum over { i : a <= x_i <= b } of p_i\n\nTwo features of that definition carry the page:\n\n1. **The interval is closed at both ends.** The accumulation admits `x_i` when\n   `a <= x_i` and `x_i <= b`. So `PROB` computes `P(a <= X <= b)`, not `P(a < X <= b)` and not\n   `P(a <= X < b)`. On a discrete distribution the difference is a whole atom, not a\n   measure-zero technicality: it is exactly `p` at the endpoint.\n\n\nThe range of the function is `[0, 1]`, and it is monotone in the interval: widening `[a, b]`\nnever decreases the result. `PROB` is a probability *lookup*, not a distribution fit — it does\nno smoothing, no interpolation between the `x_i`, and no normalization. A value of `lower_limit`\nthat lies strictly between two atoms contributes nothing.\n\n`x_range` is not required to be sorted, and the atoms are not required to be distinct. If the\nsame `x` appears twice with different probabilities, both are admitted and both are counted;\n`PROB` sums over index positions, not over distinct support points.\n\n\n\n### Arguments\n\n\n| Argument | Meaning | Default |\n|---|---|---|\n| `x_range` | The support: the numeric values `X` can take. Required. | — |\n| `prob_range` | The probabilities attached to those values, positionally. Required. | — |\n| `lower_limit` | The lower bound of the interval, inclusive. Required. | — |\n| `upper_limit` | The upper bound, inclusive. Optional. | `lower_limit` |\n\nThe pairing is **positional**, element by element in row-major order over each argument. That is\nthe whole of the correspondence: `x_range` and `prob_range` are two columns of one table, and\nnothing checks that they were meant to line up beyond their having the same number of elements.\n\n`prob_range` is documented to be a genuine probability vector: each entry in `(0, 1]`, and the\nentries summing to 1. Both conditions are stated by Microsoft as `#NUM!` conditions rather than\nas advice, which makes `PROB` unusually strict for a worksheet function — most of Excel will\ncompute happily on nonsense.\n\n`lower_limit` and `upper_limit` are ordinary numeric slots subject to\n[coercion and lifting](../model/02-coercion-and-lifting.md).\n\n\n"
  },
  "signature": {
    "display": "PROB(x_range, prob_range, lower_limit, [upper_limit])",
    "parameters": [
      {
        "description": null,
        "name": "x_range",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "prob_range",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "lower_limit",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "upper_limit",
        "optional": true,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 4,
        "min": 3
      },
      "category": "Statistical functions",
      "classification": {
        "arg_preparation_profile": "RefsVisibleInAdapter",
        "coercion_lift_profile": "Custom",
        "determinism_class": "Deterministic",
        "error_collapse_profile": "None",
        "fec_dependency_profile": "RefOnly",
        "host_interaction_class": "None",
        "kernel_signature_class": "Custom",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "RefOnly",
        "thread_safety_class": "SafePure",
        "volatility_class": "NonVolatile"
      },
      "descriptions": {
        "long": null,
        "short": "Probability that values in a range fall between two limits, from their probabilities",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the probability that values in a range are between two limits",
        "microsoft_url": "https://support.microsoft.com/en-us/office/prob-function-9ac30561-c81c-4259-8253-34f0a238fc49"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "PROB"
        },
        {
          "locale": "bg-BG",
          "name": "PROB"
        },
        {
          "locale": "cs-CZ",
          "name": "PROB"
        },
        {
          "locale": "da-DK",
          "name": "SANDSYNLIGHED"
        },
        {
          "locale": "de-DE",
          "name": "PROB"
        },
        {
          "locale": "el-GR",
          "name": "PROB"
        },
        {
          "locale": "en-AU",
          "name": "PROB"
        },
        {
          "locale": "en-GB",
          "name": "PROB"
        },
        {
          "locale": "en-US",
          "name": "PROB"
        },
        {
          "locale": "es-ES",
          "name": "PROBABILIDAD"
        },
        {
          "locale": "et-EE",
          "name": "PROB"
        },
        {
          "locale": "fi-FI",
          "name": "TODENNÄKÖISYYS"
        },
        {
          "locale": "fr-FR",
          "name": "PROBABILITE*"
        },
        {
          "locale": "he-IL",
          "name": "PROB"
        },
        {
          "locale": "hr-HR",
          "name": "PROB"
        },
        {
          "locale": "hu-HU",
          "name": "VALÓSZÍNŰSÉG"
        },
        {
          "locale": "id-ID",
          "name": "PROB"
        },
        {
          "locale": "it-IT",
          "name": "PROB"
        },
        {
          "locale": "ja-JP",
          "name": "PROB"
        },
        {
          "locale": "ko-KR",
          "name": "PROB"
        },
        {
          "locale": "lt-LT",
          "name": "PROB"
        },
        {
          "locale": "lv-LV",
          "name": "PROB"
        },
        {
          "locale": "nb-NO",
          "name": "PROB"
        },
        {
          "locale": "nl-NL",
          "name": "KANS"
        },
        {
          "locale": "pl-PL",
          "name": "PRAWDPD"
        },
        {
          "locale": "pt-BR",
          "name": "PROB"
        },
        {
          "locale": "pt-PT",
          "name": "PROB"
        },
        {
          "locale": "ro-RO",
          "name": "PROB"
        },
        {
          "locale": "ru-RU",
          "name": "ВЕРОЯТНОСТЬ"
        },
        {
          "locale": "sk-SK",
          "name": "PROB"
        },
        {
          "locale": "sl-SI",
          "name": "PROB"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "PROB"
        },
        {
          "locale": "sv-SE",
          "name": "SANNOLIKHET"
        },
        {
          "locale": "th-TH",
          "name": "PROB"
        },
        {
          "locale": "tr-TR",
          "name": "OLASILIK işlevi"
        },
        {
          "locale": "uk-UA",
          "name": "PROB"
        },
        {
          "locale": "vi-VN",
          "name": "PROB"
        },
        {
          "locale": "zh-CN",
          "name": "PROB"
        },
        {
          "locale": "zh-HK",
          "name": "PROB"
        },
        {
          "locale": "zh-TW",
          "name": "PROB"
        }
      ],
      "signature": {
        "display": "PROB(x_range, prob_range, lower_limit, [upper_limit])",
        "parameters": [
          {
            "description": null,
            "name": "x_range",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "prob_range",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "lower_limit",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "upper_limit",
            "optional": true,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "PROB",
      "version_marker": null,
      "xlcall": {
        "code": "317",
        "symbol": "xlfProb"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/prob-function-9ac30561-c81c-4259-8253-34f0a238fc49"
  },
  "try_it": {
    "formula": "=PROB({1;2;3},{0.2;0.3;0.5},2,3)"
  },
  "url": "https://handbook.dnacalc.com/functions/PROB.html",
  "variants": [],
  "versions": []
}