Repository navigation
Add MUNIT, MDETERM and MINVERSE functions (HF-401, HF-399, HF-400) - #1817
marcin-kordas-hoc wants to merge 9 commits into
Conversation
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
hyperformula-docs | f7a20f9 | Commit Preview URL Branch Preview URL |
Oct 25 2026, 02:30 AM |
Performance comparison of head (f7a20f9) vs base (d143456) |
…it-mdeterm-minverse
…rtial pivoting The fraction-free elimination multiplied minors together, so a matrix with large or small elements overflowed or underflowed although its determinant was a number, and MINVERSE returned #NUM! for matrices that have an inverse. A singular matrix is now one whose elimination meets a pivot that is exactly 0, and the list of differences no longer claims an exact elimination. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and ruRU Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…st MUNIT among such functions Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sion at parse time A dimension above the row or column limit of a sheet is now #VALUE!, like SEQUENCE, instead of allocating the matrix (a dimension of 20000 crashed the process). A dimension written as +3 or -3 is read when the result size is predicted, so =MUNIT(+3) spills a 3x3 matrix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n MDETERM and MINVERSE
Excel returns a 3x3 matrix for MUNIT("3") and #VALUE! for a matrix that holds both text and an
error, whichever comes first. MUNIT now takes its dimension as a number, and the result size of a
numeric text literal is known at parse time.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Excel lifts MUNIT over a range and returns one result per cell; HyperFormula returns #VALUE!. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f7a20f9. Configure here.
| if (node.type === AstNodeType.STRING) { | ||
| const value = Number(node.value) | ||
| return node.value.trim() !== '' && Number.isFinite(value) ? value : undefined | ||
| } |
There was a problem hiding this comment.
String size parse disagrees with eval
Medium Severity
numberLiteral now accepts quoted dimensions via JavaScript Number(), but evaluation coerces the same argument with locale-aware NUMBER rules. Those parsers disagree, so munitArraySize can reserve a multi-cell spill for a #VALUE! result, or stay 1×1 when evaluation would build a larger identity matrix.
Reviewed by Cursor Bugbot for commit f7a20f9. Configure here.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1817 +/- ##
===========================================
+ Coverage 97.28% 97.30% +0.01%
===========================================
Files 207 207
Lines 16218 16337 +119
Branches 3556 3620 +64
===========================================
+ Hits 15777 15896 +119
Misses 433 433
Partials 8 8
🚀 New features to boost your workflow:
|


Context
Adds the matrix functions
MUNIT,MDETERMandMINVERSEtoMatrixPlugin, next toMMULT.MUNIT(dimension)returns the identity matrix of that size. Numeric text such as"3"is read as a number, and a fractional dimension is truncated. A dimension below 1, text, an empty text, an empty cell or a dimension above the sheet's row or column limit is#VALUE!, andTRUE()is 1.MDETERM(array)returns the determinant of a square matrix of numbers. A matrix that is not square, or that holds text, an empty cell or a boolean, is#VALUE!, even when it also holds an error. Otherwise an error inside the matrix propagates. A single number is its own determinant.MINVERSE(array)returns the inverse of a square matrix, with the same#VALUE!cases. A singular matrix is#NUM!.MDETERMmultiplies the pivots, andMINVERSEsolves one pair of triangular systems per column. A matrix is singular when the elimination meets a pivot that is exactly 0.#NUM!instead of its determinant (about 6E300), andMINVERSEreturned#NUM!for matrices that have an inverse.MDETERM({1,2,3;4,5,6;7,8,9})returns about 6.66E-16 in both, andMINVERSEof that matrix returns about -4.5E+15 at position (1,1) in both, instead of#NUM!.MUNIT, esES isM.UNIDADand ruRU isМЕДИН, taken from those pages. idID keeps the English names.MUNITadded to the known limitation on result sizes that must be known at parse time.How did you test your changes?
feat/hf-matrix-munit-mdeterm-minverseinhyperformula-tests. It addsunit/interpreter/function-matrix-munit-mdeterm-minverse.spec.tswith 79 tests.2004308b8. The 2MUNITsize tests (a dimension written as+2, a dimension above the sheet limits) fail onb37ce5db5. The 4 tests for numeric text inMUNITand for text next to an error fail on3d8c23fd6. All pass now.#NUM!or 0 for 11 of the 108. LU returns#NUM!for 1: its pivots overflow when multiplied, although the determinant is about 3E137. Excel also returns#NUM!for a matrix whose pivot product overflows (table below). The previous elimination also returned#NUM!fromMINVERSEfor 3 invertible matrices; LU for none.INDEX(MINVERSE(...))of{1,2,3;4,5,6;7,8,9}scaled by a power of ten. That matrix is singular, and it now gives#NUM!instead of rounding noise.jestrun on this head with the paired tests: 521 suites, 6821 passed, 3 skipped.Compatibility with Excel and Google Sheets
60 formulas were evaluated in Excel Online on one data layout (A1:B2 =
{1,2;3,4}, A3 = text); 58 match. Selected rows:=INDEX(MUNIT(3),2,2)11=ROWS(MUNIT(2.9))22=MUNIT(0)#VALUE!#VALUE!=MUNIT(TRUE())11=MDETERM(A1:B2)-2-2=MDETERM(A1:C2)#VALUE!#VALUE!=MDETERM(TRUE())#VALUE!#VALUE!=INDEX(MINVERSE(A1:B2),2,1)1.51.5=MINVERSE(0)#NUM!#NUM!=MDETERM(A1:B2*2)-8#VALUE!;-8withuseArrayArithmetic=MINVERSE(A3:B4)(a range with text)#VALUE!#VALUE!in each cell of the predicted 2x2 result,#SPILL!when that area is occupiedThe last two rows are differences.
MDETERM(A1:B2*2)needs array arithmetic, which HyperFormula enables only withuseArrayArithmetic.MINVERSEsizes its result before it evaluates the argument, so an error result still occupies a 2x2 area.14 more formulas were measured in Excel Online after the first round; 13 match:
=MDETERM({1,2,3;4,5,6;7,8,9})6.66E-166.66E-16=INDEX(MINVERSE({1,2,3;4,5,6;7,8,9}),1,1)-4.5036E+15-4.5036E+15=ROWS(MUNIT("3"))33=ROWS(MUNIT(+3))33=MDETERM(A1:C3)with{1,2,0;0,3,1;2,1,1}times 1E1006E+3006E+300=MDETERM(A1:C3)with the same matrix times 1E-906E-2706E-270=MDETERM(A1:B2)with{1E200,0;0,1E200}#NUM!#NUM!=MDETERM(A1:C3)with{1E200,0,0;0,1E200,0;0,0,1E-200}#NUM!#NUM!=INDEX(MINVERSE(A1:C3),1,1)with{1E-170,0,0;0,1,0;0,0,1E-170}1E+1701E+170=INDEX(MINVERSE(A1),1,1)with A1 = 1E-3071E+3071E+307=INDEX(MINVERSE(1e-307/1000),1,1)#NUM!#NUM!=MDETERM(A1:B2)with{1,"x";=1/0,4}#VALUE!#VALUE!=MDETERM(A1:B2)with{TRUE,2;3,4}#VALUE!#VALUE!=ROWS(MUNIT(A1:A2))with A1:A2 = 3, 22#VALUE!The last row is a difference: Excel returns one result per cell of a range of dimensions, and HyperFormula does not. It is listed in
docs/guide/list-of-differences.md.Public API changes
None.
Out of scope and follow-ups
getRegisteredFunctionNames. This already affects every ruRU function and is not changed here.MUNITwith a cell reference or a formula as the dimension (=MUNIT(A1)) is#VALUE!unless the result is 1x1, likeSEQUENCE; see the known limitations.Types of changes
Related issues
Checklist
dev-docs/pages this change affects – or none needed it.🤖 Generated with Claude Code