Repository navigation
Add FORECAST.LINEAR, INTERCEPT, TREND, GROWTH and LOGEST functions - #1802
Tobiadefami wants to merge 12 commits into
Conversation
|
@Tobiadefami thanks for the pull request. No CLA step needed here — our records show you signed the Contributor License Agreement on 2026-07-31. That signature came from our previous signing form and has been carried over, so there is nothing for you to re-sign. |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
hyperformula-docs | 130c9dc | Commit Preview URL Branch Preview URL |
Oct 08 2026, 10:55 PM |
Add INTERCEPT and FORECAST.LINEAR, with FORECAST as an alias of FORECAST.LINEAR, next to SLOPE in StatisticalAggregationPlugin. Like SLOPE, they skip pairs with a non-numeric value, propagate errors from the ranges, and return #N/A when the ranges have a different number of cells. Fewer than two points, or x values that are all equal, return #DIV/0! (new ErrorMessage.ZeroVariance). The fit uses plain two-pass sums for the means and sums of squares, which reproduce Microsoft Excel's results to the last digits. In x, FORECAST.LINEAR coerces a blank cell, booleans and numeric text, and returns #VALUE! for an empty string, as Excel does. Both functions enable array arithmetic for their arguments, so computed ranges work in the default configuration. Includes the catalogue entries and the names in all language packs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add TREND, GROWTH and LOGEST to RegressionPlugin, built on LINEST's shape detection and fitLinearRegression. - TREND returns the values of the least-squares fit at new_x (or at known_x when new_x is omitted). Its result size is predicted by the new trendArraySize: the shape of new_x for one predictor, one value per row or column of new_x for several. - GROWTH fits ln y with the same method and evaluates b * m^x in Microsoft Excel's product form, so it overflows and underflows where Excel does. Non-positive known_y values return #NUM!. - LOGEST returns LINEST's layout for the fit to ln y, with the first row exponentiated. It shares LINEST's size method and, like LINEST, requires a constant stats argument. As in Excel, any non-number in known_y or known_x returns #VALUE! (no pairs are skipped), dimension mismatches return #REF!, and const and stats treat a blank cell as FALSE and text as #VALUE!. An error read from a cell reference in const or stats returns #VALUE!; an error written in the formula propagates. New error messages: PositiveValues, StaticResultSize(name) and StaticStats(name). Includes the catalogue entries, the names in all language packs, list-of-differences and known-limitations sections, and the changelog entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TREND, GROWTH and LOGEST returned #VALUE! for the text "TRUE" or "FALSE" as const or stats, while LINEST accepts it and LOGEST's size prediction already treated it as a constant. Read the options the way LINEST does, which matches Microsoft Excel: "TRUE" and "FALSE" in any letter case are booleans; other text, numeric text and an empty string are #VALUE!. An error read from a cell reference is still #VALUE!. Also state in LOGEST's short description that stats must be a constant, with a link to the known limitations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add FORECAST.LINEAR, GROWTH, INTERCEPT, LOGEST and TREND to the ungrouped functions of the function capability table, so they are covered by fun:all and by their single-function tokens, like SLOPE and RSQ. FORECAST is an alias and travels with FORECAST.LINEAR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2bad285 to
130c9dc
Compare
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 130c9dc. Configure here.
| 'IMSINH', 'IMSQRT', 'IMSUB', 'IMSUM', 'IMTAN', 'INTERVAL', 'ISBINARY', 'ISFORMULA', 'ISNONTEXT', 'ISPMT', | ||
| 'ISREF', 'LCM', 'LOG10', 'LOGNORM.DIST', 'LOGNORM.INV', 'MAXA', 'MAXPOOL', 'MEDIANPOOL', 'MINA', 'MIRR', | ||
| 'IMSINH', 'IMSQRT', 'IMSUB', 'IMSUM', 'IMTAN', 'INTERCEPT', 'INTERVAL', 'ISBINARY', 'ISFORMULA', 'ISNONTEXT', 'ISPMT', | ||
| 'ISREF', 'LCM', 'LOG10', 'LOGEST', 'LOGNORM.DIST', 'LOGNORM.INV', 'MAXA', 'MAXPOOL', 'MEDIANPOOL', 'MINA', 'MIRR', |
There was a problem hiding this comment.
LINEST omitted from license table
Medium Severity
LINEST is a new built-in in RegressionPlugin but is not listed in UNGROUPED_FUNCTIONS or any FUNCTION_GROUPS entry. A built-in absent from this table is not gated, so a subset license that does not include LINEST still evaluates it. FORECAST.LINEAR, INTERCEPT, TREND, GROWTH, and LOGEST were added to the same list.
Reviewed by Cursor Bugbot for commit 130c9dc. Configure here.
Performance comparison of head (130c9dc) vs base (eff7928) |


Context
This PR adds five regression functions:
FORECAST.LINEAR(also available under its legacy nameFORECAST),INTERCEPT,TREND,GROWTHandLOGEST.Important
Stacked on #1769 (
LINEST).TREND,GROWTHandLOGESTreuse LINEST's least-squares fit and its inputhelpers, so this branch is based on
feature/hf-221-linest. Until #1769 merges, this diff also shows LINEST'scommits. Review only the commits from
feat(HF-414): add INTERCEPT and FORECAST.LINEARonward:feat(HF-414): add INTERCEPT and FORECAST.LINEAR,feat(HF-414): add TREND, GROWTH and LOGEST,docs(HF-414): link the pull request in the changelog,fix(HF-414): accept the text TRUE and FALSE as const and statsand
feat(HF-414): list the regression functions in the license catalog. Once #1769 merges, this branch will berebased onto
developand only these commits will remain.Behavior, checked against Excel:
FORECAST.LINEARandINTERCEPTpairknown_y/known_xlikeSLOPE: a pair is skipped when either value isblank, text, numeric text or a boolean, and an error in a pair is returned. Ranges need the same number of cells
(
#N/Aotherwise); fewer than two pairs, orxvalues that are all equal, return#DIV/0!.TREND,GROWTHandLOGESTfollowLINEST: every known value must be a number (#VALUE!otherwise), dimensionsmust be compatible (
#REF!), and several x-variables are supported in column or row orientation.known_xomitted means 1, 2, 3, …;
new_xomitted meansknown_x.LINEST: the later column is kept and the removed one gets a coefficient of0 (
LOGESTshows its base as 1).GROWTHandLOGESTrequire positiveknown_yvalues (#NUM!otherwise).GROWTHevaluatesb·m^xas Exceldoes, so overflow and underflow give
#NUM!in the affected cells.LOGESTreturnsLINEST's layout: one row of bases and the constant, or five rows withstatsset. Thestatistics are
LINEST's statistics of the fit to ln y.constandstats: a blank cell is FALSE, an empty argument is the default, numbers and booleans are coerced, thetext
"TRUE"or"FALSE"(in any letter case) is accepted as inLINEST, and other text is#VALUE!. An error written in the formula is returned as is; a cell holding an error gives#VALUE!, as inExcel.
Note: Microsoft's FORECAST.LINEAR and INTERCEPT pages say empty data returns
#N/A. Excel returns#DIV/0!, andthis implementation follows Excel.
Implementation
INTERCEPTandFORECAST.LINEARlive inStatisticalAggregationPlugin, next toSLOPE, and reuse its pairinghelper. A new private
simpleLinearFitcomputes the line with plain two-pass sums, which reproduces Excel's lastdigits more closely than the jStat helpers
SLOPEuses.SLOPEis unchanged.FORECASTis an alias ofFORECAST.LINEAR.TREND,GROWTHandLOGESTlive inRegressionPlugin, next toLINEST, and reuseregressionShape,buildPredictorRows,regressionOutputandfitLinearRegression.LINEST's existing code is not modified.TRENDandGROWTHshare one method and a new size method,trendArraySize, which predicts the result size fromnew_x(orknown_ywhennew_xis omitted).LOGESTsharesLINEST's size method,linestArraySize, becauseboth return the same coefficient and statistics layout.
ZeroVariance,PositiveValues, and the parameterizedStaticResultSize(name)andStaticStats(name). No new error types.categories/statistical.ts, and names in all language packs, read from Excel in eachlocale.
FORECAST.LINEARis not localized in any Excel locale;FORECASTis.functionCapabilities.ts, sofun:alland their single-function tokens cover them.FORECASTtravels withFORECAST.LINEARas an alias.TREND, GROWTH and LOGESTsection inlist-of-differences.mdand inknown-limitations.md, next toLINEST's.
How did you test your changes?
data the tests use, so any case can be re-checked in Excel.
function-forecast.linear97,function-intercept70,function-trend138,
function-growth136,function-logest125. Numbers are compared with a relative tolerance, as infunction-linest.spec.ts, because the fit can differ from Excel in the last digits. Cases cover the docs examples,exact and noisy data, several variables in both orientations, collinear columns,
constandstats, coercion anderrors in every argument, error precedence, and the
FORECASTalias.pre-existing). The 7 failures are all
VERSIONtests infunction-version.spec.tsandfunction-metadata-api.spec.ts:HF-307: license-key entitlement gating — capability model, key reader, API guards #1728 changed
VERSION, and the tests branch is based on LINEST's tests branch, which does not includedevelop'supdated specs yet. With
develop's versions of those two specs, both pass.function-linest.spec.tspassesunchanged.
develop'scapability-registry.spec.tscompleteness check covers all five functions (the only name itreports is
LINEST, which is handled in feat(HF-221): add LINEST regression function #1769).npm run lint(no new warnings),npm run compile,npm run docs:generate-function-docs,git diff --check.Types of changes
Related issues:
LINEST).Checklist:
🤖 Generated with Claude Code
Note
Medium Risk
Large new numerical and array-sizing paths affect formula evaluation and spilled results; behavior is Excel-sensitive but confined to statistical functions rather than core engine security.
Overview
Adds Excel-style linear and exponential regression to the formula engine:
LINEST(simple/multiple regression with optional statistics), plusFORECAST.LINEAR/FORECAST,INTERCEPT,TREND,GROWTH, andLOGEST.INTERCEPTandFORECAST.LINEARare implemented inStatisticalAggregationPluginvia a newsimpleLinearFithelper (pairing behavior aligned withSLOPE).LINEST,TREND,GROWTH, andLOGESTlive in a newRegressionPluginbacked byfitLinearRegression(Householder QR) inLinearRegression.ts, with shared shape/prediction helpers and static array-size prediction sostats(and result width forLINEST/LOGEST) must be constants—mismatches yield#VALUE!.Also adds regression-specific error messages, statistical function metadata, localized names across language packs, changelog entries, and docs on limitations and Excel differences (constant
stats, pre-sized arrays, numerical edge cases). The unreleased changelog in this diff also records unrelated fixes (MOD, pool functions, etc.) if they ship in the same release.Reviewed by Cursor Bugbot for commit 2bad285. Bugbot is set up for automated code reviews on this repo. Configure here.