{
  "category": "Math and trigonometry functions",
  "display_name": "SUMPRODUCT",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.SUMPRODUCT",
  "implementation_state": {
    "answer_bank": null,
    "detail": "Recorded: 66 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 66 recorded answers",
    "workbook_corpus": {
      "cells": 68,
      "matched": 66,
      "pending": 2
    }
  },
  "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/aggregate.rs#L99-L99",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/aggregate.rs#L497-L512",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/aggregate.rs#L522-L560",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/aggregate.rs#L562-L626"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/aggregate::aggregate",
        "catalogue/aggregate::product",
        "catalogue/aggregate::min",
        "catalogue/aggregate::extreme",
        "catalogue/aggregate::times",
        "catalogue/aggregate::holds_held_arrays",
        "catalogue/aggregate::read_held_references",
        "catalogue/aggregate::number_of",
        "catalogue/aggregate::each_number",
        "catalogue/aggregate::each_value",
        "catalogue/aggregate::read_values",
        "catalogue/aggregate::reader",
        "catalogue/aggregate::read_reference",
        "catalogue/comparison::overflow_numbers",
        "catalogue/comparison::numbers",
        "catalogue/comparison::in_band",
        "catalogue/comparison::Rounded::up",
        "catalogue/comparison::Roundings::of",
        "catalogue/comparison::Roundings::disjoint",
        "decimal::low32",
        "decimal::Natural::from_u64",
        "decimal::Natural::pow10",
        "decimal::Natural::normalize",
        "decimal::Natural::is_zero",
        "decimal::Natural::mul_add_small",
        "decimal::Natural::times_pow10",
        "decimal::Natural::times_pow5",
        "decimal::Natural::times_pow2",
        "decimal::ExactDecimal::binary"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/aggregate.rs#L99-L99",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 66 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.SUMPRODUCT.json",
  "name": "SUMPRODUCT",
  "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\n- **`SUMX2MY2`, `SUMX2PY2`, `SUMXMY2`** — fixed-shape special cases in the same module, with the\n  different documented conventions tabulated above.\n- **`SUMSQ`** — `SUMPRODUCT(x, x)`.\n- **`SERIESSUM`** — the module's other member: a power series rather than an inner product, but\n  the same reduce-a-product-list shape.\n- **`SUMIF`, `SUMIFS`, `COUNTIFS`, `AVERAGEIFS`** — the criteria family that supersedes the\n  conditional-sum idiom for the common cases. They are clearer and generally faster; they are\n  also less general, and they use a criteria-string language rather than array expressions.\n- **`MMULT`** — matrix multiplication, which is the inner product generalized in the other\n  direction (over pairs of indices rather than over more arrays). `SUMPRODUCT(x, y)` equals\n  `MMULT(TRANSPOSE(x), y)` for column vectors, and where a whole matrix of inner products is\n  wanted, `MMULT` is the right tool.\n- **`SUM` with an array formula** — `SUM((A:A>5)*(B:B))` entered as an array formula does the\n  same job; `SUMPRODUCT` was for decades the way to get array evaluation without the\n  Ctrl+Shift+Enter ritual, which is a large part of its historical popularity.\n- **Confused with**: `SUMIFS` (criteria strings, not array expressions), and `PRODUCT` (which\n  multiplies everything together and does not sum).\n\n\n",
    "how-to-implement": "\n### Numerical notes\n\n\nThe inner product is one of the most studied kernels in numerical analysis, and its behaviour is\ncompletely characterized.\n\n**Conditioning.** The relative condition number of a dot product is\n\n    2 * SUM |x_i y_i|  /  |SUM x_i y_i|\n\n— the ratio of the sum of absolute term magnitudes to the absolute value of the answer. When the\nterms are all the same sign this is about `2` and the computation is perfectly benign. When the\nresult is small relative to its terms — near-orthogonal vectors, a residual, a balanced\nportfolio, a centred correlation — the condition number is unbounded and the computed result can\nhave **no correct digits at all**. This is not an implementation flaw; it is the problem being\nill-posed, and no algorithm in working precision can fix it.\n\nThe practical statement: `SUMPRODUCT` is exact-ish when you use it as a weighted total, and\ndangerous when you use it to detect orthogonality or to compute a residual.\n\n**Error bound.** For the naive left-to-right evaluation, the computed dot product satisfies the\nclassical bound in Higham: the error is at most about `n` times the unit roundoff times the sum\nof absolute term magnitudes. Note what the bound is proportional to — the *sum of magnitudes*,\nnot the answer. That is the same statement as the condition number above, read from the other\nside.\n\n**The three improvements, in increasing order of cost:**\n\n1. **Fused multiply-add.** Computing each `x_i*y_i + acc` in one `fma` removes the rounding of\n   the product entirely, halving the error term at no cost on hardware that has it. It also makes\n   the result depend on whether `fma` was used, which is a reproducibility hazard — a\n   portable-reproducible implementation has to choose one and pin it.\n2. **Pairwise summation**, which replaces the factor `n` in the bound by its logarithm, at\n   essentially no cost.\n3. **Compensated dot product** — Ogita, Rump and Oishi's `Dot2` and its relatives — which\n   delivers a result as accurate as if the whole computation had been done in doubled precision,\n   and which can therefore return correct digits even in the ill-conditioned cases above. This is\n   what a mathematically-correct flavour of `SUMPRODUCT` should do.\n\n**Order dependence.** Because floating-point addition is not associative, the answer depends on\nthe accumulation order. Two implementations that differ only in summation order will disagree in\nthe last bits on almost any real data set. When comparing a `SUMPRODUCT` against a hand-built\n`SUM(x*y)` array formula, expect small differences and do not read them as a defect in either.\n\n\n",
    "quirks": "\n### The conditional-sum idiom\n\n\n`SUMPRODUCT` is used far more often as a conditional aggregator than as a dot product, and the\nmechanism is worth stating because it depends on the coercion rule above.\n\nA comparison over a range produces an array of logicals: `(A1:A10>5)` is\n`{TRUE;FALSE;...}`. Multiplying two such arrays and summing counts the rows where both hold.\nBut logicals inside an array are *non-numeric entries* under the documented rule, so they must\nbe forced to numbers first. The two idiomatic forms are:\n\n    =SUMPRODUCT(--(A1:A10>5), --(B1:B10=\"x\"))\n    =SUMPRODUCT((A1:A10>5) * (B1:B10=\"x\"))\n\nThe double unary minus (`--`) is a coercion, not a sign trick: the first negation makes the\nlogical a number, the second restores the sign. The multiplication form coerces through the\narithmetic operator instead. Both work; the `*` form additionally makes the AND semantics\nvisible, and `+` gives OR (with the caveat that overlapping conditions then count twice).\n\nHistorically this idiom was the only way to write multi-criteria aggregation, and it is the\nreason `SUMPRODUCT` appears in workbooks that have no dot product anywhere in them.\n`SUMIFS`, `COUNTIFS` and `AVERAGEIFS` supersede it for the common cases and are clearer; but\n`SUMPRODUCT` remains strictly more general, because its conditions are arbitrary array\nexpressions rather than criteria strings, and because it can weight as well as filter.\n\n\n\n### Result and edge cases\n\n\nReturns `Number`.\n\n- **Dimension mismatch**: `#VALUE!`, as documented.\n- **A single array**: behaves as `SUM` over it.\n- **Non-numeric entries**: zero, per the documented remark — including text, logicals and,\n  presumably, empty cells, though the documentation does not enumerate them.\n- **Error values in the data**: not addressed by the documented remark. Under the shared\n  coercion discipline an error propagates rather than being treated as zero; the reference\n  engine declares `error_collapse_profile: ReductionFold` with\n  `error_algebra=CanonicalExcelLegacy` for this module, which is a fold rather than a mask.\n- **Full-column references**: Microsoft advises against them for performance. The advice is real\n  — the function has no way to know that most of a column is empty until it has looked.\n\n**Two family-level divergences, recorded rather than resolved.** `SUMPRODUCT` shares its\nimplementing module with `SUMX2MY2`, `SUMX2PY2`, `SUMXMY2` and `SERIESSUM`, and it disagrees\nwith the first three on two documented points at once:\n\n| | `SUMPRODUCT` | `SUMX2MY2` / `SUMX2PY2` / `SUMXMY2` |\n|---|---|---|\n| Mismatched inputs | `#VALUE!` (dimensions) | `#N/A` (number of values) |\n| Text / logicals in the data | treated as **zero** | **ignored** |\n\nBoth rows come from Microsoft's own pages. For a sum, \"zero\" and \"ignored\" happen to coincide;\nfor a product they emphatically do not, since a zeroed factor annihilates its whole term. An\nimplementation sharing a scan across the module has to keep these apart deliberately.\n\n\n\n### Errors\n\n\n| Error | Condition | Source |\n|---|---|---|\n| `#VALUE!` | The array arguments do not have the same dimensions | Documented by Microsoft |\n| `#VALUE!` | An argument does not resolve to an array or reference | Shared call model |\n| propagated | An error value among the scanned data surfaces as that error | Shared coercion rules and the module's `ReductionFold` |\n\n\n",
    "sources": "\n- Microsoft, \"SUMPRODUCT function\" —\n  <https://support.microsoft.com/en-us/office/sumproduct-function-16753e75-9f68-4874-94ac-4d2145a2fd2e>\n  (signature; \"array arguments 2 to 255\"; \"The array arguments must have the same dimensions. If\n  they do not, SUMPRODUCT returns the #VALUE! error value\"; \"SUMPRODUCT treats non-numeric array\n  entries as if they were zeros\"; the operator-substitution style; and the full-column\n  performance advice).\n- Microsoft's `SUMX2MY2`, `SUMX2PY2` and `SUMXMY2` pages — cited for the contrasting `#N/A`\n  mismatch code and ignore-rather-than-zero convention recorded as divergences.\n- Higham, *Accuracy and Stability of Numerical Algorithms* — dot-product error bounds and the\n  condition number.\n- Ogita, Rump & Oishi, \"Accurate Sum and Dot Product\", *SIAM J. Sci. Comput.*, 2005 — compensated\n  algorithms.\n- Handbook projections `data/functions/FUNC.SUMPRODUCT.json` (arity minimum 1 and maximum\n  `unbounded`, `error_collapse_profile: ReductionFold`,\n  `numerical_reduction_policy=SequentialLeftFold`, `arg_preparation_profile: RefsVisibleInAdapter`)\n  and `data/presence/FUNC.SUMPRODUCT.json` (module shared with `SERIESSUM`, `SUMX2MY2`,\n  `SUMX2PY2`, `SUMXMY2`).\n- Handbook [Coercion and lifting](../model/02-coercion-and-lifting.md).\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`SUMPRODUCT(array1, [array2], ...)` multiplies corresponding elements of its array arguments and\nsums the products:\n\n    SUM over i of (a1_i * a2_i * ... * ak_i)\n\n- **Domain**: `k` arrays of identical shape. Microsoft documents that arrays of differing\n  dimensions give `#VALUE!`.\n- **Range**: all reals.\n- **With two arrays this is the inner product** `x · y` — the fundamental bilinear form of\n  Euclidean geometry. Everything the dot product means is available here: `SUMPRODUCT(x, x)` is\n  the squared norm, `SUMPRODUCT(x, y)` divided by the product of the norms is the cosine of the\n  angle between the vectors, and `SUMPRODUCT(x, y) = 0` says the vectors are orthogonal.\n  Cauchy-Schwarz bounds the result: `|x · y| <= ||x|| ||y||`.\n- **With one array** it degenerates to `SUM`. With three or more it is a multilinear contraction\n  — a sum over the diagonal of a `k`-fold tensor product — which has no standard name in\n  spreadsheet vocabulary but is exactly what the formula says.\n- **Identities**: `SUMPRODUCT(x, x) = SUMSQ(x)`;\n  `SUMPRODUCT(x-y, x+y) = SUMX2MY2(x, y)`;\n  `SUMX2PY2(x,y) - 2*SUMPRODUCT(x,y) = SUMXMY2(x,y)`. The three fixed-shape members of this\n  module are all `SUMPRODUCT` in disguise.\n- **Weighted averages**: `SUMPRODUCT(values, weights) / SUM(weights)` is the standard idiom, and\n  is why this function appears in more finance worksheets than any other in the category.\n\nMicrosoft documents an alternative calling style in which the commas are replaced by arithmetic\noperators — `SUMPRODUCT((A1:A10)*(B1:B10))` and similar — with the arrays parenthesized to\ncontrol evaluation order.\n\n\n\n### Arguments\n\n\n| Argument | Meaning | Default |\n|---|---|---|\n| `array1` | The first array argument. Required. | — |\n| `array2, array3, ...` | Further arrays, documented as \"array arguments 2 to 255\". Optional. | — |\n\nThe commonly misunderstood aspects are two:\n\n1. **Shape, not length.** Unlike the paired-array trio, `SUMPRODUCT` compares *dimensions*. A\n   row range and a column range of the same length are not the same shape, and the documented\n   consequence is `#VALUE!` — though in modern Excel a row and a column also *broadcast* into a\n   rectangle under the dynamic-array evaluation rules, which is a different behaviour reached by\n   a different path. Which one applies to a given formula is not settled here.\n\n\n"
  },
  "signature": {
    "display": "SUMPRODUCT(array1, [array2], ...)",
    "parameters": [
      {
        "description": null,
        "name": "array1",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "array2",
        "optional": true,
        "repeats": true
      }
    ],
    "trailing_repeats": true
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 255,
        "min": 1
      },
      "category": "Math and trigonometry functions",
      "classification": {
        "arg_preparation_profile": "RefsVisibleInAdapter",
        "coercion_lift_profile": "Custom",
        "determinism_class": "Deterministic",
        "error_collapse_profile": "ReductionFold",
        "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": "Sum of the products of matching items of arrays",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the sum of the products of corresponding array components",
        "microsoft_url": "https://support.microsoft.com/en-us/office/sumproduct-function-16753e75-9f68-4874-94ac-4d2145a2fd2e"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "bg-BG",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "cs-CZ",
          "name": "SOUČIN.SKALÁRNÍ"
        },
        {
          "locale": "da-DK",
          "name": "SUMPRODUKT"
        },
        {
          "locale": "de-DE",
          "name": "SUMMENPRODUKT"
        },
        {
          "locale": "el-GR",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "en-AU",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "en-GB",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "en-US",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "es-ES",
          "name": "SUMAPRODUCTO"
        },
        {
          "locale": "et-EE",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "fi-FI",
          "name": "TULOJEN.SUMMA"
        },
        {
          "locale": "fr-FR",
          "name": "SOMMEPROD"
        },
        {
          "locale": "he-IL",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "hr-HR",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "hu-HU",
          "name": "SZORZATÖSSZEG"
        },
        {
          "locale": "id-ID",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "it-IT",
          "name": "MATR.SOMMA.PRODOTTO"
        },
        {
          "locale": "ja-JP",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "ko-KR",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "lt-LT",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "lv-LV",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "nb-NO",
          "name": "SUMMERPRODUKT"
        },
        {
          "locale": "nl-NL",
          "name": "SOMPRODUCT"
        },
        {
          "locale": "pl-PL",
          "name": "SUMA.ILOCZYNÓW"
        },
        {
          "locale": "pt-BR",
          "name": "SOMARPRODUTO"
        },
        {
          "locale": "pt-PT",
          "name": "SOMARPRODUTO"
        },
        {
          "locale": "ro-RO",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "ru-RU",
          "name": "СУММПРОИЗВ"
        },
        {
          "locale": "sk-SK",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "sl-SI",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "sv-SE",
          "name": "PRODUKTSUMMA"
        },
        {
          "locale": "th-TH",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "tr-TR",
          "name": "TOPLA.ÇARPIM"
        },
        {
          "locale": "uk-UA",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "vi-VN",
          "name": "Hàm SUMPRODUCT"
        },
        {
          "locale": "zh-CN",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "zh-HK",
          "name": "SUMPRODUCT"
        },
        {
          "locale": "zh-TW",
          "name": "SUMPRODUCT"
        }
      ],
      "signature": {
        "display": "SUMPRODUCT(array1, [array2], ...)",
        "parameters": [
          {
            "description": null,
            "name": "array1",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "array2",
            "optional": true,
            "repeats": true
          }
        ],
        "trailing_repeats": true
      },
      "surface_name": "SUMPRODUCT",
      "version_marker": null,
      "xlcall": {
        "code": "228",
        "symbol": "xlfSumproduct"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/sumproduct-function-16753e75-9f68-4874-94ac-4d2145a2fd2e"
  },
  "try_it": {
    "formula": "=SUMPRODUCT(1)"
  },
  "url": "https://handbook.dnacalc.com/functions/SUMPRODUCT.html",
  "variants": [],
  "versions": []
}