Skip to content

Conversation

@jpoz
Copy link
Contributor

@jpoz jpoz commented Feb 1, 2026

PR Details

Enable element-wise comparison and multiplication for matrix operands. Use broadcasting for scalar-matrix operations to ensure consistent behavior during complex formula evaluation.

Add range-to-range matching support for COUNTIF. This enables formulas like SUMPRODUCT with conditionals and improves parity with standard spreadsheet matrix logic.

Description

This PR adds element-wise array operation support to the calculation engine, enabling conditional array formulas and range-based calculations. This allows comparison and arithmetic operators to work with matrix data.

New Capabilities:

  1. Range-to-range COUNTIF - COUNTIF(D:D, D:D) can now check if each value exists anywhere in a criteria range
  2. Conditional array formulas - SUMPRODUCT((A1:A6="Apple")*(B1:B6)) enables filtering and aggregation based on conditions
  3. Element-wise operations - All comparison operators (=, <>, <, <=, >, >=) and multiplication (*) now support array operations with scalar broadcasting

Comparison operators now return boolean arrays when operating on ranges, enabling conditional logic in formulas:

A1:A6 = "Apple"              // Returns [TRUE, FALSE, TRUE, FALSE, FALSE, TRUE]
B1:B6 > 10                   // Returns [FALSE, TRUE, TRUE, FALSE, TRUE, TRUE]
(A1:A6="Apple")*(B1:B6>10)   // Element-wise boolean multiplication

COUNTIF now accepts range references as criteria, checking if each search value matches any value in the criteria range:

COUNTIF(D1:D6, D1:D6)        // Count values that appear in both ranges
COUNTIF(Sales, Targets)      // Count sales values that hit any target

SUMPRODUCT can now use comparison expressions to filter data before aggregation:

SUMPRODUCT((Product="Apple")*(Sales))                    // Sum sales for Apple
SUMPRODUCT((Product="Apple")*(Qty>10)*(Sales))          // Sum with multiple conditions
SUMPRODUCT((Date>=StartDate)*(Date<=EndDate)*(Amount))  // Sum within date range

Related Issue

Motivation and Context

This change enables conditional array formulas and advanced range-based calculations that are essential for complex data analysis in spreadsheets.

What users couldn't do before:

  1. No conditional aggregation - Users couldn't write formulas like SUMPRODUCT((Category="Electronics")*(Sales)) to sum values based on conditions. They had to create helper columns or use complex workarounds.
  2. Limited COUNTIF functionality - COUNTIF only accepted single-value criteria, not range-to-range matching like COUNTIF(Orders, ValidOrders) to count how many values appear in both ranges.
  3. No element-wise array operations - Comparison operators couldn't operate on arrays, so expressions like A1:A6="Apple" would only check the first cell instead of returning a boolean array.

What this unlocks:

  • Complex business logic in single formulas - Revenue calculations with multiple conditions: SUMPRODUCT((Region="West")(Product="A")(Qty>5)*(Revenue))
  • Dynamic criteria matching - Count or sum based on criteria ranges that change
  • Simplified formulas - What previously required helper columns, VBA, or complex nested IFs can now be expressed naturally with boolean algebra

This brings excelize's formula calculation capabilities in line with Excel's array formula support, enabling users to perform sophisticated data analysis directly in their spreadsheet formulas.

How Has This Been Tested

Various new tests

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

jpoz added 6 commits January 30, 2026 11:02
Enable element-wise comparison and multiplication for matrix
operands. Use broadcasting for scalar-matrix operations to ensure
consistent behavior during complex formula evaluation.

Add range-to-range matching support for COUNTIF. This enables
formulas like SUMPRODUCT with conditionals and improves parity with
standard spreadsheet matrix logic.
Verify element-wise operations and broadcasting logic for comparison
and arithmetic operators in array formulas.

Test matrix-matrix, scalar-matrix, and vector broadcasting for
equality, relational operators, and multiplication. This ensures
calculation consistency across varying input dimensions.
Expand test coverage for comparison operators in array formulas.
Verify relational logic, inequality, and scalar broadcasting across
different data types in SUMPRODUCT and COUNTIF.

Ensure mixed-type comparisons and range overlaps evaluate correctly
during formula calculation.
Verify `COUNTIF` behavior when matching numeric ranges against empty or
nil criteria. This ensures the calculation engine handles type
mismatches by returning zero instead of errors or false matches.

Validating this edge case prevents regressions when evaluating formulas
on sparse datasets that contain uninitialized cells.
Verify that array comparison and arithmetic functions return
#VALUE! errors for incompatible matrix dimensions.

Ensures the formula engine correctly identifies and rejects
operands that cannot be broadcast, preventing invalid results
during matrix operations.
Remove redundant dimension validation for left-hand operands in array
operations. These checks are unnecessary because the broadcasting logic
and output dimension calculation already handle these constraints.

Add tests to verify that incompatible dimensions still correctly return
#VALUE! errors. This ensures consistent spreadsheet behavior while
reducing logic duplication in calculation functions.
@jpoz jpoz changed the title Jpoz/element wise array operation support feat(calc): support matrix logic and products Feb 1, 2026
@codecov
Copy link

codecov bot commented Feb 1, 2026

Codecov Report

❌ Patch coverage is 99.39759% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 99.56%. Comparing base (418be6d) to head (1e53fe7).
⚠️ Report is 20 commits behind head on master.

Files with missing lines Patch % Lines
calc.go 99.39% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##           master    #2258    +/-   ##
========================================
  Coverage   99.55%   99.56%            
========================================
  Files          32       32            
  Lines       25778    26448   +670     
========================================
+ Hits        25663    26332   +669     
- Misses         60       61     +1     
  Partials       55       55            
Flag Coverage Δ
unittests 99.56% <99.39%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

jpoz added 7 commits January 31, 2026 20:40
Validate calculation engine behavior for row vector broadcasting in
matrix formulas. Ensure mixed-type comparison operations follow
spreadsheet logic for number and string inequalities.
Verify broadcasting behavior for single-cell matrix operands to
ensure correct scaling of larger matrices. This covers both left
and right operand positioning.

Include validation for non-numeric input values within matrices.
These tests ensure the calculator returns appropriate errors
instead of proceeding with invalid data types.
Verify logic branches for mixed-type comparisons in array operations.
Ensure string-to-number comparisons follow expected truthiness rules
within the calculation engine.

This addition targets specific code paths in calcGeArray and
calcLeArray to ensure robust handling of mismatched types.
Add unit tests for calcEqArray to ensure correct scalar broadcasting.
These cases verify that 1x1 matrices properly expand to match larger
operands in both left and right positions.

This targets logic paths where single-row or single-column dimensions
require value replication across the resulting matrix.
Extract broadcasting and value comparison logic into
shared helper functions. This removes redundant loops
and index calculations from individual operators,
ensuring a single source of truth for array logic.

Standardize error handling in array multiplication
by pushing error arguments to the stack. This aligns
operator behavior with formula evaluation patterns
and improves consistency across the calculation engine.
Validate matrix dimensions in operandToMatrix to ensure operands
contain at least one element. Return a #VALUE! error instead of
triggering panics on zero-row or zero-column arrays.

Prevents index-out-of-bounds errors during array comparisons and
multiplication. Includes regression tests for empty matrices and
verification of valid scalar/matrix operations.
Add benchmarks for array formula operations, focusing on element-wise
comparisons and scalar broadcasting. These metrics track calculation
engine efficiency when processing matrix data.

Include performance tests for SUMPRODUCT using conditional logic.
These baselines ensure complex array-based calculations maintain
stable performance during engine optimizations.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant