From 7d51279e0766829a6a7710b2d5a3d9811bebcae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E7=86=B1?= Date: Thu, 31 Oct 2024 12:10:15 +0800 Subject: [PATCH 1/4] chore: fix d.ts files (#3905) --- common/shared/vite/build-pkg.js | 16 ++++++++-------- common/shared/vite/index.js | 1 + packages/docs-ui/package.json | 8 ++++++++ packages/engine-formula/package.json | 12 ++++++++++-- packages/sheets-crosshair-highlight/package.json | 8 ++++++++ packages/sheets-data-validation/package.json | 12 ++++++++++-- packages/sheets-drawing-ui/package.json | 8 ++++++++ packages/sheets-filter/package.json | 12 ++++++++++-- packages/sheets-formula/package.json | 12 ++++++++++-- packages/sheets-hyper-link-ui/package.json | 8 ++++++++ packages/sheets-hyper-link/package.json | 12 ++++++++++-- packages/sheets-numfmt/package.json | 12 ++++++++++-- packages/sheets-thread-comment/package.json | 12 ++++++++++-- packages/sheets-ui/package.json | 8 ++++++++ packages/sheets/package.json | 8 ++++++++ packages/ui/package.json | 8 ++++++++ packages/watermark/package.json | 8 ++++++++ 17 files changed, 143 insertions(+), 22 deletions(-) diff --git a/common/shared/vite/build-pkg.js b/common/shared/vite/build-pkg.js index 5ed66af4f199..f62cc93cf69c 100644 --- a/common/shared/vite/build-pkg.js +++ b/common/shared/vite/build-pkg.js @@ -71,14 +71,6 @@ exports.buildPkg = function buildPkg() { './*': './src/*', }, pkg.exports); - const facadeEntry = path.resolve(process.cwd(), 'src/facade/index.ts'); - if (fs.existsSync(facadeEntry)) { - pkg.publishConfig.exports['./facade'] = { - import: './lib/es/facade.js', - types: './lib/types/facade/index.d.ts', - }; - } - // main pkg.main = './src/index.ts'; @@ -100,6 +92,14 @@ exports.buildPkg = function buildPkg() { }, }; + const facadeEntry = path.resolve(process.cwd(), 'src/facade/index.ts'); + if (fs.existsSync(facadeEntry)) { + pkg.publishConfig.exports['./facade'] = { + import: './lib/es/facade.js', + types: './lib/types/facade/index.d.ts', + }; + } + // locale const localeDir = path.resolve(process.cwd(), 'src/locale'); if (fs.existsSync(localeDir)) { diff --git a/common/shared/vite/index.js b/common/shared/vite/index.js index f1aa76baa3c4..e77f1570d9a5 100644 --- a/common/shared/vite/index.js +++ b/common/shared/vite/index.js @@ -81,6 +81,7 @@ function createViteConfig(overrideConfig, /** @type {IOptions} */ options) { dts({ entryRoot: 'src', outDir: 'lib/types', + clearPureImport: false, }), buildPkg(), ], diff --git a/packages/docs-ui/package.json b/packages/docs-ui/package.json index 58434262ae0c..38c9bb8f965f 100644 --- a/packages/docs-ui/package.json +++ b/packages/docs-ui/package.json @@ -42,6 +42,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" @@ -95,6 +99,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" diff --git a/packages/engine-formula/package.json b/packages/engine-formula/package.json index 635b14867fef..4b8386499cf8 100644 --- a/packages/engine-formula/package.json +++ b/packages/engine-formula/package.json @@ -40,7 +40,11 @@ "import": "./lib/es/*", "types": "./lib/types/index.d.ts" }, - "./lib/*": "./lib/*" + "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + } } }, "directories": { @@ -82,6 +86,10 @@ "import": "./lib/es/*", "types": "./lib/types/index.d.ts" }, - "./lib/*": "./lib/*" + "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + } } } diff --git a/packages/sheets-crosshair-highlight/package.json b/packages/sheets-crosshair-highlight/package.json index 2a5d1f1b057d..bd305ec18766 100644 --- a/packages/sheets-crosshair-highlight/package.json +++ b/packages/sheets-crosshair-highlight/package.json @@ -40,6 +40,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" @@ -91,6 +95,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" diff --git a/packages/sheets-data-validation/package.json b/packages/sheets-data-validation/package.json index c8f9ba7ff676..da6273b6dc1f 100644 --- a/packages/sheets-data-validation/package.json +++ b/packages/sheets-data-validation/package.json @@ -40,7 +40,11 @@ "import": "./lib/es/*", "types": "./lib/types/index.d.ts" }, - "./lib/*": "./lib/*" + "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + } } }, "directories": { @@ -88,6 +92,10 @@ "import": "./lib/es/*", "types": "./lib/types/index.d.ts" }, - "./lib/*": "./lib/*" + "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + } } } diff --git a/packages/sheets-drawing-ui/package.json b/packages/sheets-drawing-ui/package.json index 89c8f3719fbd..a4ad38f102d5 100644 --- a/packages/sheets-drawing-ui/package.json +++ b/packages/sheets-drawing-ui/package.json @@ -40,6 +40,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" @@ -95,6 +99,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" diff --git a/packages/sheets-filter/package.json b/packages/sheets-filter/package.json index 022adc2964ad..39be3e89a9cc 100644 --- a/packages/sheets-filter/package.json +++ b/packages/sheets-filter/package.json @@ -38,7 +38,11 @@ "import": "./lib/es/*", "types": "./lib/types/index.d.ts" }, - "./lib/*": "./lib/*" + "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + } } }, "directories": { @@ -78,6 +82,10 @@ "import": "./lib/es/*", "types": "./lib/types/index.d.ts" }, - "./lib/*": "./lib/*" + "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + } } } diff --git a/packages/sheets-formula/package.json b/packages/sheets-formula/package.json index 97a268a8c266..f45404c16f6e 100644 --- a/packages/sheets-formula/package.json +++ b/packages/sheets-formula/package.json @@ -39,7 +39,11 @@ "import": "./lib/es/*", "types": "./lib/types/index.d.ts" }, - "./lib/*": "./lib/*" + "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + } } }, "directories": { @@ -84,6 +88,10 @@ "import": "./lib/es/*", "types": "./lib/types/index.d.ts" }, - "./lib/*": "./lib/*" + "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + } } } diff --git a/packages/sheets-hyper-link-ui/package.json b/packages/sheets-hyper-link-ui/package.json index cef27a83e349..66aa5f207523 100644 --- a/packages/sheets-hyper-link-ui/package.json +++ b/packages/sheets-hyper-link-ui/package.json @@ -42,6 +42,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" @@ -97,6 +101,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" diff --git a/packages/sheets-hyper-link/package.json b/packages/sheets-hyper-link/package.json index 9e3c113088c3..d629af922555 100644 --- a/packages/sheets-hyper-link/package.json +++ b/packages/sheets-hyper-link/package.json @@ -38,7 +38,11 @@ "import": "./lib/es/*", "types": "./lib/types/index.d.ts" }, - "./lib/*": "./lib/*" + "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + } } }, "directories": { @@ -81,6 +85,10 @@ "import": "./lib/es/*", "types": "./lib/types/index.d.ts" }, - "./lib/*": "./lib/*" + "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + } } } diff --git a/packages/sheets-numfmt/package.json b/packages/sheets-numfmt/package.json index 85af7660f414..cbb7f6d48904 100644 --- a/packages/sheets-numfmt/package.json +++ b/packages/sheets-numfmt/package.json @@ -41,7 +41,11 @@ "import": "./lib/es/*", "types": "./lib/types/index.d.ts" }, - "./lib/*": "./lib/*" + "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + } } }, "directories": { @@ -83,6 +87,10 @@ "import": "./lib/es/*", "types": "./lib/types/index.d.ts" }, - "./lib/*": "./lib/*" + "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + } } } diff --git a/packages/sheets-thread-comment/package.json b/packages/sheets-thread-comment/package.json index 6a7b6f95892e..fb2e5e0cb4ed 100644 --- a/packages/sheets-thread-comment/package.json +++ b/packages/sheets-thread-comment/package.json @@ -38,7 +38,11 @@ "import": "./lib/es/*", "types": "./lib/types/index.d.ts" }, - "./lib/*": "./lib/*" + "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + } } }, "directories": { @@ -81,6 +85,10 @@ "import": "./lib/es/*", "types": "./lib/types/index.d.ts" }, - "./lib/*": "./lib/*" + "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + } } } diff --git a/packages/sheets-ui/package.json b/packages/sheets-ui/package.json index fc88bbcdcb24..b372bcfbcf80 100644 --- a/packages/sheets-ui/package.json +++ b/packages/sheets-ui/package.json @@ -41,6 +41,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" @@ -99,6 +103,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" diff --git a/packages/sheets/package.json b/packages/sheets/package.json index 14ba48e22b87..81d5bf6dc02e 100644 --- a/packages/sheets/package.json +++ b/packages/sheets/package.json @@ -42,6 +42,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" @@ -89,6 +93,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" diff --git a/packages/ui/package.json b/packages/ui/package.json index fe9ffcbc79ea..9e23d5d15728 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -42,6 +42,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" @@ -106,6 +110,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" diff --git a/packages/watermark/package.json b/packages/watermark/package.json index f6234be4aba8..281213a2f63e 100644 --- a/packages/watermark/package.json +++ b/packages/watermark/package.json @@ -42,6 +42,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" @@ -93,6 +97,10 @@ "types": "./lib/types/index.d.ts" }, "./lib/*": "./lib/*", + "./facade": { + "import": "./lib/es/facade.js", + "types": "./lib/types/facade/index.d.ts" + }, "./locale/*": { "import": "./lib/locale/*.js", "types": "./lib/types/locale/*.d.ts" From da6392d03f25877fbc96bab7304ad9bea28886ee Mon Sep 17 00:00:00 2001 From: Wenzhao Hu Date: Thu, 31 Oct 2024 14:28:01 +0800 Subject: [PATCH 2/4] chore: add sheets numfmt ui plugin in demo (#3892) --- examples/src/sheets/main.ts | 2 ++ .../src/commands/operations/close.numfmt.panel.operation.ts | 2 +- .../src/commands/operations/open.numfmt.panel.operation.ts | 5 ++--- packages/sheets-numfmt-ui/src/controllers/menu.schema.ts | 3 ++- packages/sheets-numfmt-ui/src/controllers/menu.ts | 3 ++- .../sheets-numfmt-ui/src/controllers/numfmt.controller.ts | 4 +++- .../src/views/components/more-numfmt-type/MoreNumfmtType.tsx | 5 +++-- packages/sheets-numfmt/src/index.ts | 2 -- packages/sheets-numfmt/src/numfmt-plugin.ts | 2 -- 9 files changed, 15 insertions(+), 13 deletions(-) rename packages/{sheets-numfmt => sheets-numfmt-ui}/src/commands/operations/close.numfmt.panel.operation.ts (94%) rename packages/{sheets-numfmt => sheets-numfmt-ui}/src/commands/operations/open.numfmt.panel.operation.ts (86%) diff --git a/examples/src/sheets/main.ts b/examples/src/sheets/main.ts index e09700771981..a7fba766bbd6 100644 --- a/examples/src/sheets/main.ts +++ b/examples/src/sheets/main.ts @@ -33,6 +33,7 @@ import { UniverSheetsFormulaPlugin } from '@univerjs/sheets-formula'; import { UniverSheetsFormulaUIPlugin } from '@univerjs/sheets-formula-ui'; import { UniverSheetsHyperLinkPlugin } from '@univerjs/sheets-hyper-link'; import { UniverSheetsNumfmtPlugin } from '@univerjs/sheets-numfmt'; +import { UniverSheetsNumfmtUIPlugin } from '@univerjs/sheets-numfmt-ui'; import { UniverSheetsSortPlugin } from '@univerjs/sheets-sort'; import { UniverSheetsThreadCommentPlugin } from '@univerjs/sheets-thread-comment'; import { UniverSheetsThreadCommentUIPlugin } from '@univerjs/sheets-thread-comment-ui'; @@ -119,6 +120,7 @@ univer.registerPlugin(UniverSheetsUIPlugin); univer.registerPlugin(UniverSheetsNumfmtPlugin); univer.registerPlugin(UniverSheetsZenEditorPlugin); univer.registerPlugin(UniverFormulaEnginePlugin, { notExecuteFormula: true }); +univer.registerPlugin(UniverSheetsNumfmtUIPlugin); univer.registerPlugin(UniverSheetsFormulaPlugin, { notExecuteFormula: true }); univer.registerPlugin(UniverSheetsFormulaUIPlugin); univer.registerPlugin(UniverSheetsDataValidationPlugin); diff --git a/packages/sheets-numfmt/src/commands/operations/close.numfmt.panel.operation.ts b/packages/sheets-numfmt-ui/src/commands/operations/close.numfmt.panel.operation.ts similarity index 94% rename from packages/sheets-numfmt/src/commands/operations/close.numfmt.panel.operation.ts rename to packages/sheets-numfmt-ui/src/commands/operations/close.numfmt.panel.operation.ts index bfd81fa01729..fea8053c930c 100644 --- a/packages/sheets-numfmt/src/commands/operations/close.numfmt.panel.operation.ts +++ b/packages/sheets-numfmt-ui/src/commands/operations/close.numfmt.panel.operation.ts @@ -21,6 +21,6 @@ export const CloseNumfmtPanelOperator: ICommand = { id: 'sheet.operation.close.numfmt.panel', type: CommandType.OPERATION, handler: () => - // do nothing,just notify panel is closed + // do nothing, just notify panel is closed true, }; diff --git a/packages/sheets-numfmt/src/commands/operations/open.numfmt.panel.operation.ts b/packages/sheets-numfmt-ui/src/commands/operations/open.numfmt.panel.operation.ts similarity index 86% rename from packages/sheets-numfmt/src/commands/operations/open.numfmt.panel.operation.ts rename to packages/sheets-numfmt-ui/src/commands/operations/open.numfmt.panel.operation.ts index c301e6d9a228..2abdd43c3472 100644 --- a/packages/sheets-numfmt/src/commands/operations/open.numfmt.panel.operation.ts +++ b/packages/sheets-numfmt-ui/src/commands/operations/open.numfmt.panel.operation.ts @@ -16,14 +16,13 @@ import type { IAccessor, ICommand } from '@univerjs/core'; import { CommandType } from '@univerjs/core'; - -import { INumfmtController } from '../../controllers/type'; +import { SheetNumfmtUIController } from '../../controllers/numfmt.controller'; export const OpenNumfmtPanelOperator: ICommand = { id: 'sheet.operation.open.numfmt.panel', type: CommandType.OPERATION, handler: (accessor: IAccessor) => { - const numfmtController = accessor.get(INumfmtController); + const numfmtController = accessor.get(SheetNumfmtUIController); numfmtController.openPanel(); return true; }, diff --git a/packages/sheets-numfmt-ui/src/controllers/menu.schema.ts b/packages/sheets-numfmt-ui/src/controllers/menu.schema.ts index 302c0bb31d97..369f8d1940cd 100644 --- a/packages/sheets-numfmt-ui/src/controllers/menu.schema.ts +++ b/packages/sheets-numfmt-ui/src/controllers/menu.schema.ts @@ -15,8 +15,9 @@ */ import type { MenuSchemaType } from '@univerjs/ui'; -import { AddDecimalCommand, OpenNumfmtPanelOperator, SetCurrencyCommand, SetPercentCommand, SubtractDecimalCommand } from '@univerjs/sheets-numfmt'; +import { AddDecimalCommand, SetCurrencyCommand, SetPercentCommand, SubtractDecimalCommand } from '@univerjs/sheets-numfmt'; import { RibbonStartGroup } from '@univerjs/ui'; +import { OpenNumfmtPanelOperator } from '../commands/operations/open.numfmt.panel.operation'; import { AddDecimalMenuItem, CurrencyMenuItem, FactoryOtherMenuItem, PercentMenuItem, SubtractDecimalMenuItem } from './menu'; export const menuSchema: MenuSchemaType = { diff --git a/packages/sheets-numfmt-ui/src/controllers/menu.ts b/packages/sheets-numfmt-ui/src/controllers/menu.ts index 5df38a5f3f45..c1101cd900aa 100644 --- a/packages/sheets-numfmt-ui/src/controllers/menu.ts +++ b/packages/sheets-numfmt-ui/src/controllers/menu.ts @@ -27,10 +27,11 @@ import { WorksheetEditPermission, WorksheetSetCellStylePermission, } from '@univerjs/sheets'; -import { AddDecimalCommand, countryCurrencyMap, isPatternEqualWithoutDecimal, MenuCurrencyService, OpenNumfmtPanelOperator, SetCurrencyCommand, SetPercentCommand, SubtractDecimalCommand } from '@univerjs/sheets-numfmt'; +import { AddDecimalCommand, countryCurrencyMap, isPatternEqualWithoutDecimal, MenuCurrencyService, SetCurrencyCommand, SetPercentCommand, SubtractDecimalCommand } from '@univerjs/sheets-numfmt'; import { deriveStateFromActiveSheet$, getCurrentRangeDisable$ } from '@univerjs/sheets-ui'; import { getMenuHiddenObservable, MenuItemType } from '@univerjs/ui'; import { merge, Observable } from 'rxjs'; +import { OpenNumfmtPanelOperator } from '../commands/operations/open.numfmt.panel.operation'; import { MORE_NUMFMT_TYPE_KEY, OPTIONS_KEY } from '../views/components/more-numfmt-type/MoreNumfmtType'; export const MENU_OPTIONS: Array<{ label: string; pattern: string | null } | '|'> = [ diff --git a/packages/sheets-numfmt-ui/src/controllers/numfmt.controller.ts b/packages/sheets-numfmt-ui/src/controllers/numfmt.controller.ts index ac806c6e20ca..f9b73f7c2806 100644 --- a/packages/sheets-numfmt-ui/src/controllers/numfmt.controller.ts +++ b/packages/sheets-numfmt-ui/src/controllers/numfmt.controller.ts @@ -42,11 +42,13 @@ import { SheetInterceptorService, SheetsSelectionsService, } from '@univerjs/sheets'; -import { CloseNumfmtPanelOperator, getPatternPreviewIgnoreGeneral, getPatternType, OpenNumfmtPanelOperator, SetNumfmtCommand } from '@univerjs/sheets-numfmt'; +import { getPatternPreviewIgnoreGeneral, getPatternType, SetNumfmtCommand } from '@univerjs/sheets-numfmt'; import { SheetSkeletonManagerService } from '@univerjs/sheets-ui'; import { ComponentManager, ISidebarService } from '@univerjs/ui'; import { combineLatest, Observable } from 'rxjs'; import { debounceTime, map, switchMap, tap } from 'rxjs/operators'; +import { CloseNumfmtPanelOperator } from '../commands/operations/close.numfmt.panel.operation'; +import { OpenNumfmtPanelOperator } from '../commands/operations/open.numfmt.panel.operation'; import { SheetNumfmtPanel } from '../views/components'; const SHEET_NUMFMT_PANEL = 'SHEET_NUMFMT_PANEL'; diff --git a/packages/sheets-numfmt-ui/src/views/components/more-numfmt-type/MoreNumfmtType.tsx b/packages/sheets-numfmt-ui/src/views/components/more-numfmt-type/MoreNumfmtType.tsx index d25b56ba8cb4..66db187677b8 100644 --- a/packages/sheets-numfmt-ui/src/views/components/more-numfmt-type/MoreNumfmtType.tsx +++ b/packages/sheets-numfmt-ui/src/views/components/more-numfmt-type/MoreNumfmtType.tsx @@ -18,11 +18,12 @@ import type { FormatType } from '@univerjs/sheets'; import { ICommandService, LocaleService, Range, useDependency, useInjector } from '@univerjs/core'; import { SheetsSelectionsService } from '@univerjs/sheets'; -import { getPatternPreview, getPatternType, OpenNumfmtPanelOperator, SetNumfmtCommand } from '@univerjs/sheets-numfmt'; +import { getPatternPreview, getPatternType, SetNumfmtCommand } from '@univerjs/sheets-numfmt'; import { ILayoutService } from '@univerjs/ui'; import React from 'react'; -import { MENU_OPTIONS } from '../../../controllers/menu'; +import { OpenNumfmtPanelOperator } from '../../../commands/operations/open.numfmt.panel.operation'; +import { MENU_OPTIONS } from '../../../controllers/menu'; // FIXME: DO NOT USE GLOBAL STYLES import './index.less'; diff --git a/packages/sheets-numfmt/src/index.ts b/packages/sheets-numfmt/src/index.ts index 709e2aaa170a..6ed83f12b765 100644 --- a/packages/sheets-numfmt/src/index.ts +++ b/packages/sheets-numfmt/src/index.ts @@ -32,7 +32,5 @@ export { SetCurrencyCommand } from './commands/commands/set-currency.command'; export { type ISetNumfmtCommandParams, SetNumfmtCommand } from './commands/commands/set-numfmt.command'; export { SetPercentCommand } from './commands/commands/set-percent.command'; export { SubtractDecimalCommand } from './commands/commands/subtract-decimal.command'; -export { CloseNumfmtPanelOperator } from './commands/operations/close.numfmt.panel.operation'; -export { OpenNumfmtPanelOperator } from './commands/operations/open.numfmt.panel.operation'; // #endregion diff --git a/packages/sheets-numfmt/src/numfmt-plugin.ts b/packages/sheets-numfmt/src/numfmt-plugin.ts index 88b4e4c97b9e..4206773ce206 100644 --- a/packages/sheets-numfmt/src/numfmt-plugin.ts +++ b/packages/sheets-numfmt/src/numfmt-plugin.ts @@ -24,7 +24,6 @@ import { SetPercentCommand } from './commands/commands/set-percent.command'; import { SubtractDecimalCommand } from './commands/commands/subtract-decimal.command'; import { SheetsNumfmtCellContentController } from './controllers/numfmt-cell-content.controller'; import { NumfmtCurrencyController } from './controllers/numfmt-currency.controller'; -import { INumfmtController } from './controllers/type'; import { MenuCurrencyService } from './service/menu.currency.service'; @DependentOn(UniverSheetsPlugin) @@ -50,7 +49,6 @@ export class UniverSheetsNumfmtPlugin extends Plugin { override onRendered(): void { touchDependencies(this._injector, [ - [INumfmtController], [SheetsNumfmtCellContentController], [NumfmtCurrencyController], ]); From 56eeb044f945f5de380dbc51d6d49a17b9af3f35 Mon Sep 17 00:00:00 2001 From: Ran Luo Date: Thu, 31 Oct 2024 15:50:42 +0800 Subject: [PATCH 3/4] fix: hide align menus in zen mode (#3904) --- packages/docs-ui/src/controllers/menu/menu.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/docs-ui/src/controllers/menu/menu.ts b/packages/docs-ui/src/controllers/menu/menu.ts index b3c26a586297..a75946be78b7 100644 --- a/packages/docs-ui/src/controllers/menu/menu.ts +++ b/packages/docs-ui/src/controllers/menu/menu.ts @@ -636,7 +636,7 @@ export function AlignLeftMenuItemFactory(accessor: IAccessor): IMenuButtonItem { return disposable.dispose; }), - hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC), + hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC, undefined, DOCS_ZEN_EDITOR_UNIT_ID_KEY), }; } @@ -670,7 +670,7 @@ export function AlignCenterMenuItemFactory(accessor: IAccessor): IMenuButtonItem return disposable.dispose; }), disabled$: disableMenuWhenNoDocRange(accessor), - hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC), + hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC, undefined, DOCS_ZEN_EDITOR_UNIT_ID_KEY), }; } @@ -704,7 +704,7 @@ export function AlignRightMenuItemFactory(accessor: IAccessor): IMenuButtonItem return disposable.dispose; }), disabled$: disableMenuWhenNoDocRange(accessor), - hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC), + hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC, undefined, DOCS_ZEN_EDITOR_UNIT_ID_KEY), }; } @@ -738,7 +738,7 @@ export function AlignJustifyMenuItemFactory(accessor: IAccessor): IMenuButtonIte return disposable.dispose; }), disabled$: disableMenuWhenNoDocRange(accessor), - hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC), + hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_DOC, undefined, DOCS_ZEN_EDITOR_UNIT_ID_KEY), }; } From 51f16168141d6c2fc0c585144238cf7e9577eee1 Mon Sep 17 00:00:00 2001 From: wpxp123456 <2677556700@qq.com> Date: Thu, 31 Oct 2024 17:36:19 +0800 Subject: [PATCH 4/4] feat(formula): add some statistical formulas (#3684) Co-authored-by: wpxp123456 --- packages/engine-formula/src/basics/math.ts | 370 +++++++++ .../engine-formula/src/basics/statistical.ts | 391 ++++++--- .../src/engine/ast-node/function-node.ts | 17 +- .../src/engine/utils/array-object.ts | 74 +- .../src/functions/base-function.ts | 5 +- .../betadist/__tests__/index.spec.ts | 17 + .../functions/compatibility/betadist/index.ts | 20 + .../functions/compatibility/function-map.ts | 32 + .../hypgeomdist/__tests__/index.spec.ts | 228 ++++++ .../compatibility/hypgeomdist/index.ts | 128 +++ .../lognormdist/__tests__/index.spec.ts | 110 +++ .../compatibility/lognormdist/index.ts | 103 +++ .../negbinomdist/__tests__/index.spec.ts | 127 +++ .../compatibility/negbinomdist/index.ts | 103 +++ .../tdist/__tests__/index.spec.ts | 134 ++++ .../functions/compatibility/tdist/index.ts | 111 +++ .../src/functions/lookup/lookup/index.ts | 4 +- .../src/functions/math/mmult/index.ts | 27 +- .../beta-dist/__tests__/index.spec.ts | 21 + .../functions/statistical/beta-dist/index.ts | 24 + .../beta-inv/__tests__/index.spec.ts | 17 + .../functions/statistical/beta-inv/index.ts | 20 + .../binom-dist-range/__tests__/index.spec.ts | 12 + .../statistical/binom-dist-range/index.ts | 16 + .../binom-dist/__tests__/index.spec.ts | 13 + .../functions/statistical/binom-dist/index.ts | 16 + .../binom-inv/__tests__/index.spec.ts | 9 + .../functions/statistical/binom-inv/index.ts | 12 + .../chisq-dist-rt/__tests__/index.spec.ts | 5 + .../statistical/chisq-dist-rt/index.ts | 8 + .../chisq-dist/__tests__/index.spec.ts | 9 + .../functions/statistical/chisq-dist/index.ts | 12 + .../chisq-inv-rt/__tests__/index.spec.ts | 7 +- .../statistical/chisq-inv-rt/index.ts | 12 +- .../chisq-inv/__tests__/index.spec.ts | 5 + .../functions/statistical/chisq-inv/index.ts | 8 + .../confidence-norm/__tests__/index.spec.ts | 9 + .../statistical/confidence-norm/index.ts | 12 + .../confidence-t/__tests__/index.spec.ts | 9 + .../statistical/confidence-t/index.ts | 12 + .../expon-dist/__tests__/index.spec.ts | 9 + .../functions/statistical/expon-dist/index.ts | 12 + .../f-dist-rt/__tests__/index.spec.ts | 8 + .../functions/statistical/f-dist-rt/index.ts | 12 + .../f-dist/__tests__/index.spec.ts | 12 + .../src/functions/statistical/f-dist/index.ts | 16 + .../f-inv-rt/__tests__/index.spec.ts | 8 + .../functions/statistical/f-inv-rt/index.ts | 12 + .../statistical/f-inv/__tests__/index.spec.ts | 8 + .../src/functions/statistical/f-inv/index.ts | 12 + .../frequency/__tests__/index.spec.ts | 322 ++++++++ .../functions/statistical/frequency/index.ts | 139 ++++ .../src/functions/statistical/function-map.ts | 93 +++ .../gamma-dist/__tests__/index.spec.ts | 181 +++++ .../functions/statistical/gamma-dist/index.ts | 120 +++ .../gamma-inv/__tests__/index.spec.ts | 132 ++++ .../functions/statistical/gamma-inv/index.ts | 107 +++ .../statistical/gamma/__tests__/index.spec.ts | 115 +++ .../src/functions/statistical/gamma/index.ts | 68 ++ .../gammaln/__tests__/index.spec.ts | 117 +++ .../functions/statistical/gammaln/index.ts | 68 ++ .../statistical/gauss/__tests__/index.spec.ts | 111 +++ .../src/functions/statistical/gauss/index.ts | 58 ++ .../geomean/__tests__/index.spec.ts | 98 +++ .../functions/statistical/geomean/index.ts | 110 +++ .../growth/__tests__/index.spec.ts | 569 +++++++++++++ .../src/functions/statistical/growth/index.ts | 357 +++++++++ .../harmean/__tests__/index.spec.ts | 98 +++ .../functions/statistical/harmean/index.ts | 114 +++ .../hypgeom-dist/__tests__/index.spec.ts | 258 ++++++ .../statistical/hypgeom-dist/index.ts | 145 ++++ .../functions/statistical/intercept/index.ts | 2 +- .../statistical/kurt/__tests__/index.spec.ts | 133 ++++ .../src/functions/statistical/kurt/index.ts | 110 +++ .../statistical/large/__tests__/index.spec.ts | 143 ++++ .../src/functions/statistical/large/index.ts | 105 +++ .../lognorm-dist/__tests__/index.spec.ts | 130 +++ .../statistical/lognorm-dist/index.ts | 120 +++ .../lognorm-inv/__tests__/index.spec.ts | 118 +++ .../statistical/lognorm-inv/index.ts | 107 +++ .../median/__tests__/index.spec.ts | 109 +++ .../src/functions/statistical/median/index.ts | 111 +++ .../mode-mult/__tests__/index.spec.ts | 119 +++ .../functions/statistical/mode-mult/index.ts | 109 +++ .../mode-sngl/__tests__/index.spec.ts | 99 +++ .../functions/statistical/mode-sngl/index.ts | 105 +++ .../negbinom-dist/__tests__/index.spec.ts | 166 ++++ .../statistical/negbinom-dist/index.ts | 120 +++ .../norm-dist/__tests__/index.spec.ts | 13 + .../functions/statistical/norm-dist/index.ts | 16 + .../norm-inv/__tests__/index.spec.ts | 9 + .../functions/statistical/norm-inv/index.ts | 12 + .../norm-s-dist/__tests__/index.spec.ts | 5 + .../statistical/norm-s-dist/index.ts | 8 + .../pearson/__tests__/index.spec.ts | 311 ++++++++ .../functions/statistical/pearson/index.ts | 125 +++ .../percentile-exc/__tests__/index.spec.ts | 160 ++++ .../statistical/percentile-exc/index.ts | 115 +++ .../percentile-inc/__tests__/index.spec.ts | 143 ++++ .../statistical/percentile-inc/index.ts | 115 +++ .../percentrank-exc/__tests__/index.spec.ts | 213 +++++ .../statistical/percentrank-exc/index.ts | 165 ++++ .../percentrank-inc/__tests__/index.spec.ts | 213 +++++ .../statistical/percentrank-inc/index.ts | 165 ++++ .../permut/__tests__/index.spec.ts | 111 +++ .../src/functions/statistical/permut/index.ts | 89 +++ .../permutationa/__tests__/index.spec.ts | 122 +++ .../statistical/permutationa/index.ts | 94 +++ .../statistical/phi/__tests__/index.spec.ts | 111 +++ .../src/functions/statistical/phi/index.ts | 57 ++ .../poisson-dist/__tests__/index.spec.ts | 145 ++++ .../statistical/poisson-dist/index.ts | 109 +++ .../statistical/prob/__tests__/index.spec.ts | 261 ++++++ .../src/functions/statistical/prob/index.ts | 215 +++++ .../quartile-exc/__tests__/index.spec.ts | 158 ++++ .../statistical/quartile-exc/index.ts | 120 +++ .../quartile-inc/__tests__/index.spec.ts | 126 +++ .../statistical/quartile-inc/index.ts | 116 +++ .../statistical/rsq/__tests__/index.spec.ts | 311 ++++++++ .../src/functions/statistical/rsq/index.ts | 127 +++ .../skew-p/__tests__/index.spec.ts | 133 ++++ .../src/functions/statistical/skew-p/index.ts | 110 +++ .../statistical/skew/__tests__/index.spec.ts | 133 ++++ .../src/functions/statistical/skew/index.ts | 110 +++ .../statistical/slope/__tests__/index.spec.ts | 311 ++++++++ .../src/functions/statistical/slope/index.ts | 123 +++ .../statistical/small/__tests__/index.spec.ts | 143 ++++ .../src/functions/statistical/small/index.ts | 105 +++ .../standardize/__tests__/index.spec.ts | 110 +++ .../statistical/standardize/index.ts | 102 +++ .../statistical/steyx/__tests__/index.spec.ts | 354 +++++++++ .../src/functions/statistical/steyx/index.ts | 131 +++ .../t-dist-2t/__tests__/index.spec.ts | 110 +++ .../functions/statistical/t-dist-2t/index.ts | 96 +++ .../t-dist-rt/__tests__/index.spec.ts | 110 +++ .../functions/statistical/t-dist-rt/index.ts | 96 +++ .../t-dist/__tests__/index.spec.ts | 130 +++ .../src/functions/statistical/t-dist/index.ts | 113 +++ .../t-inv-2t/__tests__/index.spec.ts | 103 +++ .../functions/statistical/t-inv-2t/index.ts | 96 +++ .../statistical/t-inv/__tests__/index.spec.ts | 103 +++ .../src/functions/statistical/t-inv/index.ts | 96 +++ .../t-test/__tests__/index.spec.ts | 303 +++++++ .../src/functions/statistical/t-test/index.ts | 409 ++++++++++ .../trimmean/__tests__/index.spec.ts | 126 +++ .../functions/statistical/trimmean/index.ts | 110 +++ .../weibull-dist/__tests__/index.spec.ts | 181 +++++ .../statistical/weibull-dist/index.ts | 125 +++ .../z-test/__tests__/index.spec.ts | 168 ++++ .../src/functions/statistical/z-test/index.ts | 169 ++++ .../function-list/compatibility/en-US.ts | 103 ++- .../function-list/compatibility/ja-JP.ts | 107 +-- .../function-list/compatibility/vi-VN.ts | 140 ++-- .../function-list/compatibility/zh-CN.ts | 111 +-- .../function-list/compatibility/zh-TW.ts | 181 +++-- .../src/locale/function-list/date/zh-TW.ts | 42 +- .../locale/function-list/engineering/zh-TW.ts | 142 ++-- .../locale/function-list/financial/zh-CN.ts | 10 +- .../locale/function-list/financial/zh-TW.ts | 468 +++++------ .../locale/function-list/information/zh-TW.ts | 10 +- .../src/locale/function-list/logical/zh-CN.ts | 14 +- .../src/locale/function-list/logical/zh-TW.ts | 10 +- .../src/locale/function-list/lookup/zh-CN.ts | 2 +- .../src/locale/function-list/lookup/zh-TW.ts | 2 +- .../src/locale/function-list/math/vi-VN.ts | 4 +- .../src/locale/function-list/math/zh-TW.ts | 156 ++-- .../locale/function-list/statistical/en-US.ts | 256 +++--- .../locale/function-list/statistical/ja-JP.ts | 260 +++--- .../locale/function-list/statistical/vi-VN.ts | 678 ++++++++++++++++ .../locale/function-list/statistical/zh-CN.ts | 268 ++++--- .../locale/function-list/statistical/zh-TW.ts | 406 +++++----- .../src/locale/function-list/text/zh-TW.ts | 14 +- .../services/function-list/compatibility.ts | 312 +++++--- .../src/services/function-list/financial.ts | 16 +- .../src/services/function-list/lookup.ts | 4 +- .../src/services/function-list/math.ts | 6 +- .../src/services/function-list/statistical.ts | 746 +++++++++++------- .../src/services/function-list/text.ts | 2 +- 178 files changed, 18810 insertions(+), 1893 deletions(-) create mode 100644 packages/engine-formula/src/functions/compatibility/hypgeomdist/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/compatibility/hypgeomdist/index.ts create mode 100644 packages/engine-formula/src/functions/compatibility/lognormdist/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/compatibility/lognormdist/index.ts create mode 100644 packages/engine-formula/src/functions/compatibility/negbinomdist/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/compatibility/negbinomdist/index.ts create mode 100644 packages/engine-formula/src/functions/compatibility/tdist/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/compatibility/tdist/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/frequency/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/frequency/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/gamma-dist/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/gamma-dist/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/gamma-inv/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/gamma-inv/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/gamma/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/gamma/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/gammaln/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/gammaln/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/gauss/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/gauss/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/geomean/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/geomean/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/growth/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/growth/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/harmean/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/harmean/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/hypgeom-dist/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/hypgeom-dist/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/kurt/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/kurt/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/large/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/large/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/lognorm-dist/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/lognorm-dist/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/lognorm-inv/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/lognorm-inv/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/median/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/median/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/mode-mult/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/mode-mult/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/mode-sngl/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/mode-sngl/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/negbinom-dist/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/negbinom-dist/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/pearson/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/pearson/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/percentile-exc/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/percentile-exc/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/percentile-inc/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/percentile-inc/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/percentrank-exc/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/percentrank-exc/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/percentrank-inc/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/percentrank-inc/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/permut/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/permut/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/permutationa/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/permutationa/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/phi/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/phi/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/poisson-dist/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/poisson-dist/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/prob/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/prob/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/quartile-exc/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/quartile-exc/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/quartile-inc/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/quartile-inc/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/rsq/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/rsq/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/skew-p/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/skew-p/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/skew/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/skew/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/slope/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/slope/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/small/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/small/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/standardize/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/standardize/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/steyx/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/steyx/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/t-dist-2t/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/t-dist-2t/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/t-dist-rt/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/t-dist-rt/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/t-dist/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/t-dist/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/t-inv-2t/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/t-inv-2t/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/t-inv/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/t-inv/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/t-test/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/t-test/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/trimmean/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/trimmean/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/weibull-dist/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/weibull-dist/index.ts create mode 100644 packages/engine-formula/src/functions/statistical/z-test/__tests__/index.spec.ts create mode 100644 packages/engine-formula/src/functions/statistical/z-test/index.ts diff --git a/packages/engine-formula/src/basics/math.ts b/packages/engine-formula/src/basics/math.ts index c07190440387..08b860bb91d3 100644 --- a/packages/engine-formula/src/basics/math.ts +++ b/packages/engine-formula/src/basics/math.ts @@ -128,6 +128,376 @@ function adjoint(matrix: number[][]): number[][] { return adj; } +export function calculateMmult(matrix1: number[][], matrix2: number[][]): number[][] { + return matrix1.map((row) => matrix2[0].map((_, colIndex) => + row.reduce((sum, element, rowIndex) => sum + element * matrix2[rowIndex][colIndex], 0) + )); +} + +export function matrixTranspose(matrix: number[][]): number[][] { + return matrix[0].map((_, colIndex) => matrix.map((row) => row[colIndex])); +} + +export function inverseMatrixByUSV(matrix: number[][]): number[][] | null { + const matrixUSV = getMatrixUSV(matrix); + + if (!matrixUSV) { + return null; + } + + const { matrixU, matrixS, matrixV } = matrixUSV; + + const matrixUT = matrixTranspose(matrixU); + const newMatrix = Array.from({ length: matrixS.length }, () => new Array(matrix[0].length).fill(0)); + const EPSILON = Math.max(matrix.length, matrix[0].length) * Number.EPSILON * matrixS[0]; + + for (let i = 0; i < matrixS.length; i++) { + if (Math.abs(matrixS[i]) > EPSILON) { + newMatrix[i][i] = 1 / matrixS[i]; + } + } + + return calculateMmult(matrixV, calculateMmult(newMatrix, matrixUT)); +} + +// eslint-disable-next-line +function getMatrixUSV(matrix: number[][]) { + const matrixU = matrixTranspose(matrix); + const m = matrixU.length; + const n = matrixU[0].length; + + if (m < n) { + return null; + } + + const matrixF = new Array(n).fill(0); + const matrixS = new Array(n).fill(0); + const matrixV = Array.from({ length: n }, () => new Array(n).fill(0)); + + let EPSILON = Number.EPSILON; + let sqrt = 0; + let msp = 0; + let maxCoeffecient = 0; + + for (let i = 0; i < n; i++) { + matrixF[i] = sqrt; + msp = getMatrixSumProductOfRows(matrixU, i, m, i, i); + + if (msp <= 1e-64 / EPSILON) { + sqrt = 0; + } else { + sqrt = Math.sqrt(msp); + + if (matrixU[i][i] >= 0) { + sqrt = -sqrt; + } + + const temp = matrixU[i][i] * sqrt - msp; + matrixU[i][i] -= sqrt; + + for (let j = i + 1; j < n; j++) { + msp = getMatrixSumProductOfRows(matrixU, i, m, i, j); + + for (let k = i; k < m; k++) { + matrixU[k][j] += msp / temp * matrixU[k][i]; + } + } + } + + matrixS[i] = sqrt; + + msp = getMatrixSumProductOfCols(matrixU, i + 1, n, i, i); + + if (msp <= 1e-64 / EPSILON) { + sqrt = 0; + } else { + sqrt = Math.sqrt(msp); + + if (matrixU[i][i + 1] >= 0) { + sqrt = -sqrt; + } + + const temp = matrixU[i][i + 1] * sqrt - msp; + matrixU[i][i + 1] -= sqrt; + + for (let j = i + 1; j < n; j++) { + matrixF[j] = matrixU[i][j] / temp; + } + + for (let j = i + 1; j < m; j++) { + msp = getMatrixSumProductOfCols(matrixU, i + 1, n, j, i); + + for (let k = i + 1; k < n; k++) { + matrixU[j][k] += msp * matrixF[k]; + } + } + } + + const coefficient = Math.abs(matrixS[i]) + Math.abs(matrixF[i]); + + if (coefficient > maxCoeffecient) { + maxCoeffecient = coefficient; + } + } + + let o = 0; + + for (let i = n - 1; i >= 0; i--) { + if (sqrt !== 0) { + for (let j = o; j < n; j++) { + matrixV[j][i] = matrixU[i][j] / (sqrt * matrixU[i][i + 1]); + } + + for (let j = o; j < n; j++) { + msp = 0; + + for (let k = o; k < n; k++) { + msp += matrixU[i][k] * matrixV[k][j]; + } + + for (let k = o; k < n; k++) { + matrixV[k][j] += msp * matrixV[k][i]; + } + } + } + + for (let j = o; j < n; j++) { + matrixV[i][j] = 0; + matrixV[j][i] = 0; + } + + matrixV[i][i] = 1; + sqrt = matrixF[i]; + o = i; + } + + for (let i = n - 1; i >= 0; i--) { + sqrt = matrixS[i]; + + for (let j = i + 1; j < n; j++) { + matrixU[i][j] = 0; + } + + if (sqrt !== 0) { + for (let j = i + 1; j < n; j++) { + msp = getMatrixSumProductOfRows(matrixU, i + 1, m, i, j); + + for (let k = i; k < m; k++) { + matrixU[k][j] += msp / (matrixU[i][i] * sqrt) * matrixU[k][i]; + } + } + + for (let j = i; j < m; j++) { + matrixU[j][i] /= sqrt; + } + } else { + for (let j = i; j < m; j++) { + matrixU[j][i] = 0; + } + } + + matrixU[i][i] += 1; + } + + EPSILON *= maxCoeffecient; + + let a = 0; + let b = 0; + let ratio = 0; + + for (let i = n - 1; i >= 0; i--) { + for (let S = 0; S < 50; S++) { + let isNeedHandle = false; + let index = i; + + for (; index >= 0; index--) { + if (Math.abs(matrixF[index]) <= EPSILON) { + isNeedHandle = true; + break; + } + + if (Math.abs(matrixS[index - 1]) <= EPSILON) { + break; + } + } + + if (!isNeedHandle) { + let temp1 = 0; + let temp2 = 1; + + for (let j = index; j < i + 1; j++) { + a = temp2 * matrixF[j]; + b = matrixS[j]; + matrixF[j] *= temp1; + + if (Math.abs(a) <= EPSILON) { + break; + } + + ratio = computeHypotenuse(a, b); + matrixS[j] = ratio; + temp1 = b / ratio; + temp2 = -a / ratio; + + for (let k = 0; k < m; k++) { + const value1 = matrixU[k][index - 1]; + const value2 = matrixU[k][j]; + + matrixU[k][index - 1] = value1 * temp1 + value2 * temp2; + matrixU[k][j] = -value1 * temp2 + value2 * temp1; + } + } + } + + if (index === i) { + if (matrixS[i] < 0) { + matrixS[i] = -matrixS[i]; + + for (let j = 0; j < n; j++) { + matrixV[j][i] = -matrixV[j][i]; + } + } + + break; + } + + if (S >= 49) { + return null; + } + + let indexValue = matrixS[index]; + + a = ((matrixS[i - 1] - matrixS[i]) * (matrixS[i - 1] + matrixS[i]) + (matrixF[i - 1] - matrixF[i]) * (matrixF[i - 1] + matrixF[i])) / (2 * matrixF[i] * matrixS[i - 1]); + ratio = computeHypotenuse(a, 1); + + if (a < 0) { + a = ((indexValue - matrixS[i]) * (indexValue + matrixS[i]) + matrixF[i] * (matrixS[i - 1] / (a - ratio) - matrixF[i])) / indexValue; + } else { + a = ((indexValue - matrixS[i]) * (indexValue + matrixS[i]) + matrixF[i] * (matrixS[i - 1] / (a + ratio) - matrixF[i])) / indexValue; + } + + let temp1 = 1; + let temp2 = 1; + + for (let j = index + 1; j < i + 1; j++) { + let matrixFValue = matrixF[j]; + let matrixSValue = matrixS[j]; + + b = temp2 * matrixFValue; + matrixFValue *= temp1; + ratio = computeHypotenuse(a, b); + matrixF[j - 1] = ratio; + + temp1 = a / ratio; + temp2 = b / ratio; + a = indexValue * temp1 + matrixFValue * temp2; + b = matrixSValue * temp2; + matrixFValue = -indexValue * temp2 + matrixFValue * temp1; + matrixSValue *= temp1; + + for (let k = 0; k < n; k++) { + const value1 = matrixV[k][j - 1]; + const value2 = matrixV[k][j]; + + matrixV[k][j - 1] = value1 * temp1 + value2 * temp2; + matrixV[k][j] = -value1 * temp2 + value2 * temp1; + } + + ratio = computeHypotenuse(a, b); + matrixS[j - 1] = ratio; + temp1 = a / ratio; + temp2 = b / ratio; + a = temp1 * matrixFValue + temp2 * matrixSValue; + indexValue = -temp2 * matrixFValue + temp1 * matrixSValue; + + for (let k = 0; k < m; k++) { + const value1 = matrixU[k][j - 1]; + const value2 = matrixU[k][j]; + + matrixU[k][j - 1] = value1 * temp1 + value2 * temp2; + matrixU[k][j] = -value1 * temp2 + value2 * temp1; + } + } + + matrixF[index] = 0; + matrixF[i] = a; + matrixS[i] = indexValue; + } + } + + for (let i = 0; i < matrixS.length; i++) { + if (matrixS[i] < EPSILON) { + matrixS[i] = 0; + } + } + + for (let i = 0; i < n; i++) { + for (let j = i - 1; j >= 0; j--) { + if (matrixS[j] < matrixS[i]) { + const temp = matrixS[j]; + matrixS[j] = matrixS[i]; + matrixS[i] = temp; + + for (let k = 0; k < matrixU.length; k++) { + const temp = matrixU[k][i]; + matrixU[k][i] = matrixU[k][j]; + matrixU[k][j] = temp; + } + + for (let k = 0; k < matrixV.length; k++) { + const temp = matrixV[k][i]; + matrixV[k][i] = matrixV[k][j]; + matrixV[k][j] = temp; + } + + i = j; + } + } + } + + return { + matrixU, + matrixS, + matrixV, + }; +} + +function computeHypotenuse(a: number, b: number): number { + let ratio = 0; + + if (Math.abs(a) > Math.abs(b)) { + ratio = b / a; + return Math.abs(a) * Math.sqrt(1 + ratio * ratio); + } + + if (b !== 0) { + ratio = a / b; + return Math.abs(b) * Math.sqrt(1 + ratio * ratio); + } + + return 0; +} + +function getMatrixSumProductOfRows(matrix: number[][], startRow: number, endRow: number, col1: number, col2: number): number { + let sum = 0; + + for (let i = startRow; i < endRow; i++) { + sum += matrix[i][col1] * matrix[i][col2]; + } + + return sum; +} + +function getMatrixSumProductOfCols(matrix: number[][], startCol: number, endCol: number, row1: number, row2: number): number { + let sum = 0; + + for (let i = startCol; i < endCol; i++) { + sum += matrix[row1][i] * matrix[row2][i]; + } + + return sum; +} + export const romanToArabicMap = new Map([ ['I', 1], ['V', 5], diff --git a/packages/engine-formula/src/basics/statistical.ts b/packages/engine-formula/src/basics/statistical.ts index d30bfa973cdd..8af43db85cdd 100644 --- a/packages/engine-formula/src/basics/statistical.ts +++ b/packages/engine-formula/src/basics/statistical.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import { isRealNum } from '@univerjs/core'; -import { erf, erfcINV } from './engineering'; -import { calculateCombin } from './math'; import type { ArrayValueObject } from '../engine/value-object/array-value-object'; import type { BaseValueObject, ErrorValueObject } from '../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { erf, erfcINV } from './engineering'; +import { calculateCombin, calculateFactorial } from './math'; export function betaCDF(x: number, alpha: number, beta: number): number { if (x <= 0) { @@ -120,7 +120,7 @@ export function betaINV(probability: number, alpha: number, beta: number): numbe function incompleteBetaFunction(x: number, alpha: number, beta: number): number { const bt = (x === 0 || x === 1) ? 0 - : Math.exp(logGamma(alpha + beta) - logGamma(alpha) - logGamma(beta) + alpha * Math.log(x) + beta * Math.log(1 - x)); + : Math.exp(gammaln(alpha + beta) - gammaln(alpha) - gammaln(beta) + alpha * Math.log(x) + beta * Math.log(1 - x)); if (x < (alpha + 1) / (alpha + beta + 2)) { return bt * betaContinuedFraction(x, alpha, beta) / alpha; @@ -192,33 +192,169 @@ function betaFunction(alpha: number, beta: number): number { return Math.exp(betaFunctionNaturalLogarithm(alpha, beta)); } - return gammaFunction(alpha) * gammaFunction(beta) / gammaFunction(alpha + beta); + return gamma(alpha) * gamma(beta) / gamma(alpha + beta); } function betaFunctionNaturalLogarithm(alpha: number, beta: number): number { - return logGamma(alpha) + logGamma(beta) - logGamma(alpha + beta); + return gammaln(alpha) + gammaln(beta) - gammaln(alpha + beta); } -function logGamma(x: number): number { - const coefficients = [ - 76.18009172947146, -86.50532032941677, 24.01409824083091, // eslint-disable-line - -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5, - ]; +export function binomialCDF(x: number, trials: number, probability: number): number { + if (x < 0) { + return 0; + } - let y = x; - let tmp = x + 5.5; - tmp -= (x + 0.5) * Math.log(tmp); - let ser = 1.000000000190015; + if (x >= trials) { + return 1; + } - for (let j = 0; j < 6; j++) { - y += 1; - ser += coefficients[j] / y; + if (probability < 0 || probability > 1 || trials <= 0) { + return Number.NaN; } - return -tmp + Math.log(2.5066282746310005 * ser / x); // eslint-disable-line + let result = 0; + + for (let i = 0; i <= x; i++) { + result += binomialPDF(i, trials, probability); + } + + return result; +} + +export function binomialPDF(x: number, trials: number, probability: number): number { + if (probability === 0 || probability === 1) { + if (trials * probability === x) { + return 1; + } + + return 0; + } + + return calculateCombin(trials, x) * (probability ** x) * ((1 - probability) ** (trials - x)); } -function gammaFunction(x: number): number { +export function chisquareCDF(x: number, degFreedom: number): number { + if (x <= 0) { + return 0; + } + + return lowRegGamma(degFreedom / 2, x / 2); +} + +export function chisquarePDF(x: number, degFreedom: number): number { + if (x < 0) { + return 0; + } + + if (x === 0 && degFreedom === 2) { + return 0.5; + } + + return Math.exp((degFreedom / 2 - 1) * Math.log(x) - x / 2 - (degFreedom / 2) * Math.log(2) - gammaln(degFreedom / 2)); +} + +export function chisquareINV(probability: number, degFreedom: number): number { + if (probability <= 0) { + return 0; + } + + if (probability >= 1) { + return Infinity; + } + + return 2 * lowRegGammaInverse(probability, degFreedom / 2); +} + +export function centralFCDF(x: number, degFreedom1: number, degFreedom2: number): number { + if (x < 0) { + return 0; + } + + return incompleteBetaFunction((degFreedom1 * x) / (degFreedom1 * x + degFreedom2), degFreedom1 / 2, degFreedom2 / 2); +} + +export function centralFPDF(x: number, degFreedom1: number, degFreedom2: number): number { + if (x < 0) { + return 0; + } + + if (x === 0 && degFreedom1 < 2) { + return Infinity; + } + + if (x === 0 && degFreedom1 === 2) { + return 1; + } + + let result = 1 / betaFunction(degFreedom1 / 2, degFreedom2 / 2); + result *= (degFreedom1 / degFreedom2) ** (degFreedom1 / 2); + result *= x ** ((degFreedom1 / 2) - 1); + result *= (1 + (degFreedom1 / degFreedom2) * x) ** (-(degFreedom1 + degFreedom2) / 2); + + return result; +} + +export function centralFINV(probability: number, degFreedom1: number, degFreedom2: number): number { + if (probability <= 0) { + return 0; + } + + if (probability >= 1) { + return Infinity; + } + + return degFreedom2 / (degFreedom1 * (1 / betaINV(probability, degFreedom1 / 2, degFreedom2 / 2) - 1)); +} + +export function exponentialCDF(x: number, lambda: number): number { + if (x < 0) { + return 0; + } + + return 1 - Math.exp(-lambda * x); +} + +export function exponentialPDF(x: number, lambda: number): number { + if (x < 0) { + return 0; + } + + return lambda * Math.exp(-lambda * x); +} + +export function forecastLinear(x: number, knownYs: number[], knownXs: number[]): number { + const n = knownYs.length; + + let knownYsSum = 0; + let knownXsSum = 0; + + for (let i = 0; i < n; i++) { + knownYsSum += knownYs[i]; + knownXsSum += knownXs[i]; + } + + const knownYsMean = knownYsSum / n; + const knownXsMean = knownXsSum / n; + + let num = 0; + let den = 0; + + for (let i = 0; i < n; i++) { + num += (knownYs[i] - knownYsMean) * (knownXs[i] - knownXsMean); + den += (knownXs[i] - knownXsMean) ** 2; + } + + if (den === 0) { + return Infinity; + } + + const b = num / den; + const a = knownYsMean - b * knownXsMean; + + return a + b * x; +} + +export function gamma(x: number): number { const p = [ -1.716185138865495, 24.76565080557592, -379.80425647094563, 629.3311553128184, 866.9662027904133, -31451.272968848367, @@ -284,61 +420,27 @@ function gammaFunction(x: number): number { return res; } -export function binomialCDF(x: number, trials: number, probability: number): number { - if (x < 0) { - return 0; - } - - if (x >= trials) { - return 1; - } - - if (probability < 0 || probability > 1 || trials <= 0) { - return Number.NaN; - } - - let result = 0; - - for (let i = 0; i <= x; i++) { - result += binomialPDF(i, trials, probability); - } - - return result; -} - -export function binomialPDF(x: number, trials: number, probability: number): number { - if (probability === 0 || probability === 1) { - if (trials * probability === x) { - return 1; - } - - return 0; - } - - return calculateCombin(trials, x) * (probability ** x) * ((1 - probability) ** (trials - x)); -} - -export function chisquareCDF(x: number, degFreedom: number): number { +export function gammaCDF(x: number, alpha: number, beta: number): number { if (x <= 0) { return 0; } - return lowRegGamma(degFreedom / 2, x / 2); + return lowRegGamma(alpha, x / beta); } -export function chisquarePDF(x: number, degFreedom: number): number { +export function gammaPDF(x: number, alpha: number, beta: number): number { if (x < 0) { return 0; } - if (x === 0 && degFreedom === 2) { - return 0.5; + if (x === 0 && alpha === 1) { + return 1 / beta; } - return Math.exp((degFreedom / 2 - 1) * Math.log(x) - x / 2 - (degFreedom / 2) * Math.log(2) - logGamma(degFreedom / 2)); + return Math.exp((alpha - 1) * Math.log(x) - x / beta - gammaln(alpha) - alpha * Math.log(beta)); } -export function chisquareINV(probability: number, degFreedom: number): number { +export function gammaINV(probability: number, alpha: number, beta: number): number { if (probability <= 0) { return 0; } @@ -347,7 +449,25 @@ export function chisquareINV(probability: number, degFreedom: number): number { return Infinity; } - return 2 * lowRegGammaInverse(probability, degFreedom / 2); + return beta * lowRegGammaInverse(probability, alpha); +} + +export function gammaln(x: number): number { + const coefficients = [ + 76.18009172947146, -86.50532032941677, 24.01409824083091, // eslint-disable-line + -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5, + ]; + + let y = x; + let tmp = x + 5.5; + tmp -= (x + 0.5) * Math.log(tmp); + let ser = 1.000000000190015; + + for (let j = 0; j < 6; j++) { + ser += coefficients[j] / ++y; + } + + return -tmp + Math.log(2.5066282746310005 * ser / x); // eslint-disable-line } function lowRegGamma(a: number, x: number): number { @@ -355,9 +475,11 @@ function lowRegGamma(a: number, x: number): number { return Number.NaN; } + const EPSILON = 1e-30; + // calculate maximum number of itterations required for a - const MAX_ITER = Math.min(-~(Math.log((a >= 1) ? a : 1 / a) * 8.5 + a * 0.4 + 17), 10000); - const aln = logGamma(a); + const MAX_ITER = -~(Math.log((a >= 1) ? a : 1 / a) * 8.5 + a * 0.4 + 17); + const aln = gammaln(a); const exp = Math.exp(-x + a * Math.log(x) - aln); let _a = a; @@ -371,6 +493,10 @@ function lowRegGamma(a: number, x: number): number { for (let i = 1; i <= MAX_ITER; i++) { sum += del *= x / ++_a; + + if (Math.abs(del) < Math.abs(sum) * EPSILON) { + break; + } } return sum * exp; @@ -381,7 +507,7 @@ function lowRegGamma(a: number, x: number): number { } let b = x + 1 - a; - let c = 1 / 1.0e-30; + let c = 1 / EPSILON; let d = 1 / b; let h = d; @@ -390,9 +516,23 @@ function lowRegGamma(a: number, x: number): number { b += 2; d = temp * d + b; + + if (Math.abs(d) < EPSILON) { + d = EPSILON; + } + c = b + temp / c; + + if (Math.abs(c) < EPSILON) { + c = EPSILON; + } + d = 1 / d; h *= d * c; + + if (Math.abs(d * c - 1) < EPSILON) { + break; + } } return 1 - h * exp; @@ -431,7 +571,7 @@ function lowRegGammaInverse(p: number, a: number): number { } const EPSILON = 1e-8; - const aln = logGamma(a); + const aln = gammaln(a); let err, t; @@ -466,113 +606,110 @@ function lowRegGammaInverse(p: number, a: number): number { return x; } -export function studentTINV(probability: number, degFreedom: number): number { - let x = betaINV(2 * Math.min(probability, 1 - probability), 0.5 * degFreedom, 0.5); - x = Math.sqrt(degFreedom * (1 - x) / x); +export function hypergeometricCDF(x: number, n: number, M: number, N: number): number { + let result = 0; - return (probability > 0.5) ? x : -x; + for (let i = 0; i <= x; i++) { + result += hypergeometricPDF(i, n, M, N); + } + + return result; } -export function exponentialCDF(x: number, lambda: number): number { - if (x < 0) { +export function hypergeometricPDF(x: number, n: number, M: number, N: number): number { + if (n - x > N - M) { return 0; } - return 1 - Math.exp(-lambda * x); + return calculateCombin(M, x) * calculateCombin(N - M, n - x) / calculateCombin(N, n); } -export function exponentialPDF(x: number, lambda: number): number { +export function lognormalCDF(x: number, mean: number, standardDev: number): number { if (x < 0) { return 0; } - return lambda * Math.exp(-lambda * x); + return 0.5 + 0.5 * erf((Math.log(x) - mean) / Math.sqrt(2 * standardDev * standardDev)); } -export function centralFCDF(x: number, degFreedom1: number, degFreedom2: number): number { - if (x < 0) { +export function lognormalPDF(x: number, mean: number, standardDev: number): number { + if (x <= 0) { return 0; } - return incompleteBetaFunction((degFreedom1 * x) / (degFreedom1 * x + degFreedom2), degFreedom1 / 2, degFreedom2 / 2); + return Math.exp(-Math.log(x) - 0.5 * Math.log(2 * Math.PI) - Math.log(standardDev) - ((Math.log(x) - mean) ** 2) / (2 * standardDev * standardDev)); } -export function centralFPDF(x: number, degFreedom1: number, degFreedom2: number): number { - if (x < 0) { +export function lognormalINV(probability: number, mean: number, standardDev: number): number { + return Math.exp(normalINV(probability, mean, standardDev)); +} + +export function negbinomialCDF(numberF: number, numberS: number, probabilityS: number): number { + if (numberF < 0) { return 0; } - if (x === 0 && degFreedom1 < 2) { - return Infinity; - } + let result = 0; - if (x === 0 && degFreedom1 === 2) { - return 1; + for (let i = 0; i <= numberF; i++) { + result += negbinomialPDF(i, numberS, probabilityS); } - let result = 1 / betaFunction(degFreedom1 / 2, degFreedom2 / 2); - result *= (degFreedom1 / degFreedom2) ** (degFreedom1 / 2); - result *= x ** ((degFreedom1 / 2) - 1); - result *= (1 + (degFreedom1 / degFreedom2) * x) ** (-(degFreedom1 + degFreedom2) / 2); - return result; } -export function centralFINV(probability: number, degFreedom1: number, degFreedom2: number): number { - if (probability <= 0) { +export function negbinomialPDF(numberF: number, numberS: number, probabilityS: number): number { + if (numberF < 0) { return 0; } - if (probability >= 1) { - return Infinity; - } - - return degFreedom2 / (degFreedom1 * (1 / betaINV(probability, degFreedom1 / 2, degFreedom2 / 2) - 1)); + return calculateCombin(numberF + numberS - 1, numberS - 1) * (probabilityS ** numberS) * ((1 - probabilityS) ** numberF); } -export function forecastLinear(x: number, knownYs: number[], knownXs: number[]): number { - const n = knownYs.length; - - let knownYsSum = 0; - let knownXsSum = 0; - - for (let i = 0; i < n; i++) { - knownYsSum += knownYs[i]; - knownXsSum += knownXs[i]; - } +export function normalCDF(x: number, mean: number, standardDev: number): number { + return 0.5 * (1 + erf((x - mean) / Math.sqrt(2 * standardDev * standardDev))); +} - const knownYsMean = knownYsSum / n; - const knownXsMean = knownXsSum / n; +export function normalPDF(x: number, mean: number, standardDev: number): number { + return Math.exp(-0.5 * Math.log(2 * Math.PI) - Math.log(standardDev) - (x - mean) ** 2 / (2 * standardDev * standardDev)); +} - let num = 0; - let den = 0; +export function normalINV(probability: number, mean: number, standardDev: number): number { + // eslint-disable-next-line + return -1.41421356237309505 * standardDev * erfcINV(2 * probability) + mean; +} - for (let i = 0; i < n; i++) { - num += (knownYs[i] - knownYsMean) * (knownXs[i] - knownXsMean); - den += (knownXs[i] - knownXsMean) ** 2; - } +export function poissonCDF(x: number, mean: number): number { + let result = 0; - if (den === 0) { - return Infinity; + for (let i = 0; i <= x; i++) { + result += poissonPDF(i, mean); } - const b = num / den; - const a = knownYsMean - b * knownXsMean; + return result; +} - return a + b * x; +export function poissonPDF(x: number, mean: number): number { + return Math.exp(-mean) * (mean ** x) / calculateFactorial(x); } -export function normalCDF(x: number, mean: number, standardDev: number): number { - return 0.5 * (1 + erf((x - mean) / Math.sqrt(2 * standardDev * standardDev))); +export function studentTCDF(x: number, degFreedom: number): number { + const result = 0.5 * incompleteBetaFunction(degFreedom / (x ** 2 + degFreedom), degFreedom / 2, 0.5); + + return x < 0 ? result : 1 - result; } -export function normalPDF(x: number, mean: number, standardDev: number): number { - return Math.exp(-0.5 * Math.log(2 * Math.PI) - Math.log(standardDev) - (x - mean) ** 2 / (2 * standardDev * standardDev)); +export function studentTPDF(x: number, degFreedom: number): number { + const pow = (1 + (x ** 2) / degFreedom) ** (-(degFreedom + 1) / 2); + + return 1 / (Math.sqrt(degFreedom) * betaFunction(0.5, degFreedom / 2)) * pow; } -export function normalINV(probability: number, mean: number, standardDev: number): number { - // eslint-disable-next-line - return -1.41421356237309505 * standardDev * erfcINV(2 * probability) + mean; +export function studentTINV(probability: number, degFreedom: number): number { + let x = betaINV(2 * Math.min(probability, 1 - probability), 0.5 * degFreedom, 0.5); + x = Math.sqrt(degFreedom * (1 - x) / x); + + return (probability > 0.5) ? x : -x; } export function getTwoArrayNumberValues( diff --git a/packages/engine-formula/src/engine/ast-node/function-node.ts b/packages/engine-formula/src/engine/ast-node/function-node.ts index 56239d970944..d2295c8559cd 100644 --- a/packages/engine-formula/src/engine/ast-node/function-node.ts +++ b/packages/engine-formula/src/engine/ast-node/function-node.ts @@ -163,14 +163,21 @@ export class FunctionNode extends BaseAstNode { return; } - const lookupVectorOrArrayRange = (lookupVectorOrArray as BaseReferenceObject).getRangeData(); + let lookupCountRow: number; + let lookupCountColumn: number; - const resultVectorRange = (resultVector as BaseReferenceObject).getRangeData(); + if (lookupVectorOrArray?.isReferenceObject()) { + const lookupVectorOrArrayRange = (lookupVectorOrArray as BaseReferenceObject).getRangeData(); + const { startRow, startColumn, endRow, endColumn } = lookupVectorOrArrayRange; - const { startRow, startColumn, endRow, endColumn } = lookupVectorOrArrayRange; + lookupCountRow = endRow - startRow + 1; + lookupCountColumn = endColumn - startColumn + 1; + } else { + lookupCountRow = lookupVectorOrArray?.isArray() ? (lookupVectorOrArray as ArrayValueObject).getRowCount() : 1; + lookupCountColumn = lookupVectorOrArray?.isArray() ? (lookupVectorOrArray as ArrayValueObject).getColumnCount() : 1; + } - const lookupCountRow = endRow - startRow + 1; - const lookupCountColumn = endColumn - startColumn + 1; + const resultVectorRange = (resultVector as BaseReferenceObject).getRangeData(); const { startRow: reStartRow, startColumn: reStartColumn, endRow: reEndRow, endColumn: reEndColumn } = resultVectorRange; diff --git a/packages/engine-formula/src/engine/utils/array-object.ts b/packages/engine-formula/src/engine/utils/array-object.ts index 07a413bf4a0f..9454da561c47 100644 --- a/packages/engine-formula/src/engine/utils/array-object.ts +++ b/packages/engine-formula/src/engine/utils/array-object.ts @@ -14,62 +14,48 @@ * limitations under the License. */ -import { ArrayValueObject } from '../value-object/array-value-object'; import type { BaseValueObject, IArrayValueObject } from '../value-object/base-value-object'; +import { ArrayValueObject } from '../value-object/array-value-object'; import { NullValueObject } from '../value-object/primitive-object'; export function expandArrayValueObject(rowCount: number, columnCount: number, valueObject: BaseValueObject, defaultValue?: BaseValueObject) { + const valueRowCount = valueObject.isArray() ? (valueObject as ArrayValueObject).getRowCount() : 1; + const valueColumnCount = valueObject.isArray() ? (valueObject as ArrayValueObject).getColumnCount() : 1; + const result: BaseValueObject[][] = []; - if (valueObject.isArray()) { - const valueRowCount = (valueObject as ArrayValueObject).getRowCount(); - const valueColumnCount = (valueObject as ArrayValueObject).getColumnCount(); + for (let r = 0; r < rowCount; r++) { + const row = []; - if (valueRowCount === 1 && valueColumnCount === 1) { - const v = (valueObject as ArrayValueObject).getFirstCell() as BaseValueObject; - for (let r = 0; r < rowCount; r++) { - const row = []; - for (let c = 0; c < columnCount; c++) { - row.push(v); - } - result.push(row); + for (let c = 0; c < columnCount; c++) { + if (valueRowCount === 1 && valueColumnCount === 1) { + const value = valueObject.isArray() ? (valueObject as ArrayValueObject).get(0, 0) as BaseValueObject : valueObject; + row.push(value); + continue; } - } else if (valueRowCount === 1 && valueColumnCount > 1) { - for (let r = 0; r < rowCount; r++) { - const row = []; - for (let c = 0; c < columnCount; c++) { - const v = (valueObject as ArrayValueObject).getRealValue(0, c) as BaseValueObject || (defaultValue ?? NullValueObject.create()); - row.push(v); - } - result.push(row); - } - } else if (valueColumnCount === 1 && valueRowCount > 1) { - for (let r = 0; r < rowCount; r++) { - const row = []; - for (let c = 0; c < columnCount; c++) { - const v = (valueObject as ArrayValueObject).getRealValue(r, 0) as BaseValueObject || (defaultValue ?? NullValueObject.create()); - row.push(v); - } - result.push(row); + + if (valueRowCount === 1 && c < valueColumnCount) { + const value = (valueObject as ArrayValueObject).get(0, c) as BaseValueObject; + row.push(value); + continue; } - } else { - for (let r = 0; r < rowCount; r++) { - const row = []; - for (let c = 0; c < columnCount; c++) { - const v = (valueObject as ArrayValueObject).getRealValue(r, c) as BaseValueObject || (defaultValue ?? NullValueObject.create()); - row.push(v); - } - result.push(row); + + if (valueColumnCount === 1 && r < valueRowCount) { + const value = (valueObject as ArrayValueObject).get(r, 0) as BaseValueObject; + row.push(value); + continue; } - } - } else { - for (let r = 0; r < rowCount; r++) { - const row = []; - for (let c = 0; c < columnCount; c++) { - row.push(valueObject); + + if (r >= valueRowCount || c >= valueColumnCount) { + row.push(defaultValue ?? NullValueObject.create()); + continue; } - result.push(row); + + const value = (valueObject as ArrayValueObject).get(r, c) as BaseValueObject; + row.push(value); } + + result.push(row); } return createNewArray(result, rowCount, columnCount); diff --git a/packages/engine-formula/src/functions/base-function.ts b/packages/engine-formula/src/functions/base-function.ts index 1c4e91269134..e88b0f735cc6 100644 --- a/packages/engine-formula/src/functions/base-function.ts +++ b/packages/engine-formula/src/functions/base-function.ts @@ -16,12 +16,10 @@ import type { IRange, LocaleType, Nullable } from '@univerjs/core'; import type { IFunctionNames } from '../basics/function'; - import type { BaseReferenceObject, FunctionVariantType, NodeValueType } from '../engine/reference-object/base-reference-object'; import type { ArrayBinarySearchType } from '../engine/utils/compare'; import type { ArrayValueObject } from '../engine/value-object/array-value-object'; import type { IDefinedNameMapItem } from '../services/defined-names.service'; - import { ErrorType } from '../basics/error-type'; import { regexTestSingeRange, regexTestSingleColumn, regexTestSingleRow } from '../basics/regex'; import { compareToken } from '../basics/token'; @@ -313,7 +311,8 @@ export class BaseFunction { } if (resultValue.isNull()) { - return ErrorValueObject.create(ErrorType.NA); + // return ErrorValueObject.create(ErrorType.NA); + return NumberValueObject.create(0); } return resultValue; diff --git a/packages/engine-formula/src/functions/compatibility/betadist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/compatibility/betadist/__tests__/index.spec.ts index 6b096f9ae2e3..8ddfd72d1212 100644 --- a/packages/engine-formula/src/functions/compatibility/betadist/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/compatibility/betadist/__tests__/index.spec.ts @@ -122,6 +122,23 @@ describe('Test betadist function', () => { const B = NumberValueObject.create(3); const result = testFunction.calculate(x, alpha, beta, A, B); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(2); + const alpha2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, alpha2, beta, A, B); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const beta2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(x2, alpha, beta2, A, B); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const A2 = ErrorValueObject.create(ErrorType.NAME); + const result4 = testFunction.calculate(x2, alpha, beta, A2, B); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); + + const B2 = ErrorValueObject.create(ErrorType.NAME); + const result5 = testFunction.calculate(x2, alpha, beta, A, B2); + expect(getObjectValue(result5)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/compatibility/betadist/index.ts b/packages/engine-formula/src/functions/compatibility/betadist/index.ts index 46ea90523544..d7115733b543 100644 --- a/packages/engine-formula/src/functions/compatibility/betadist/index.ts +++ b/packages/engine-formula/src/functions/compatibility/betadist/index.ts @@ -91,6 +91,26 @@ export class Betadist extends BaseFunction { AObject: BaseValueObject, BObject: BaseValueObject ): BaseValueObject { + if (xObject.isError()) { + return xObject; + } + + if (alphaObject.isError()) { + return alphaObject; + } + + if (betaObject.isError()) { + return betaObject; + } + + if (AObject.isError()) { + return AObject; + } + + if (BObject.isError()) { + return BObject; + } + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(xObject, alphaObject, betaObject, AObject, BObject); if (isError) { diff --git a/packages/engine-formula/src/functions/compatibility/function-map.ts b/packages/engine-formula/src/functions/compatibility/function-map.ts index 675dceb72da7..8eb24ae026e8 100644 --- a/packages/engine-formula/src/functions/compatibility/function-map.ts +++ b/packages/engine-formula/src/functions/compatibility/function-map.ts @@ -26,17 +26,33 @@ import { ExponDist } from '../statistical/expon-dist'; import { FDistRt } from '../statistical/f-dist-rt'; import { FInvRt } from '../statistical/f-inv-rt'; import { FTest } from '../statistical/f-test'; +import { GammaDist } from '../statistical/gamma-dist'; +import { GammaInv } from '../statistical/gamma-inv'; +import { LognormInv } from '../statistical/lognorm-inv'; +import { ModeSngl } from '../statistical/mode-sngl'; import { NormDist } from '../statistical/norm-dist'; import { NormInv } from '../statistical/norm-inv'; import { NormSInv } from '../statistical/norm-s-inv'; +import { PercentileInc } from '../statistical/percentile-inc'; +import { PercentrankInc } from '../statistical/percentrank-inc'; +import { PoissonDist } from '../statistical/poisson-dist'; +import { QuartileInc } from '../statistical/quartile-inc'; import { StdevP } from '../statistical/stdev-p'; import { StdevS } from '../statistical/stdev-s'; +import { TInv2t } from '../statistical/t-inv-2t'; +import { TTest } from '../statistical/t-test'; import { VarP } from '../statistical/var-p'; import { VarS } from '../statistical/var-s'; +import { WeibullDist } from '../statistical/weibull-dist'; +import { ZTest } from '../statistical/z-test'; import { Betadist } from './betadist'; import { FUNCTION_NAMES_COMPATIBILITY } from './function-names'; +import { Hypgeomdist } from './hypgeomdist'; +import { Lognormdist } from './lognormdist'; +import { Negbinomdist } from './negbinomdist'; import { Normsdist } from './normsdist'; import { Rank } from './rank'; +import { Tdist } from './tdist'; export const functionCompatibility = [ [Betadist, FUNCTION_NAMES_COMPATIBILITY.BETADIST], @@ -52,13 +68,29 @@ export const functionCompatibility = [ [FDistRt, FUNCTION_NAMES_COMPATIBILITY.FDIST], [FInvRt, FUNCTION_NAMES_COMPATIBILITY.FINV], [FTest, FUNCTION_NAMES_COMPATIBILITY.FTEST], + [GammaDist, FUNCTION_NAMES_COMPATIBILITY.GAMMADIST], + [GammaInv, FUNCTION_NAMES_COMPATIBILITY.GAMMAINV], + [Hypgeomdist, FUNCTION_NAMES_COMPATIBILITY.HYPGEOMDIST], + [Lognormdist, FUNCTION_NAMES_COMPATIBILITY.LOGNORMDIST], + [LognormInv, FUNCTION_NAMES_COMPATIBILITY.LOGINV], + [ModeSngl, FUNCTION_NAMES_COMPATIBILITY.MODE], + [Negbinomdist, FUNCTION_NAMES_COMPATIBILITY.NEGBINOMDIST], [NormDist, FUNCTION_NAMES_COMPATIBILITY.NORMDIST], [NormInv, FUNCTION_NAMES_COMPATIBILITY.NORMINV], [Normsdist, FUNCTION_NAMES_COMPATIBILITY.NORMSDIST], [NormSInv, FUNCTION_NAMES_COMPATIBILITY.NORMSINV], + [PercentileInc, FUNCTION_NAMES_COMPATIBILITY.PERCENTILE], + [PercentrankInc, FUNCTION_NAMES_COMPATIBILITY.PERCENTRANK], + [PoissonDist, FUNCTION_NAMES_COMPATIBILITY.POISSON], + [QuartileInc, FUNCTION_NAMES_COMPATIBILITY.QUARTILE], [Rank, FUNCTION_NAMES_COMPATIBILITY.RANK], [StdevS, FUNCTION_NAMES_COMPATIBILITY.STDEV], [StdevP, FUNCTION_NAMES_COMPATIBILITY.STDEVP], + [Tdist, FUNCTION_NAMES_COMPATIBILITY.TDIST], + [TInv2t, FUNCTION_NAMES_COMPATIBILITY.TINV], + [TTest, FUNCTION_NAMES_COMPATIBILITY.TTEST], [VarS, FUNCTION_NAMES_COMPATIBILITY.VAR], [VarP, FUNCTION_NAMES_COMPATIBILITY.VARP], + [WeibullDist, FUNCTION_NAMES_COMPATIBILITY.WEIBULL], + [ZTest, FUNCTION_NAMES_COMPATIBILITY.ZTEST], ]; diff --git a/packages/engine-formula/src/functions/compatibility/hypgeomdist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/compatibility/hypgeomdist/__tests__/index.spec.ts new file mode 100644 index 000000000000..cb9e2917abd8 --- /dev/null +++ b/packages/engine-formula/src/functions/compatibility/hypgeomdist/__tests__/index.spec.ts @@ -0,0 +1,228 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_COMPATIBILITY } from '../../function-names'; +import { Hypgeomdist } from '../index'; + +describe('Test hypgeomdist function', () => { + const testFunction = new Hypgeomdist(FUNCTION_NAMES_COMPATIBILITY.HYPGEOMDIST); + + describe('Hypgeomdist', () => { + it('Value is normal', () => { + const sampleS = NumberValueObject.create(1); + const numberSample = NumberValueObject.create(4); + const populationS = NumberValueObject.create(8); + const numberPop = NumberValueObject.create(20); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop); + expect(getObjectValue(result)).toBe(0.3632610939112487); + }); + + it('Value is large number', () => { + const sampleS = NumberValueObject.create(1); + const numberSample = NumberValueObject.create(100000); + const populationS = NumberValueObject.create(1000000); + const numberPop = NumberValueObject.create(10000000); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop); + expect(getObjectValue(result)).toBe(0); + }); + + it('SampleS value test', () => { + const sampleS = NumberValueObject.create(-1); + const numberSample = NumberValueObject.create(4); + const populationS = NumberValueObject.create(8); + const numberPop = NumberValueObject.create(20); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const sampleS2 = NumberValueObject.create(5); + const result2 = testFunction.calculate(sampleS2, numberSample, populationS, numberPop); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + + const sampleS3 = BooleanValueObject.create(true); + const result3 = testFunction.calculate(sampleS3, numberSample, populationS, numberPop); + expect(getObjectValue(result3)).toBe(0.3632610939112487); + + const sampleS4 = NullValueObject.create(); + const result4 = testFunction.calculate(sampleS4, numberSample, populationS, numberPop); + expect(getObjectValue(result4)).toBe(0.1021671826625387); + + const sampleS5 = StringValueObject.create('test'); + const result5 = testFunction.calculate(sampleS5, numberSample, populationS, numberPop); + expect(getObjectValue(result5)).toBe(ErrorType.VALUE); + + const sampleS6 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(sampleS6, numberSample, populationS, numberPop); + expect(getObjectValue(result6)).toBe(ErrorType.NAME); + }); + + it('NumberSample value test', () => { + const sampleS = NumberValueObject.create(1); + const numberSample = NumberValueObject.create(-1); + const populationS = NumberValueObject.create(8); + const numberPop = NumberValueObject.create(20); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const numberSample2 = NumberValueObject.create(22); + const result2 = testFunction.calculate(sampleS, numberSample2, populationS, numberPop); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + + const numberSample3 = BooleanValueObject.create(true); + const result3 = testFunction.calculate(sampleS, numberSample3, populationS, numberPop); + expect(getObjectValue(result3)).toBe(0.4); + + const numberSample4 = NullValueObject.create(); + const result4 = testFunction.calculate(sampleS, numberSample4, populationS, numberPop); + expect(getObjectValue(result4)).toBe(ErrorType.NUM); + + const numberSample5 = StringValueObject.create('test'); + const result5 = testFunction.calculate(sampleS, numberSample5, populationS, numberPop); + expect(getObjectValue(result5)).toBe(ErrorType.VALUE); + + const numberSample6 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(sampleS, numberSample6, populationS, numberPop); + expect(getObjectValue(result6)).toBe(ErrorType.NAME); + }); + + it('PopulationS value test', () => { + const sampleS = NumberValueObject.create(1); + const numberSample = NumberValueObject.create(4); + const populationS = NumberValueObject.create(-1); + const numberPop = NumberValueObject.create(20); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const populationS2 = NumberValueObject.create(21); + const result2 = testFunction.calculate(sampleS, numberSample, populationS2, numberPop); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + + const populationS3 = BooleanValueObject.create(true); + const result3 = testFunction.calculate(sampleS, numberSample, populationS3, numberPop); + expect(getObjectValue(result3)).toBe(0.2); + + const populationS4 = NullValueObject.create(); + const result4 = testFunction.calculate(sampleS, numberSample, populationS4, numberPop); + expect(getObjectValue(result4)).toBe(ErrorType.NUM); + + const populationS5 = StringValueObject.create('test'); + const result5 = testFunction.calculate(sampleS, numberSample, populationS5, numberPop); + expect(getObjectValue(result5)).toBe(ErrorType.VALUE); + + const populationS6 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(sampleS, numberSample, populationS6, numberPop); + expect(getObjectValue(result6)).toBe(ErrorType.NAME); + }); + + it('NumberPop value test', () => { + const sampleS = NumberValueObject.create(1); + const numberSample = NumberValueObject.create(4); + const populationS = NumberValueObject.create(8); + const numberPop = NumberValueObject.create(-20); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const numberPop2 = BooleanValueObject.create(true); + const result2 = testFunction.calculate(sampleS, numberSample, populationS, numberPop2); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + + const numberPop3 = NullValueObject.create(); + const result3 = testFunction.calculate(sampleS, numberSample, populationS, numberPop3); + expect(getObjectValue(result3)).toBe(ErrorType.NUM); + + const numberPop4 = StringValueObject.create('test'); + const result4 = testFunction.calculate(sampleS, numberSample, populationS, numberPop4); + expect(getObjectValue(result4)).toBe(ErrorType.VALUE); + + const numberPop5 = ErrorValueObject.create(ErrorType.NAME); + const result5 = testFunction.calculate(sampleS, numberSample, populationS, numberPop5); + expect(getObjectValue(result5)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const sampleS = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const numberSample = NumberValueObject.create(4); + const populationS = NumberValueObject.create(8); + const numberPop = NumberValueObject.create(20); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop); + expect(getObjectValue(result)).toStrictEqual([ + [0.3632610939112487, ErrorType.VALUE, 0.3632610939112487, 0.3632610939112487, 0.1021671826625387, 0.1021671826625387], + [0.1021671826625387, ErrorType.NUM, 0.3814241486068111, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + + const sampleS2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [4], + [8], + [20], + ]), + rowCount: 4, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const numberSample2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [4], + [8], + [20], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(sampleS2, numberSample2, populationS, numberPop); + expect(getObjectValue(result2)).toStrictEqual([ + [0.3632610939112487], + [0.27506549178375805], + [1], + [ErrorType.NA], + ]); + }); + + it('More test', () => { + const sampleS = NumberValueObject.create(20); + const numberSample = NumberValueObject.create(20); + const populationS = NumberValueObject.create(20); + const numberPop = NumberValueObject.create(20); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop); + expect(getObjectValue(result)).toBe(1); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/compatibility/hypgeomdist/index.ts b/packages/engine-formula/src/functions/compatibility/hypgeomdist/index.ts new file mode 100644 index 000000000000..66e1cfc6845f --- /dev/null +++ b/packages/engine-formula/src/functions/compatibility/hypgeomdist/index.ts @@ -0,0 +1,128 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ErrorType } from '../../../basics/error-type'; +import { hypergeometricPDF } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; + +export class Hypgeomdist extends BaseFunction { + override minParams = 4; + + override maxParams = 4; + + override calculate( + sampleS: BaseValueObject, + numberSample: BaseValueObject, + populationS: BaseValueObject, + numberPop: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + sampleS.isArray() ? (sampleS as ArrayValueObject).getRowCount() : 1, + numberSample.isArray() ? (numberSample as ArrayValueObject).getRowCount() : 1, + populationS.isArray() ? (populationS as ArrayValueObject).getRowCount() : 1, + numberPop.isArray() ? (numberPop as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + sampleS.isArray() ? (sampleS as ArrayValueObject).getColumnCount() : 1, + numberSample.isArray() ? (numberSample as ArrayValueObject).getColumnCount() : 1, + populationS.isArray() ? (populationS as ArrayValueObject).getColumnCount() : 1, + numberPop.isArray() ? (numberPop as ArrayValueObject).getColumnCount() : 1 + ); + + const sampleSArray = expandArrayValueObject(maxRowLength, maxColumnLength, sampleS, ErrorValueObject.create(ErrorType.NA)); + const numberSampleArray = expandArrayValueObject(maxRowLength, maxColumnLength, numberSample, ErrorValueObject.create(ErrorType.NA)); + const populationSArray = expandArrayValueObject(maxRowLength, maxColumnLength, populationS, ErrorValueObject.create(ErrorType.NA)); + const numberPopArray = expandArrayValueObject(maxRowLength, maxColumnLength, numberPop, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = sampleSArray.mapValue((sampleSObject, rowIndex, columnIndex) => { + const numberSampleObject = numberSampleArray.get(rowIndex, columnIndex) as BaseValueObject; + const populationSObject = populationSArray.get(rowIndex, columnIndex) as BaseValueObject; + const numberPopObject = numberPopArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (sampleSObject.isError()) { + return sampleSObject; + } + + if (numberSampleObject.isError()) { + return numberSampleObject; + } + + if (populationSObject.isError()) { + return populationSObject; + } + + if (numberPopObject.isError()) { + return numberPopObject; + } + + return this._handleSignleObject(sampleSObject, numberSampleObject, populationSObject, numberPopObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + sampleSObject: BaseValueObject, + numberSampleObject: BaseValueObject, + populationSObject: BaseValueObject, + numberPopObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(sampleSObject, numberSampleObject, populationSObject, numberPopObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_sampleSObject, _numberSampleObject, _populationSObject, _numberPopObject] = variants as BaseValueObject[]; + + const sampleSValue = Math.floor(+_sampleSObject.getValue()); + const numberSampleValue = Math.floor(+_numberSampleObject.getValue()); + const populationSValue = Math.floor(+_populationSObject.getValue()); + const numberPopValue = Math.floor(+_numberPopObject.getValue()); + + if ( + sampleSValue < 0 || + sampleSValue > numberSampleValue || + sampleSValue > populationSValue || + sampleSValue < numberSampleValue - numberPopValue + populationSValue || + numberSampleValue <= 0 || + numberSampleValue > numberPopValue || + populationSValue <= 0 || + populationSValue > numberPopValue || + numberPopValue <= 0 + ) { + return ErrorValueObject.create(ErrorType.NUM); + } + + let result = hypergeometricPDF(sampleSValue, numberSampleValue, populationSValue, numberPopValue); + + if (Number.isNaN(result)) { + result = 0; + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/compatibility/lognormdist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/compatibility/lognormdist/__tests__/index.spec.ts new file mode 100644 index 000000000000..44bbd4ea479d --- /dev/null +++ b/packages/engine-formula/src/functions/compatibility/lognormdist/__tests__/index.spec.ts @@ -0,0 +1,110 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_COMPATIBILITY } from '../../function-names'; +import { Lognormdist } from '../index'; + +describe('Test lognormdist function', () => { + const testFunction = new Lognormdist(FUNCTION_NAMES_COMPATIBILITY.LOGNORMDIST); + + describe('Lognormdist', () => { + it('Value is normal', () => { + const x = NumberValueObject.create(15.2069); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const result = testFunction.calculate(x, mean, standardDev); + expect(getObjectValue(result)).toBe(0.20623272748031884); + }); + + it('StandardDev value test', () => { + const x = NumberValueObject.create(15.2069); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(0); + const result = testFunction.calculate(x, mean, standardDev); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Value is normal string', () => { + const x = StringValueObject.create('test'); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const result = testFunction.calculate(x, mean, standardDev); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const x = BooleanValueObject.create(true); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const result = testFunction.calculate(x, mean, standardDev); + expect(getObjectValue(result)).toBe(0.06680720126885809); + }); + + it('Value is null', () => { + const x = NullValueObject.create(); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const result = testFunction.calculate(x, mean, standardDev); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Value is error', () => { + const x = ErrorValueObject.create(ErrorType.NAME); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const result = testFunction.calculate(x, mean, standardDev); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(15.2069); + const mean2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, mean2, standardDev); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const standardDev2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(x2, mean, standardDev2); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const x = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const result = testFunction.calculate(x, mean, standardDev); + expect(getObjectValue(result)).toStrictEqual([ + [0.06680720126885809, ErrorType.VALUE, 0.07377406798431951, 0.06680720126885809, ErrorType.NUM, ErrorType.NUM], + [ErrorType.NUM, 0.3636544740101908, 0.09896660651880768, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/compatibility/lognormdist/index.ts b/packages/engine-formula/src/functions/compatibility/lognormdist/index.ts new file mode 100644 index 000000000000..f86d57bd7776 --- /dev/null +++ b/packages/engine-formula/src/functions/compatibility/lognormdist/index.ts @@ -0,0 +1,103 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ErrorType } from '../../../basics/error-type'; +import { lognormalCDF } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; + +export class Lognormdist extends BaseFunction { + override minParams = 3; + + override maxParams = 3; + + override calculate( + x: BaseValueObject, + mean: BaseValueObject, + standardDev: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getRowCount() : 1, + mean.isArray() ? (mean as ArrayValueObject).getRowCount() : 1, + standardDev.isArray() ? (standardDev as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getColumnCount() : 1, + mean.isArray() ? (mean as ArrayValueObject).getColumnCount() : 1, + standardDev.isArray() ? (standardDev as ArrayValueObject).getColumnCount() : 1 + ); + + const xArray = expandArrayValueObject(maxRowLength, maxColumnLength, x, ErrorValueObject.create(ErrorType.NA)); + const meanArray = expandArrayValueObject(maxRowLength, maxColumnLength, mean, ErrorValueObject.create(ErrorType.NA)); + const standardDevArray = expandArrayValueObject(maxRowLength, maxColumnLength, standardDev, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = xArray.mapValue((xObject, rowIndex, columnIndex) => { + const meanObject = meanArray.get(rowIndex, columnIndex) as BaseValueObject; + const standardDevObject = standardDevArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (xObject.isError()) { + return xObject; + } + + if (meanObject.isError()) { + return meanObject; + } + + if (standardDevObject.isError()) { + return standardDevObject; + } + + return this._handleSignleObject(xObject, meanObject, standardDevObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + xObject: BaseValueObject, + meanObject: BaseValueObject, + standardDevObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(xObject, meanObject, standardDevObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_xObject, _meanObject, _standardDevObject] = variants as BaseValueObject[]; + + const xValue = +_xObject.getValue(); + const meanValue = +_meanObject.getValue(); + const standardDevValue = +_standardDevObject.getValue(); + + if (xValue <= 0 || standardDevValue <= 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const result = lognormalCDF(xValue, meanValue, standardDevValue); + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/compatibility/negbinomdist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/compatibility/negbinomdist/__tests__/index.spec.ts new file mode 100644 index 000000000000..9d73bdc3b6f5 --- /dev/null +++ b/packages/engine-formula/src/functions/compatibility/negbinomdist/__tests__/index.spec.ts @@ -0,0 +1,127 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_COMPATIBILITY } from '../../function-names'; +import { Negbinomdist } from '../index'; + +describe('Test negbinomdist function', () => { + const testFunction = new Negbinomdist(FUNCTION_NAMES_COMPATIBILITY.NEGBINOMDIST); + + describe('Negbinomdist', () => { + it('Value is normal', () => { + const numberF = NumberValueObject.create(6); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(0.5); + const result = testFunction.calculate(numberF, numberS, probabilityS); + expect(getObjectValue(result)).toBe(0.0763702392578125); + }); + + it('NumberF and numberS value test', () => { + const numberF = NumberValueObject.create(-6); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(0.5); + const result = testFunction.calculate(numberF, numberS, probabilityS); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const numberF2 = NumberValueObject.create(11); + const numberS2 = NumberValueObject.create(0.1); + const result2 = testFunction.calculate(numberF2, numberS2, probabilityS); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + }); + + it('ProbabilityS value test', () => { + const numberF = NumberValueObject.create(6); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(-0.5); + const result = testFunction.calculate(numberF, numberS, probabilityS); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const probabilityS2 = NumberValueObject.create(1.5); + const result2 = testFunction.calculate(numberF, numberS, probabilityS2); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + }); + + it('Value is normal string', () => { + const numberF = StringValueObject.create('test'); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(0.5); + const result = testFunction.calculate(numberF, numberS, probabilityS); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const numberF = BooleanValueObject.create(true); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(0.5); + const result = testFunction.calculate(numberF, numberS, probabilityS); + expect(getObjectValue(result)).toBe(0.0048828125); + }); + + it('Value is null', () => { + const numberF = NullValueObject.create(); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(0.5); + const result = testFunction.calculate(numberF, numberS, probabilityS); + expect(getObjectValue(result)).toBe(0.0009765625); + }); + + it('Value is error', () => { + const numberF = ErrorValueObject.create(ErrorType.NAME); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(0.5); + const result = testFunction.calculate(numberF, numberS, probabilityS); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const numberF2 = NumberValueObject.create(6); + const numberS2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(numberF2, numberS2, probabilityS); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const probabilityS2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(numberF2, numberS, probabilityS2); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const numberF = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(0.5); + const result = testFunction.calculate(numberF, numberS, probabilityS); + expect(getObjectValue(result)).toStrictEqual([ + [0.0048828125, ErrorType.VALUE, 0.0048828125, 0.0048828125, 0.0009765625, 0.0009765625], + [0.0009765625, 3.284420461640601e-21, 0.013427734375, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/compatibility/negbinomdist/index.ts b/packages/engine-formula/src/functions/compatibility/negbinomdist/index.ts new file mode 100644 index 000000000000..e9d439dcb038 --- /dev/null +++ b/packages/engine-formula/src/functions/compatibility/negbinomdist/index.ts @@ -0,0 +1,103 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { negbinomialPDF } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Negbinomdist extends BaseFunction { + override minParams = 3; + + override maxParams = 3; + + override calculate( + numberF: BaseValueObject, + numberS: BaseValueObject, + probabilityS: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + numberF.isArray() ? (numberF as ArrayValueObject).getRowCount() : 1, + numberS.isArray() ? (numberS as ArrayValueObject).getRowCount() : 1, + probabilityS.isArray() ? (probabilityS as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + numberF.isArray() ? (numberF as ArrayValueObject).getColumnCount() : 1, + numberS.isArray() ? (numberS as ArrayValueObject).getColumnCount() : 1, + probabilityS.isArray() ? (probabilityS as ArrayValueObject).getColumnCount() : 1 + ); + + const numberFArray = expandArrayValueObject(maxRowLength, maxColumnLength, numberF, ErrorValueObject.create(ErrorType.NA)); + const numberSArray = expandArrayValueObject(maxRowLength, maxColumnLength, numberS, ErrorValueObject.create(ErrorType.NA)); + const probabilitySArray = expandArrayValueObject(maxRowLength, maxColumnLength, probabilityS, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = numberFArray.mapValue((numberFObject, rowIndex, columnIndex) => { + const numberSObject = numberSArray.get(rowIndex, columnIndex) as BaseValueObject; + const probabilitySObject = probabilitySArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (numberFObject.isError()) { + return numberFObject; + } + + if (numberSObject.isError()) { + return numberSObject; + } + + if (probabilitySObject.isError()) { + return probabilitySObject; + } + + return this._handleSignleObject(numberFObject, numberSObject, probabilitySObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + numberFObject: BaseValueObject, + numberSObject: BaseValueObject, + probabilitySObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(numberFObject, numberSObject, probabilitySObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_numberFObject, _numberSObject, _probabilitySObject] = variants as BaseValueObject[]; + + const numberFValue = Math.floor(+_numberFObject.getValue()); + const numberSValue = Math.floor(+_numberSObject.getValue()); + const probabilitySValue = +_probabilitySObject.getValue(); + + if (numberFValue < 0 || numberSValue < 1 || probabilitySValue <= 0 || probabilitySValue >= 1) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const result = negbinomialPDF(numberFValue, numberSValue, probabilitySValue); + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/compatibility/tdist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/compatibility/tdist/__tests__/index.spec.ts new file mode 100644 index 000000000000..7e59d83759d3 --- /dev/null +++ b/packages/engine-formula/src/functions/compatibility/tdist/__tests__/index.spec.ts @@ -0,0 +1,134 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_COMPATIBILITY } from '../../function-names'; +import { Tdist } from '../index'; + +describe('Test tdist function', () => { + const testFunction = new Tdist(FUNCTION_NAMES_COMPATIBILITY.TDIST); + + describe('Tdist', () => { + it('Value is normal', () => { + const x = NumberValueObject.create(1); + const degFreedom = NumberValueObject.create(2); + const tails = NumberValueObject.create(1); + const result = testFunction.calculate(x, degFreedom, tails); + expect(getObjectValue(result)).toBe(0.2113248654052009); + }); + + it('DegFreedom value test', () => { + const x = NumberValueObject.create(1); + const degFreedom = NumberValueObject.create(0); + const tails = NumberValueObject.create(1); + const result = testFunction.calculate(x, degFreedom, tails); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const degFreedom2 = NumberValueObject.create(10 ** 10 + 1); + const result2 = testFunction.calculate(x, degFreedom2, tails); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + }); + + it('Cumulative value test', () => { + const x = NumberValueObject.create(1); + const degFreedom = NumberValueObject.create(2); + const tails = NumberValueObject.create(2); + const result = testFunction.calculate(x, degFreedom, tails); + expect(getObjectValue(result)).toBe(0.4226497308104018); + + const tails2 = NumberValueObject.create(0); + const result2 = testFunction.calculate(x, degFreedom, tails2); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + }); + + it('Value is normal string', () => { + const x = StringValueObject.create('test'); + const degFreedom = NumberValueObject.create(2); + const tails = NumberValueObject.create(1); + const result = testFunction.calculate(x, degFreedom, tails); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const x = BooleanValueObject.create(true); + const degFreedom = NumberValueObject.create(2); + const tails = NumberValueObject.create(1); + const result = testFunction.calculate(x, degFreedom, tails); + expect(getObjectValue(result)).toBe(0.2113248654052009); + }); + + it('Value is null', () => { + const x = NullValueObject.create(); + const degFreedom = NumberValueObject.create(2); + const tails = NumberValueObject.create(1); + const result = testFunction.calculate(x, degFreedom, tails); + expect(getObjectValue(result)).toBe(0.5); + }); + + it('Value is error', () => { + const x = ErrorValueObject.create(ErrorType.NAME); + const degFreedom = NumberValueObject.create(2); + const tails = NumberValueObject.create(1); + const result = testFunction.calculate(x, degFreedom, tails); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(1); + const degFreedom2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, degFreedom2, tails); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const tails2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(x2, degFreedom, tails2); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const x = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const degFreedom = NumberValueObject.create(2); + const tails = NumberValueObject.create(1); + const result = testFunction.calculate(x, degFreedom, tails); + expect(getObjectValue(result)).toStrictEqual([ + [0.2113248654052009, ErrorType.VALUE, 0.1718728077748428, 0.2113248654052009, 0.5, 0.5], + [0.5, 0.00004999250124977886, 0.07207975447515451, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + }); + + it('More test', () => { + const x = NumberValueObject.create(0.1); + const degFreedom = NumberValueObject.create(900000000); + const tails = NumberValueObject.create(1); + const result = testFunction.calculate(x, degFreedom, tails); + expect(getObjectValue(result)).toBe(0.4601721457389526); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/compatibility/tdist/index.ts b/packages/engine-formula/src/functions/compatibility/tdist/index.ts new file mode 100644 index 000000000000..1d692528e630 --- /dev/null +++ b/packages/engine-formula/src/functions/compatibility/tdist/index.ts @@ -0,0 +1,111 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { studentTCDF } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Tdist extends BaseFunction { + override minParams = 3; + + override maxParams = 3; + + override calculate( + x: BaseValueObject, + degFreedom: BaseValueObject, + tails: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getRowCount() : 1, + degFreedom.isArray() ? (degFreedom as ArrayValueObject).getRowCount() : 1, + tails.isArray() ? (tails as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getColumnCount() : 1, + degFreedom.isArray() ? (degFreedom as ArrayValueObject).getColumnCount() : 1, + tails.isArray() ? (tails as ArrayValueObject).getColumnCount() : 1 + ); + + const xArray = expandArrayValueObject(maxRowLength, maxColumnLength, x, ErrorValueObject.create(ErrorType.NA)); + const degFreedomArray = expandArrayValueObject(maxRowLength, maxColumnLength, degFreedom, ErrorValueObject.create(ErrorType.NA)); + const tailsArray = expandArrayValueObject(maxRowLength, maxColumnLength, tails, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = xArray.mapValue((xObject, rowIndex, columnIndex) => { + const degFreedomObject = degFreedomArray.get(rowIndex, columnIndex) as BaseValueObject; + const tailsObject = tailsArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (xObject.isError()) { + return xObject; + } + + if (degFreedomObject.isError()) { + return degFreedomObject; + } + + if (tailsObject.isError()) { + return tailsObject; + } + + return this._handleSignleObject(xObject, degFreedomObject, tailsObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + xObject: BaseValueObject, + degFreedomObject: BaseValueObject, + tailsObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(xObject, degFreedomObject, tailsObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_xObject, _degFreedomObject, _tailsObject] = variants as BaseValueObject[]; + + const xValue = +_xObject.getValue(); + const degFreedomValue = Math.floor(+_degFreedomObject.getValue()); + const tailsValue = Math.floor(+_tailsObject.getValue()); + + if (xValue < 0 || degFreedomValue < 1 || degFreedomValue > 10 ** 10 || tailsValue < 1 || tailsValue > 2) { + return ErrorValueObject.create(ErrorType.NUM); + } + + let result = studentTCDF(-xValue, degFreedomValue); + + if (tailsValue === 2) { + result *= 2; + } + + if (Number.isNaN(result) || !Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/lookup/lookup/index.ts b/packages/engine-formula/src/functions/lookup/lookup/index.ts index 07f6a146859d..f727c36ab489 100644 --- a/packages/engine-formula/src/functions/lookup/lookup/index.ts +++ b/packages/engine-formula/src/functions/lookup/lookup/index.ts @@ -16,11 +16,11 @@ import type { Nullable } from '@univerjs/core'; -import { ErrorType } from '../../../basics/error-type'; +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { ErrorType } from '../../../basics/error-type'; import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; export class Lookup extends BaseFunction { override minParams = 2; diff --git a/packages/engine-formula/src/functions/math/mmult/index.ts b/packages/engine-formula/src/functions/math/mmult/index.ts index cea4bead8ee7..7021cadce710 100644 --- a/packages/engine-formula/src/functions/math/mmult/index.ts +++ b/packages/engine-formula/src/functions/math/mmult/index.ts @@ -15,6 +15,7 @@ */ import { ErrorType } from '../../../basics/error-type'; +import { calculateMmult } from '../../../basics/math'; import { ArrayValueObject } from '../../../engine/value-object/array-value-object'; import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { BaseFunction } from '../../base-function'; @@ -46,7 +47,7 @@ export class Mmult extends BaseFunction { return matrix2; } - const result = this._getResult(matrix1, matrix2, array1RowCount, array1ColumnCount, array2ColumnCount); + const result = calculateMmult(matrix1, matrix2); return ArrayValueObject.createByArray(result); } @@ -86,28 +87,4 @@ export class Mmult extends BaseFunction { return matrix; } - - private _getResult( - matrix1: number[][], - matrix2: number[][], - array1RowCount: number, - array1ColumnCount: number, - array2ColumnCount: number - ): number[][] { - const result = Array.from({ length: array1RowCount }, () => new Array(array2ColumnCount).fill(0)); - - for (let r = 0; r < array1RowCount; r++) { - for (let c = 0; c < array2ColumnCount; c++) { - let value = 0; - - for (let k = 0; k < array1ColumnCount; k++) { - value += matrix1[r][k] * matrix2[k][c]; - } - - result[r][c] = value; - } - } - - return result; - } } diff --git a/packages/engine-formula/src/functions/statistical/beta-dist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/beta-dist/__tests__/index.spec.ts index d7e4a689d8ac..4693956fca36 100644 --- a/packages/engine-formula/src/functions/statistical/beta-dist/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/beta-dist/__tests__/index.spec.ts @@ -167,6 +167,27 @@ describe('Test betaDist function', () => { const B = NumberValueObject.create(3); const result = testFunction.calculate(x, alpha, beta, cumulative, A, B); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(2); + const alpha2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, alpha2, beta, cumulative, A, B); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const beta2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(x2, alpha, beta2, cumulative, A, B); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const cumulative2 = ErrorValueObject.create(ErrorType.NAME); + const result4 = testFunction.calculate(x2, alpha, beta, cumulative2, A, B); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); + + const A2 = ErrorValueObject.create(ErrorType.NAME); + const result5 = testFunction.calculate(x2, alpha, beta, cumulative, A2, B); + expect(getObjectValue(result5)).toBe(ErrorType.NAME); + + const B2 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(x2, alpha, beta, cumulative, A, B2); + expect(getObjectValue(result6)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/beta-dist/index.ts b/packages/engine-formula/src/functions/statistical/beta-dist/index.ts index 522dd30ec0a8..c29aba0f027c 100644 --- a/packages/engine-formula/src/functions/statistical/beta-dist/index.ts +++ b/packages/engine-formula/src/functions/statistical/beta-dist/index.ts @@ -97,6 +97,30 @@ export class BetaDist extends BaseFunction { AObject: BaseValueObject, BObject: BaseValueObject ): BaseValueObject { + if (xObject.isError()) { + return xObject; + } + + if (alphaObject.isError()) { + return alphaObject; + } + + if (betaObject.isError()) { + return betaObject; + } + + if (cumulativeObject.isError()) { + return cumulativeObject; + } + + if (AObject.isError()) { + return AObject; + } + + if (BObject.isError()) { + return BObject; + } + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(xObject, alphaObject, betaObject, cumulativeObject, AObject, BObject); if (isError) { diff --git a/packages/engine-formula/src/functions/statistical/beta-inv/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/beta-inv/__tests__/index.spec.ts index cb46b8445601..a31d4ed40169 100644 --- a/packages/engine-formula/src/functions/statistical/beta-inv/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/beta-inv/__tests__/index.spec.ts @@ -140,6 +140,23 @@ describe('Test betaInv function', () => { const B = NumberValueObject.create(3); const result = testFunction.calculate(probability, alpha, beta, A, B); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const probability2 = NumberValueObject.create(0.685470581); + const alpha2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(probability2, alpha2, beta, A, B); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const beta2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(probability2, alpha, beta2, A, B); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const A2 = ErrorValueObject.create(ErrorType.NAME); + const result4 = testFunction.calculate(probability2, alpha, beta, A2, B); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); + + const B2 = ErrorValueObject.create(ErrorType.NAME); + const result5 = testFunction.calculate(probability2, alpha, beta, A, B2); + expect(getObjectValue(result5)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/beta-inv/index.ts b/packages/engine-formula/src/functions/statistical/beta-inv/index.ts index 42009fc281b5..5f055aa828e5 100644 --- a/packages/engine-formula/src/functions/statistical/beta-inv/index.ts +++ b/packages/engine-formula/src/functions/statistical/beta-inv/index.ts @@ -91,6 +91,26 @@ export class BetaInv extends BaseFunction { AObject: BaseValueObject, BObject: BaseValueObject ): BaseValueObject { + if (probabilityObject.isError()) { + return probabilityObject; + } + + if (alphaObject.isError()) { + return alphaObject; + } + + if (betaObject.isError()) { + return betaObject; + } + + if (AObject.isError()) { + return AObject; + } + + if (BObject.isError()) { + return BObject; + } + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(probabilityObject, alphaObject, betaObject, AObject, BObject); if (isError) { diff --git a/packages/engine-formula/src/functions/statistical/binom-dist-range/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/binom-dist-range/__tests__/index.spec.ts index 22d41c7bcb7c..94b5758f365e 100644 --- a/packages/engine-formula/src/functions/statistical/binom-dist-range/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/binom-dist-range/__tests__/index.spec.ts @@ -118,6 +118,18 @@ describe('Test binomDistRange function', () => { const numberS2 = NumberValueObject.create(50); const result = testFunction.calculate(trials, probabilityS, numberS, numberS2); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const trials2 = NumberValueObject.create(60); + const probabilityS2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(trials2, probabilityS2, numberS, numberS2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const numberS3 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(trials2, probabilityS, numberS3, numberS2); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const result4 = testFunction.calculate(trials2, probabilityS, numberS, numberS3); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/binom-dist-range/index.ts b/packages/engine-formula/src/functions/statistical/binom-dist-range/index.ts index 013e1a5bec89..9ceec1e95c5d 100644 --- a/packages/engine-formula/src/functions/statistical/binom-dist-range/index.ts +++ b/packages/engine-formula/src/functions/statistical/binom-dist-range/index.ts @@ -64,6 +64,22 @@ export class BinomDistRange extends BaseFunction { const numberSObject = numberSArray.get(rowIndex, columnIndex) as BaseValueObject; const numberS2Object = numberS2Array.get(rowIndex, columnIndex) as BaseValueObject; + if (trialsObject.isError()) { + return trialsObject; + } + + if (probabilitySObject.isError()) { + return probabilitySObject; + } + + if (numberSObject.isError()) { + return numberSObject; + } + + if (numberS2Object.isError()) { + return numberS2Object; + } + return this._handleSignleObject(trialsObject, probabilitySObject, numberSObject, numberS2Object); }); diff --git a/packages/engine-formula/src/functions/statistical/binom-dist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/binom-dist/__tests__/index.spec.ts index f102c3f06bfe..c9ea9962ab4b 100644 --- a/packages/engine-formula/src/functions/statistical/binom-dist/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/binom-dist/__tests__/index.spec.ts @@ -118,6 +118,19 @@ describe('Test binomDist function', () => { const cumulative = BooleanValueObject.create(true); const result = testFunction.calculate(numberS, trials, probabilityS, cumulative); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const numberS2 = NumberValueObject.create(6); + const trials2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(numberS2, trials2, probabilityS, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const probabilityS2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(numberS2, trials, probabilityS2, cumulative); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const cumulative2 = ErrorValueObject.create(ErrorType.NAME); + const result4 = testFunction.calculate(numberS2, trials, probabilityS, cumulative2); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/binom-dist/index.ts b/packages/engine-formula/src/functions/statistical/binom-dist/index.ts index 3c30e5871600..36a8eba1b675 100644 --- a/packages/engine-formula/src/functions/statistical/binom-dist/index.ts +++ b/packages/engine-formula/src/functions/statistical/binom-dist/index.ts @@ -58,6 +58,22 @@ export class BinomDist extends BaseFunction { const probabilitySObject = probabilitySArray.get(rowIndex, columnIndex) as BaseValueObject; const cumulativeObject = cumulativeArray.get(rowIndex, columnIndex) as BaseValueObject; + if (numberSObject.isError()) { + return numberSObject; + } + + if (trialsObject.isError()) { + return trialsObject; + } + + if (probabilitySObject.isError()) { + return probabilitySObject; + } + + if (cumulativeObject.isError()) { + return cumulativeObject; + } + return this._handleSignleObject(numberSObject, trialsObject, probabilitySObject, cumulativeObject); }); diff --git a/packages/engine-formula/src/functions/statistical/binom-inv/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/binom-inv/__tests__/index.spec.ts index bbed1edce79c..5df484004b28 100644 --- a/packages/engine-formula/src/functions/statistical/binom-inv/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/binom-inv/__tests__/index.spec.ts @@ -86,6 +86,15 @@ describe('Test binomInv function', () => { const alpha = NumberValueObject.create(0.75); const result = testFunction.calculate(trials, probabilityS, alpha); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const trials2 = NumberValueObject.create(6); + const probabilityS2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(trials2, probabilityS2, alpha); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const alpha2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(trials2, probabilityS, alpha2); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/binom-inv/index.ts b/packages/engine-formula/src/functions/statistical/binom-inv/index.ts index b8216861dc63..0ad61bdeb69b 100644 --- a/packages/engine-formula/src/functions/statistical/binom-inv/index.ts +++ b/packages/engine-formula/src/functions/statistical/binom-inv/index.ts @@ -53,6 +53,18 @@ export class BinomInv extends BaseFunction { const probabilitySObject = probabilitySArray.get(rowIndex, columnIndex) as BaseValueObject; const alphaObject = alphaArray.get(rowIndex, columnIndex) as BaseValueObject; + if (trialsObject.isError()) { + return trialsObject; + } + + if (probabilitySObject.isError()) { + return probabilitySObject; + } + + if (alphaObject.isError()) { + return alphaObject; + } + return this._handleSignleObject(trialsObject, probabilitySObject, alphaObject); }); diff --git a/packages/engine-formula/src/functions/statistical/chisq-dist-rt/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/chisq-dist-rt/__tests__/index.spec.ts index f9da9a22b3ed..cf54570d003f 100644 --- a/packages/engine-formula/src/functions/statistical/chisq-dist-rt/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/chisq-dist-rt/__tests__/index.spec.ts @@ -72,6 +72,11 @@ describe('Test chisqDistRt function', () => { const degFreedom = NumberValueObject.create(1); const result = testFunction.calculate(x, degFreedom); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(0.5); + const degFreedom2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, degFreedom2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/chisq-dist-rt/index.ts b/packages/engine-formula/src/functions/statistical/chisq-dist-rt/index.ts index 0a4305155c43..bf70007989eb 100644 --- a/packages/engine-formula/src/functions/statistical/chisq-dist-rt/index.ts +++ b/packages/engine-formula/src/functions/statistical/chisq-dist-rt/index.ts @@ -48,6 +48,14 @@ export class ChisqDistRt extends BaseFunction { const resultArray = xArray.mapValue((xObject, rowIndex, columnIndex) => { const degFreedomObject = degFreedomArray.get(rowIndex, columnIndex) as BaseValueObject; + if (xObject.isError()) { + return xObject; + } + + if (degFreedomObject.isError()) { + return degFreedomObject; + } + return this._handleSignleObject(xObject, degFreedomObject); }); diff --git a/packages/engine-formula/src/functions/statistical/chisq-dist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/chisq-dist/__tests__/index.spec.ts index bc84021835ac..80819876f6a5 100644 --- a/packages/engine-formula/src/functions/statistical/chisq-dist/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/chisq-dist/__tests__/index.spec.ts @@ -91,6 +91,15 @@ describe('Test chisqDist function', () => { const cumulative = BooleanValueObject.create(true); const result = testFunction.calculate(x, degFreedom, cumulative); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(0.5); + const degFreedom2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, degFreedom2, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const cumulative2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(x2, degFreedom, cumulative2); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/chisq-dist/index.ts b/packages/engine-formula/src/functions/statistical/chisq-dist/index.ts index 15f707110153..4f48fdf0f16e 100644 --- a/packages/engine-formula/src/functions/statistical/chisq-dist/index.ts +++ b/packages/engine-formula/src/functions/statistical/chisq-dist/index.ts @@ -53,6 +53,18 @@ export class ChisqDist extends BaseFunction { const degFreedomObject = degFreedomArray.get(rowIndex, columnIndex) as BaseValueObject; const cumulativeObject = cumulativeArray.get(rowIndex, columnIndex) as BaseValueObject; + if (xObject.isError()) { + return xObject; + } + + if (degFreedomObject.isError()) { + return degFreedomObject; + } + + if (cumulativeObject.isError()) { + return cumulativeObject; + } + return this._handleSignleObject(xObject, degFreedomObject, cumulativeObject); }); diff --git a/packages/engine-formula/src/functions/statistical/chisq-inv-rt/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/chisq-inv-rt/__tests__/index.spec.ts index 0df353c24971..432793ff54f1 100644 --- a/packages/engine-formula/src/functions/statistical/chisq-inv-rt/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/chisq-inv-rt/__tests__/index.spec.ts @@ -54,7 +54,7 @@ describe('Test chisqInvRt function', () => { const degFreedom2 = NumberValueObject.create(10 ** 10 + 1); const result2 = testFunction.calculate(probability, degFreedom2); - expect(getObjectValue(result2)).toBe(10000000002.186049); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); }); it('Value is normal string', () => { @@ -83,6 +83,11 @@ describe('Test chisqInvRt function', () => { const degFreedom = NumberValueObject.create(1); const result = testFunction.calculate(probability, degFreedom); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const probability2 = NumberValueObject.create(0.5); + const degFreedom2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(probability2, degFreedom2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/chisq-inv-rt/index.ts b/packages/engine-formula/src/functions/statistical/chisq-inv-rt/index.ts index 63d1b2b0875b..26192d4a358c 100644 --- a/packages/engine-formula/src/functions/statistical/chisq-inv-rt/index.ts +++ b/packages/engine-formula/src/functions/statistical/chisq-inv-rt/index.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; import { ErrorType } from '../../../basics/error-type'; import { chisquareINV } from '../../../basics/statistical'; import { expandArrayValueObject } from '../../../engine/utils/array-object'; @@ -21,7 +22,6 @@ import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check- import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; import { NumberValueObject } from '../../../engine/value-object/primitive-object'; import { BaseFunction } from '../../base-function'; -import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; export class ChisqInvRt extends BaseFunction { override minParams = 2; @@ -48,6 +48,14 @@ export class ChisqInvRt extends BaseFunction { const resultArray = probabilityArray.mapValue((probabilityObject, rowIndex, columnIndex) => { const degFreedomObject = degFreedomArray.get(rowIndex, columnIndex) as BaseValueObject; + if (probabilityObject.isError()) { + return probabilityObject; + } + + if (degFreedomObject.isError()) { + return degFreedomObject; + } + return this._handleSignleObject(probabilityObject, degFreedomObject); }); @@ -73,7 +81,7 @@ export class ChisqInvRt extends BaseFunction { const probabilityValue = +_probabilityObject.getValue(); const degFreedomValue = Math.floor(+_degFreedomObject.getValue()); - if (probabilityValue < 0 || probabilityValue > 1 || degFreedomValue < 1) { + if (probabilityValue < 0 || probabilityValue > 1 || degFreedomValue < 1 || degFreedomValue > 10 ** 10) { return ErrorValueObject.create(ErrorType.NUM); } diff --git a/packages/engine-formula/src/functions/statistical/chisq-inv/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/chisq-inv/__tests__/index.spec.ts index d7642023977f..44f267219744 100644 --- a/packages/engine-formula/src/functions/statistical/chisq-inv/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/chisq-inv/__tests__/index.spec.ts @@ -93,6 +93,11 @@ describe('Test chisqInv function', () => { const degFreedom = NumberValueObject.create(1); const result = testFunction.calculate(probability, degFreedom); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const probability2 = NumberValueObject.create(0.5); + const degFreedom2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(probability2, degFreedom2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/chisq-inv/index.ts b/packages/engine-formula/src/functions/statistical/chisq-inv/index.ts index 7a3d569de15c..4a01b390c6fc 100644 --- a/packages/engine-formula/src/functions/statistical/chisq-inv/index.ts +++ b/packages/engine-formula/src/functions/statistical/chisq-inv/index.ts @@ -48,6 +48,14 @@ export class ChisqInv extends BaseFunction { const resultArray = probabilityArray.mapValue((probabilityObject, rowIndex, columnIndex) => { const degFreedomObject = degFreedomArray.get(rowIndex, columnIndex) as BaseValueObject; + if (probabilityObject.isError()) { + return probabilityObject; + } + + if (degFreedomObject.isError()) { + return degFreedomObject; + } + return this._handleSignleObject(probabilityObject, degFreedomObject); }); diff --git a/packages/engine-formula/src/functions/statistical/confidence-norm/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/confidence-norm/__tests__/index.spec.ts index 5d05d42c309c..5ba678ac6129 100644 --- a/packages/engine-formula/src/functions/statistical/confidence-norm/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/confidence-norm/__tests__/index.spec.ts @@ -94,6 +94,15 @@ describe('Test confidenceNorm function', () => { const size = NumberValueObject.create(50); const result = testFunction.calculate(alpha, standardDev, size); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const alpha2 = NumberValueObject.create(0.05); + const standardDev2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(alpha2, standardDev2, size); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const size2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(alpha2, standardDev, size2); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/confidence-norm/index.ts b/packages/engine-formula/src/functions/statistical/confidence-norm/index.ts index 7afec78da5f7..d6f62fb91f9b 100644 --- a/packages/engine-formula/src/functions/statistical/confidence-norm/index.ts +++ b/packages/engine-formula/src/functions/statistical/confidence-norm/index.ts @@ -49,6 +49,18 @@ export class ConfidenceNorm extends BaseFunction { const standardDevObject = standardDevArray.get(rowIndex, columnIndex) as BaseValueObject; const sizeObject = sizeArray.get(rowIndex, columnIndex) as BaseValueObject; + if (alphaObject.isError()) { + return alphaObject; + } + + if (standardDevObject.isError()) { + return standardDevObject; + } + + if (sizeObject.isError()) { + return sizeObject; + } + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(alphaObject, standardDevObject, sizeObject); if (isError) { diff --git a/packages/engine-formula/src/functions/statistical/confidence-t/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/confidence-t/__tests__/index.spec.ts index 1bfd8d852e7b..7d9b25d69219 100644 --- a/packages/engine-formula/src/functions/statistical/confidence-t/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/confidence-t/__tests__/index.spec.ts @@ -98,6 +98,15 @@ describe('Test confidenceT function', () => { const size = NumberValueObject.create(50); const result = testFunction.calculate(alpha, standardDev, size); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const alpha2 = NumberValueObject.create(0.05); + const standardDev2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(alpha2, standardDev2, size); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const size2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(alpha2, standardDev, size2); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/confidence-t/index.ts b/packages/engine-formula/src/functions/statistical/confidence-t/index.ts index 9a865fcd0da7..2f02099ab838 100644 --- a/packages/engine-formula/src/functions/statistical/confidence-t/index.ts +++ b/packages/engine-formula/src/functions/statistical/confidence-t/index.ts @@ -49,6 +49,18 @@ export class ConfidenceT extends BaseFunction { const standardDevObject = standardDevArray.get(rowIndex, columnIndex) as BaseValueObject; const sizeObject = sizeArray.get(rowIndex, columnIndex) as BaseValueObject; + if (alphaObject.isError()) { + return alphaObject; + } + + if (standardDevObject.isError()) { + return standardDevObject; + } + + if (sizeObject.isError()) { + return sizeObject; + } + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(alphaObject, standardDevObject, sizeObject); if (isError) { diff --git a/packages/engine-formula/src/functions/statistical/expon-dist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/expon-dist/__tests__/index.spec.ts index de2a13b44da6..d888075ab06e 100644 --- a/packages/engine-formula/src/functions/statistical/expon-dist/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/expon-dist/__tests__/index.spec.ts @@ -86,6 +86,15 @@ describe('Test exponDist function', () => { const cumulative = BooleanValueObject.create(true); const result = testFunction.calculate(x, lambda, cumulative); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(0.5); + const lambda2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, lambda2, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const cumulative2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(x2, lambda, cumulative2); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/expon-dist/index.ts b/packages/engine-formula/src/functions/statistical/expon-dist/index.ts index a353429037c9..30d097d91b85 100644 --- a/packages/engine-formula/src/functions/statistical/expon-dist/index.ts +++ b/packages/engine-formula/src/functions/statistical/expon-dist/index.ts @@ -53,6 +53,18 @@ export class ExponDist extends BaseFunction { const lambdaObject = lambdaArray.get(rowIndex, columnIndex) as BaseValueObject; const cumulativeObject = cumulativeArray.get(rowIndex, columnIndex) as BaseValueObject; + if (xObject.isError()) { + return xObject; + } + + if (lambdaObject.isError()) { + return lambdaObject; + } + + if (cumulativeObject.isError()) { + return cumulativeObject; + } + return this._handleSignleObject(xObject, lambdaObject, cumulativeObject); }); diff --git a/packages/engine-formula/src/functions/statistical/f-dist-rt/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/f-dist-rt/__tests__/index.spec.ts index 029358b9c82a..664ef088dade 100644 --- a/packages/engine-formula/src/functions/statistical/f-dist-rt/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/f-dist-rt/__tests__/index.spec.ts @@ -78,6 +78,14 @@ describe('Test fDistRt function', () => { const degFreedom2 = NumberValueObject.create(4); const result = testFunction.calculate(x, degFreedom1, degFreedom2); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(15.2069); + const degFreedom3 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, degFreedom3, degFreedom2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const result3 = testFunction.calculate(x2, degFreedom1, degFreedom3); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/f-dist-rt/index.ts b/packages/engine-formula/src/functions/statistical/f-dist-rt/index.ts index ae93830a96bf..ca741474ba2f 100644 --- a/packages/engine-formula/src/functions/statistical/f-dist-rt/index.ts +++ b/packages/engine-formula/src/functions/statistical/f-dist-rt/index.ts @@ -53,6 +53,18 @@ export class FDistRt extends BaseFunction { const degFreedom1Object = degFreedom1Array.get(rowIndex, columnIndex) as BaseValueObject; const degFreedom2Object = degFreedom2Array.get(rowIndex, columnIndex) as BaseValueObject; + if (xObject.isError()) { + return xObject; + } + + if (degFreedom1Object.isError()) { + return degFreedom1Object; + } + + if (degFreedom2Object.isError()) { + return degFreedom2Object; + } + return this._handleSignleObject(xObject, degFreedom1Object, degFreedom2Object); }); diff --git a/packages/engine-formula/src/functions/statistical/f-dist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/f-dist/__tests__/index.spec.ts index 76bf2cc67bd9..a6f6cb88f274 100644 --- a/packages/engine-formula/src/functions/statistical/f-dist/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/f-dist/__tests__/index.spec.ts @@ -105,6 +105,18 @@ describe('Test fDist function', () => { const cumulative = BooleanValueObject.create(true); const result = testFunction.calculate(x, degFreedom1, degFreedom2, cumulative); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(15.2069); + const degFreedom3 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, degFreedom3, degFreedom2, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const result3 = testFunction.calculate(x2, degFreedom1, degFreedom3, cumulative); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const cumulative2 = ErrorValueObject.create(ErrorType.NAME); + const result4 = testFunction.calculate(x2, degFreedom1, degFreedom2, cumulative2); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/f-dist/index.ts b/packages/engine-formula/src/functions/statistical/f-dist/index.ts index 84058126531a..4fb02bf41264 100644 --- a/packages/engine-formula/src/functions/statistical/f-dist/index.ts +++ b/packages/engine-formula/src/functions/statistical/f-dist/index.ts @@ -58,6 +58,22 @@ export class FDist extends BaseFunction { const degFreedom2Object = degFreedom2Array.get(rowIndex, columnIndex) as BaseValueObject; const cumulativeObject = cumulativeArray.get(rowIndex, columnIndex) as BaseValueObject; + if (xObject.isError()) { + return xObject; + } + + if (degFreedom1Object.isError()) { + return degFreedom1Object; + } + + if (degFreedom2Object.isError()) { + return degFreedom2Object; + } + + if (cumulativeObject.isError()) { + return cumulativeObject; + } + return this._handleSignleObject(xObject, degFreedom1Object, degFreedom2Object, cumulativeObject); }); diff --git a/packages/engine-formula/src/functions/statistical/f-inv-rt/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/f-inv-rt/__tests__/index.spec.ts index d657f22c4808..20991e55bbf2 100644 --- a/packages/engine-formula/src/functions/statistical/f-inv-rt/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/f-inv-rt/__tests__/index.spec.ts @@ -78,6 +78,14 @@ describe('Test fInvRt function', () => { const degFreedom2 = NumberValueObject.create(4); const result = testFunction.calculate(probability, degFreedom1, degFreedom2); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const probability2 = NumberValueObject.create(0.01); + const degFreedom3 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(probability2, degFreedom3, degFreedom2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const result3 = testFunction.calculate(probability2, degFreedom1, degFreedom3); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/f-inv-rt/index.ts b/packages/engine-formula/src/functions/statistical/f-inv-rt/index.ts index e56550bbf89f..2cc0772c9739 100644 --- a/packages/engine-formula/src/functions/statistical/f-inv-rt/index.ts +++ b/packages/engine-formula/src/functions/statistical/f-inv-rt/index.ts @@ -53,6 +53,18 @@ export class FInvRt extends BaseFunction { const degFreedom1Object = degFreedom1Array.get(rowIndex, columnIndex) as BaseValueObject; const degFreedom2Object = degFreedom2Array.get(rowIndex, columnIndex) as BaseValueObject; + if (probabilityObject.isError()) { + return probabilityObject; + } + + if (degFreedom1Object.isError()) { + return degFreedom1Object; + } + + if (degFreedom2Object.isError()) { + return degFreedom2Object; + } + return this._handleSignleObject(probabilityObject, degFreedom1Object, degFreedom2Object); }); diff --git a/packages/engine-formula/src/functions/statistical/f-inv/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/f-inv/__tests__/index.spec.ts index 810c18c5e012..ebff1e8af9d1 100644 --- a/packages/engine-formula/src/functions/statistical/f-inv/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/f-inv/__tests__/index.spec.ts @@ -78,6 +78,14 @@ describe('Test fInv function', () => { const degFreedom2 = NumberValueObject.create(4); const result = testFunction.calculate(probability, degFreedom1, degFreedom2); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const probability2 = NumberValueObject.create(0.01); + const degFreedom3 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(probability2, degFreedom3, degFreedom2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const result3 = testFunction.calculate(probability2, degFreedom1, degFreedom3); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/f-inv/index.ts b/packages/engine-formula/src/functions/statistical/f-inv/index.ts index 39ef45296deb..18808483527e 100644 --- a/packages/engine-formula/src/functions/statistical/f-inv/index.ts +++ b/packages/engine-formula/src/functions/statistical/f-inv/index.ts @@ -53,6 +53,18 @@ export class FInv extends BaseFunction { const degFreedom1Object = degFreedom1Array.get(rowIndex, columnIndex) as BaseValueObject; const degFreedom2Object = degFreedom2Array.get(rowIndex, columnIndex) as BaseValueObject; + if (probabilityObject.isError()) { + return probabilityObject; + } + + if (degFreedom1Object.isError()) { + return degFreedom1Object; + } + + if (degFreedom2Object.isError()) { + return degFreedom2Object; + } + return this._handleSignleObject(probabilityObject, degFreedom1Object, degFreedom2Object); }); diff --git a/packages/engine-formula/src/functions/statistical/frequency/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/frequency/__tests__/index.spec.ts new file mode 100644 index 000000000000..9e5a5f7f487c --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/frequency/__tests__/index.spec.ts @@ -0,0 +1,322 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { NullValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Frequency } from '../index'; + +describe('Test frequency function', () => { + const testFunction = new Frequency(FUNCTION_NAMES_STATISTICAL.FREQUENCY); + + describe('Frequency', () => { + it('Value is normal', () => { + const dataArray = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [79], + [85], + [78], + [85], + [50], + [81], + [95], + [88], + [97], + ]), + rowCount: 9, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const binsArray = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [70], + [79], + [89], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(dataArray, binsArray); + expect(getObjectValue(result)).toStrictEqual([ + [1], + [2], + [4], + [2], + ]); + }); + + it('BinsArray value order test', () => { + const dataArray = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [79], + [85], + [78], + [85], + [50], + [81], + [95], + [88], + [97], + ]), + rowCount: 9, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const binsArray = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [79], + [70], + [89], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(dataArray, binsArray); + expect(getObjectValue(result)).toStrictEqual([ + [2], + [1], + [4], + [2], + ]); + + const binsArray2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [89], + [79], + [70], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(dataArray, binsArray2); + expect(getObjectValue(result2)).toStrictEqual([ + [4], + [2], + [1], + [2], + ]); + + const binsArray3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [79], + [79], + [79], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result3 = testFunction.calculate(dataArray, binsArray3); + expect(getObjectValue(result3)).toStrictEqual([ + [3], + [0], + [0], + [6], + ]); + }); + + it('Value is error', () => { + const dataArray = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [79], + [85], + [78], + [85], + [50], + [81], + [95], + [88], + [97], + ]), + rowCount: 9, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const binsArray = ErrorValueObject.create(ErrorType.NAME); + const result = testFunction.calculate(dataArray, binsArray); + expect(getObjectValue(result)).toStrictEqual([ + [0], + [9], + ]); + + const dataArray2 = ErrorValueObject.create(ErrorType.NAME); + const binsArray2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [70], + [79], + [89], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(dataArray2, binsArray2); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); + }); + + it('Value is null', () => { + const dataArray = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [79], + [85], + [78], + [85], + [50], + [81], + [95], + [88], + [97], + ]), + rowCount: 9, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const binsArray = NullValueObject.create(); + const result = testFunction.calculate(dataArray, binsArray); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); + + const dataArray2 = NullValueObject.create(); + const binsArray2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [70], + [79], + [89], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(dataArray2, binsArray2); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.VALUE); + + const dataArray3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null], + [null], + [null], + [null], + [null], + [null], + [null], + [null], + [null], + ]), + rowCount: 9, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const binsArray3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null], + [null], + [null], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result3 = testFunction.calculate(dataArray3, binsArray3); + expect(getObjectValue(result3)).toStrictEqual([ + [0], + [0], + ]); + }); + + it('Value ignore string/boolean/blank cell', () => { + const dataArray = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [79], + [85], + [true], + [85], + [false], + [81], + ['test'], + [88], + [null], + ]), + rowCount: 9, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const binsArray = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [true], + [false], + [null], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(dataArray, binsArray); + expect(getObjectValue(result)).toStrictEqual([ + [0], + [5], + ]); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/frequency/index.ts b/packages/engine-formula/src/functions/statistical/frequency/index.ts new file mode 100644 index 000000000000..9351c6b07fc4 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/frequency/index.ts @@ -0,0 +1,139 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { BaseFunction } from '../../base-function'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; + +export class Frequency extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate(dataArray: BaseValueObject, binsArray: BaseValueObject): BaseValueObject { + const { isError, errorObject, values: dataArrayValues } = this._getValues(dataArray); + + if (isError) { + return errorObject as ErrorValueObject; + } + + if (dataArray.isNull() || binsArray.isNull()) { + return ErrorValueObject.create(ErrorType.VALUE); + } + + let { values: binsArrayValues } = this._getValues(binsArray, true); + + if (binsArrayValues.length === 0) { + binsArrayValues = [0]; + } + + const newBinsArrayValues = this._getNewBinsArrayValues(binsArrayValues); + + const result: number[] = new Array(newBinsArrayValues.length).fill(0); + + for (let i = 0; i < dataArrayValues.length; i++) { + const value = dataArrayValues[i]; + + const index = newBinsArrayValues.findIndex((item) => value > item.start && value <= item.end); + + result[index]++; + } + + return ArrayValueObject.createByArray(result.map((item) => [item])); + } + + private _getValues(array: BaseValueObject, isIgnoreError: boolean = false) { + const values: number[] = []; + + const arrayRowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; + const arrayColumnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; + + for (let r = 0; r < arrayRowCount; r++) { + for (let c = 0; c < arrayColumnCount; c++) { + const valueObject = array.isArray() ? (array as ArrayValueObject).get(r, c) as BaseValueObject : array; + + if (valueObject.isError()) { + if (!isIgnoreError) { + return { + isError: true, + errorObject: valueObject as ErrorValueObject, + values, + }; + } + + continue; + } + + if (valueObject.isNull() || valueObject.isBoolean()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + values.push(+value); + } + } + + return { + isError: false, + errorObject: null, + values, + }; + } + + private _getNewBinsArrayValues(binsArrayValues: number[]) { + const _binsArrayValues = binsArrayValues.map((value, index) => { + return { + value, + index, + }; + }).sort((a, b) => a.value - b.value); + + const newBinsArrayValues = []; + + for (let i = 0; i < _binsArrayValues.length; i++) { + const index = _binsArrayValues[i].index; + + if (i === 0) { + newBinsArrayValues[index] = { + start: -Infinity, + end: _binsArrayValues[i].value, + }; + + continue; + } + + newBinsArrayValues[index] = { + start: _binsArrayValues[i - 1].value, + end: _binsArrayValues[i].value, + }; + } + + newBinsArrayValues.push({ + start: _binsArrayValues[_binsArrayValues.length - 1].value, + end: Infinity, + }); + + return newBinsArrayValues; + } +} diff --git a/packages/engine-formula/src/functions/statistical/function-map.ts b/packages/engine-formula/src/functions/statistical/function-map.ts index 89d43778999f..0144e40745ae 100644 --- a/packages/engine-formula/src/functions/statistical/function-map.ts +++ b/packages/engine-formula/src/functions/statistical/function-map.ts @@ -49,28 +49,74 @@ import { FTest } from './f-test'; import { Fisher } from './fisher'; import { Fisherinv } from './fisherinv'; import { Forecast } from './forecast'; +import { Frequency } from './frequency'; import { FUNCTION_NAMES_STATISTICAL } from './function-names'; +import { Gamma } from './gamma'; +import { GammaDist } from './gamma-dist'; +import { GammaInv } from './gamma-inv'; +import { Gammaln } from './gammaln'; +import { Gauss } from './gauss'; +import { Geomean } from './geomean'; +import { Growth } from './growth'; +import { Harmean } from './harmean'; +import { HypgeomDist } from './hypgeom-dist'; import { Intercept } from './intercept'; +import { Kurt } from './kurt'; +import { Large } from './large'; +import { LognormDist } from './lognorm-dist'; +import { LognormInv } from './lognorm-inv'; import { Max } from './max'; import { Maxa } from './maxa'; import { Maxifs } from './maxifs'; +import { Median } from './median'; import { Min } from './min'; import { Mina } from './mina'; import { Minifs } from './minifs'; +import { ModeMult } from './mode-mult'; +import { ModeSngl } from './mode-sngl'; +import { NegbinomDist } from './negbinom-dist'; import { NormDist } from './norm-dist'; import { NormInv } from './norm-inv'; import { NormSDist } from './norm-s-dist'; import { NormSInv } from './norm-s-inv'; +import { Pearson } from './pearson'; +import { PercentileExc } from './percentile-exc'; +import { PercentileInc } from './percentile-inc'; +import { PercentrankExc } from './percentrank-exc'; +import { PercentrankInc } from './percentrank-inc'; +import { Permut } from './permut'; +import { Permutationa } from './permutationa'; +import { Phi } from './phi'; +import { PoissonDist } from './poisson-dist'; +import { Prob } from './prob'; +import { QuartileExc } from './quartile-exc'; +import { QuartileInc } from './quartile-inc'; import { RankAvg } from './rank-avg'; import { RankEq } from './rank-eq'; +import { Rsq } from './rsq'; +import { Skew } from './skew'; +import { SkewP } from './skew-p'; +import { Slope } from './slope'; +import { Small } from './small'; +import { Standardize } from './standardize'; import { StdevP } from './stdev-p'; import { StdevS } from './stdev-s'; import { Stdeva } from './stdeva'; import { Stdevpa } from './stdevpa'; +import { Steyx } from './steyx'; +import { TDist } from './t-dist'; +import { TDist2t } from './t-dist-2t'; +import { TDistRt } from './t-dist-rt'; +import { TInv } from './t-inv'; +import { TInv2t } from './t-inv-2t'; +import { TTest } from './t-test'; +import { Trimmean } from './trimmean'; import { VarP } from './var-p'; import { VarS } from './var-s'; import { Vara } from './vara'; import { Varpa } from './varpa'; +import { WeibullDist } from './weibull-dist'; +import { ZTest } from './z-test'; export const functionStatistical = [ [Avedev, FUNCTION_NAMES_STATISTICAL.AVEDEV], @@ -109,25 +155,72 @@ export const functionStatistical = [ [Fisherinv, FUNCTION_NAMES_STATISTICAL.FISHERINV], [Forecast, FUNCTION_NAMES_STATISTICAL.FORECAST], [Forecast, FUNCTION_NAMES_STATISTICAL.FORECAST_LINEAR], + [Frequency, FUNCTION_NAMES_STATISTICAL.FREQUENCY], + [Gamma, FUNCTION_NAMES_STATISTICAL.GAMMA], + [GammaDist, FUNCTION_NAMES_STATISTICAL.GAMMA_DIST], + [GammaInv, FUNCTION_NAMES_STATISTICAL.GAMMA_INV], + [Gammaln, FUNCTION_NAMES_STATISTICAL.GAMMALN], + [Gammaln, FUNCTION_NAMES_STATISTICAL.GAMMALN_PRECISE], + [Gauss, FUNCTION_NAMES_STATISTICAL.GAUSS], + [Geomean, FUNCTION_NAMES_STATISTICAL.GEOMEAN], + [Growth, FUNCTION_NAMES_STATISTICAL.GROWTH], + [Harmean, FUNCTION_NAMES_STATISTICAL.HARMEAN], + [HypgeomDist, FUNCTION_NAMES_STATISTICAL.HYPGEOM_DIST], [Intercept, FUNCTION_NAMES_STATISTICAL.INTERCEPT], + [Kurt, FUNCTION_NAMES_STATISTICAL.KURT], + [Large, FUNCTION_NAMES_STATISTICAL.LARGE], + [LognormDist, FUNCTION_NAMES_STATISTICAL.LOGNORM_DIST], + [LognormInv, FUNCTION_NAMES_STATISTICAL.LOGNORM_INV], [Max, FUNCTION_NAMES_STATISTICAL.MAX], [Maxa, FUNCTION_NAMES_STATISTICAL.MAXA], [Maxifs, FUNCTION_NAMES_STATISTICAL.MAXIFS], + [Median, FUNCTION_NAMES_STATISTICAL.MEDIAN], [Min, FUNCTION_NAMES_STATISTICAL.MIN], [Mina, FUNCTION_NAMES_STATISTICAL.MINA], [Minifs, FUNCTION_NAMES_STATISTICAL.MINIFS], + [ModeMult, FUNCTION_NAMES_STATISTICAL.MODE_MULT], + [ModeSngl, FUNCTION_NAMES_STATISTICAL.MODE_SNGL], + [NegbinomDist, FUNCTION_NAMES_STATISTICAL.NEGBINOM_DIST], [NormDist, FUNCTION_NAMES_STATISTICAL.NORM_DIST], [NormInv, FUNCTION_NAMES_STATISTICAL.NORM_INV], [NormSDist, FUNCTION_NAMES_STATISTICAL.NORM_S_DIST], [NormSInv, FUNCTION_NAMES_STATISTICAL.NORM_S_INV], + [Pearson, FUNCTION_NAMES_STATISTICAL.PEARSON], + [PercentileExc, FUNCTION_NAMES_STATISTICAL.PERCENTILE_EXC], + [PercentileInc, FUNCTION_NAMES_STATISTICAL.PERCENTILE_INC], + [PercentrankExc, FUNCTION_NAMES_STATISTICAL.PERCENTRANK_EXC], + [PercentrankInc, FUNCTION_NAMES_STATISTICAL.PERCENTRANK_INC], + [Permut, FUNCTION_NAMES_STATISTICAL.PERMUT], + [Permutationa, FUNCTION_NAMES_STATISTICAL.PERMUTATIONA], + [Phi, FUNCTION_NAMES_STATISTICAL.PHI], + [PoissonDist, FUNCTION_NAMES_STATISTICAL.POISSON_DIST], + [Prob, FUNCTION_NAMES_STATISTICAL.PROB], + [QuartileExc, FUNCTION_NAMES_STATISTICAL.QUARTILE_EXC], + [QuartileInc, FUNCTION_NAMES_STATISTICAL.QUARTILE_INC], [RankAvg, FUNCTION_NAMES_STATISTICAL.RANK_AVG], [RankEq, FUNCTION_NAMES_STATISTICAL.RANK_EQ], + [Rsq, FUNCTION_NAMES_STATISTICAL.RSQ], + [Skew, FUNCTION_NAMES_STATISTICAL.SKEW], + [SkewP, FUNCTION_NAMES_STATISTICAL.SKEW_P], + [Slope, FUNCTION_NAMES_STATISTICAL.SLOPE], + [Small, FUNCTION_NAMES_STATISTICAL.SMALL], + [Standardize, FUNCTION_NAMES_STATISTICAL.STANDARDIZE], [StdevP, FUNCTION_NAMES_STATISTICAL.STDEV_P], [StdevS, FUNCTION_NAMES_STATISTICAL.STDEV_S], [Stdeva, FUNCTION_NAMES_STATISTICAL.STDEVA], [Stdevpa, FUNCTION_NAMES_STATISTICAL.STDEVPA], + [Steyx, FUNCTION_NAMES_STATISTICAL.STEYX], + [TDist, FUNCTION_NAMES_STATISTICAL.T_DIST], + [TDist2t, FUNCTION_NAMES_STATISTICAL.T_DIST_2T], + [TDistRt, FUNCTION_NAMES_STATISTICAL.T_DIST_RT], + [TInv, FUNCTION_NAMES_STATISTICAL.T_INV], + [TInv2t, FUNCTION_NAMES_STATISTICAL.T_INV_2T], + [TTest, FUNCTION_NAMES_STATISTICAL.T_TEST], + [Trimmean, FUNCTION_NAMES_STATISTICAL.TRIMMEAN], [VarP, FUNCTION_NAMES_STATISTICAL.VAR_P], [VarS, FUNCTION_NAMES_STATISTICAL.VAR_S], [Vara, FUNCTION_NAMES_STATISTICAL.VARA], [Varpa, FUNCTION_NAMES_STATISTICAL.VARPA], + [WeibullDist, FUNCTION_NAMES_STATISTICAL.WEIBULL_DIST], + [ZTest, FUNCTION_NAMES_STATISTICAL.Z_TEST], ]; diff --git a/packages/engine-formula/src/functions/statistical/gamma-dist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/gamma-dist/__tests__/index.spec.ts new file mode 100644 index 000000000000..39651dcd03dd --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/gamma-dist/__tests__/index.spec.ts @@ -0,0 +1,181 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { GammaDist } from '../index'; + +describe('Test gammaDist function', () => { + const testFunction = new GammaDist(FUNCTION_NAMES_STATISTICAL.GAMMA_DIST); + + describe('GammaDist', () => { + it('Value is normal', () => { + const x = NumberValueObject.create(10); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(0.1333716740699961); + }); + + it('Alpha and beta value test', () => { + const x = NumberValueObject.create(10); + const alpha = NumberValueObject.create(0); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const alpha2 = NumberValueObject.create(8); + const beta2 = NumberValueObject.create(0); + const result2 = testFunction.calculate(x, alpha2, beta2, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + + const alpha3 = NumberValueObject.create(1); + const beta3 = NumberValueObject.create(1); + const result3 = testFunction.calculate(x, alpha3, beta3, cumulative); + expect(getObjectValue(result3)).toBe(0.9999546000702375); + + const alpha4 = NumberValueObject.create(5); + const result4 = testFunction.calculate(x, alpha4, beta, cumulative); + expect(getObjectValue(result4)).toBe(0.5595067149347875); + }); + + it('X value test', () => { + const x = NumberValueObject.create(0); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(0); + + const x2 = NumberValueObject.create(-1); + const result2 = testFunction.calculate(x2, alpha, beta, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + }); + + it('Cumulative value is normal', () => { + const x = NumberValueObject.create(10); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(false); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(0.05222243147852266); + + const alpha2 = NumberValueObject.create(1); + const beta2 = NumberValueObject.create(1); + const result2 = testFunction.calculate(x, alpha2, beta2, cumulative); + expect(getObjectValue(result2)).toBe(0.00004539992976248485); + + const x2 = NumberValueObject.create(3); + const result3 = testFunction.calculate(x2, alpha2, beta2, cumulative); + expect(getObjectValue(result3)).toBe(0.049787068367863944); + + const alpha3 = NumberValueObject.create(520); + const beta3 = NumberValueObject.create(520); + const result4 = testFunction.calculate(x, alpha3, beta3, cumulative); + expect(getObjectValue(result4)).toBe(0); + + const alpha4 = NumberValueObject.create(350); + const beta4 = NumberValueObject.create(350); + const result5 = testFunction.calculate(x, alpha4, beta4, cumulative); + expect(getObjectValue(result5)).toBe(0); + + const alpha5 = NumberValueObject.create(0.1); + const beta5 = NumberValueObject.create(0.1); + const result6 = testFunction.calculate(x, alpha5, beta5, cumulative); + expect(getObjectValue(result6)).toBe(6.197422944912591e-46); + }); + + it('Value is normal string', () => { + const x = StringValueObject.create('test'); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const x = BooleanValueObject.create(true); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(6.219690863728135e-8); + }); + + it('Value is null', () => { + const x = NullValueObject.create(); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(0); + }); + + it('Value is error', () => { + const x = ErrorValueObject.create(ErrorType.NAME); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(10); + const alpha2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, alpha2, beta, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const beta2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(x2, alpha, beta2, cumulative); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const cumulative2 = ErrorValueObject.create(ErrorType.NAME); + const result4 = testFunction.calculate(x2, alpha, beta, cumulative2); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const x = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toStrictEqual([ + [6.219690863728135e-8, ErrorType.VALUE, 2.943752902702369e-7, 6.219690863728135e-8, 0, 0], + [0, 0.9999999999999654, 0.00003100313605738345, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/gamma-dist/index.ts b/packages/engine-formula/src/functions/statistical/gamma-dist/index.ts new file mode 100644 index 000000000000..8fd2b07f2650 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/gamma-dist/index.ts @@ -0,0 +1,120 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ErrorType } from '../../../basics/error-type'; +import { gammaCDF, gammaPDF } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; + +export class GammaDist extends BaseFunction { + override minParams = 4; + + override maxParams = 4; + + override calculate( + x: BaseValueObject, + alpha: BaseValueObject, + beta: BaseValueObject, + cumulative: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getRowCount() : 1, + alpha.isArray() ? (alpha as ArrayValueObject).getRowCount() : 1, + beta.isArray() ? (beta as ArrayValueObject).getRowCount() : 1, + cumulative.isArray() ? (cumulative as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getColumnCount() : 1, + alpha.isArray() ? (alpha as ArrayValueObject).getColumnCount() : 1, + beta.isArray() ? (beta as ArrayValueObject).getColumnCount() : 1, + cumulative.isArray() ? (cumulative as ArrayValueObject).getColumnCount() : 1 + ); + + const xArray = expandArrayValueObject(maxRowLength, maxColumnLength, x, ErrorValueObject.create(ErrorType.NA)); + const alphaArray = expandArrayValueObject(maxRowLength, maxColumnLength, alpha, ErrorValueObject.create(ErrorType.NA)); + const betaArray = expandArrayValueObject(maxRowLength, maxColumnLength, beta, ErrorValueObject.create(ErrorType.NA)); + const cumulativeArray = expandArrayValueObject(maxRowLength, maxColumnLength, cumulative, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = xArray.mapValue((xObject, rowIndex, columnIndex) => { + const alphaObject = alphaArray.get(rowIndex, columnIndex) as BaseValueObject; + const betaObject = betaArray.get(rowIndex, columnIndex) as BaseValueObject; + const cumulativeObject = cumulativeArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (xObject.isError()) { + return xObject; + } + + if (alphaObject.isError()) { + return alphaObject; + } + + if (betaObject.isError()) { + return betaObject; + } + + if (cumulativeObject.isError()) { + return cumulativeObject; + } + + return this._handleSignleObject(xObject, alphaObject, betaObject, cumulativeObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + xObject: BaseValueObject, + alphaObject: BaseValueObject, + betaObject: BaseValueObject, + cumulativeObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(xObject, alphaObject, betaObject, cumulativeObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_xObject, _alphaObject, _betaObject, _cumulativeObject] = variants as BaseValueObject[]; + + const xValue = +_xObject.getValue(); + const alphaValue = +_alphaObject.getValue(); + const betaValue = +_betaObject.getValue(); + const cumulativeValue = +_cumulativeObject.getValue(); + + if (xValue < 0 || alphaValue <= 0 || betaValue <= 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + let result; + + if (cumulativeValue) { + result = gammaCDF(xValue, alphaValue, betaValue); + } else { + result = gammaPDF(xValue, alphaValue, betaValue); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/gamma-inv/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/gamma-inv/__tests__/index.spec.ts new file mode 100644 index 000000000000..5b15e68c7962 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/gamma-inv/__tests__/index.spec.ts @@ -0,0 +1,132 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { GammaInv } from '../index'; + +describe('Test gammaInv function', () => { + const testFunction = new GammaInv(FUNCTION_NAMES_STATISTICAL.GAMMA_INV); + + describe('GammaInv', () => { + it('Value is normal', () => { + const probability = NumberValueObject.create(0.068094); + const alpha = NumberValueObject.create(9); + const beta = NumberValueObject.create(2); + const result = testFunction.calculate(probability, alpha, beta); + expect(getObjectValue(result)).toBe(10.00001119143767); + }); + + it('Alpha and beta value test', () => { + const probability = NumberValueObject.create(0.068094); + const alpha = NumberValueObject.create(0); + const beta = NumberValueObject.create(2); + const result = testFunction.calculate(probability, alpha, beta); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const alpha2 = NumberValueObject.create(9); + const beta2 = NumberValueObject.create(0); + const result2 = testFunction.calculate(probability, alpha2, beta2); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + + const alpha3 = NumberValueObject.create(1); + const beta3 = NumberValueObject.create(1); + const result3 = testFunction.calculate(probability, alpha3, beta3); + expect(getObjectValue(result3)).toBe(0.07052332775219192); + }); + + it('Probability value test', () => { + const probability = NumberValueObject.create(0); + const alpha = NumberValueObject.create(9); + const beta = NumberValueObject.create(2); + const result = testFunction.calculate(probability, alpha, beta); + expect(getObjectValue(result)).toBe(0); + + const probability2 = NumberValueObject.create(1); + const result2 = testFunction.calculate(probability2, alpha, beta); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + }); + + it('Value is normal string', () => { + const probability = StringValueObject.create('test'); + const alpha = NumberValueObject.create(9); + const beta = NumberValueObject.create(2); + const result = testFunction.calculate(probability, alpha, beta); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const probability = BooleanValueObject.create(true); + const alpha = NumberValueObject.create(9); + const beta = NumberValueObject.create(2); + const result = testFunction.calculate(probability, alpha, beta); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Value is null', () => { + const probability = NullValueObject.create(); + const alpha = NumberValueObject.create(9); + const beta = NumberValueObject.create(2); + const result = testFunction.calculate(probability, alpha, beta); + expect(getObjectValue(result)).toBe(0); + }); + + it('Value is error', () => { + const probability = ErrorValueObject.create(ErrorType.NAME); + const alpha = NumberValueObject.create(9); + const beta = NumberValueObject.create(2); + const result = testFunction.calculate(probability, alpha, beta); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const probability2 = NumberValueObject.create(0.068094); + const alpha2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(probability2, alpha2, beta); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const beta2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(probability2, alpha, beta2); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const probability = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const alpha = NumberValueObject.create(9); + const beta = NumberValueObject.create(2); + const result = testFunction.calculate(probability, alpha, beta); + expect(getObjectValue(result)).toStrictEqual([ + [ErrorType.NUM, ErrorType.VALUE, ErrorType.NUM, ErrorType.NUM, 0, 0], + [0, ErrorType.NUM, ErrorType.NUM, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/gamma-inv/index.ts b/packages/engine-formula/src/functions/statistical/gamma-inv/index.ts new file mode 100644 index 000000000000..34370c26793b --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/gamma-inv/index.ts @@ -0,0 +1,107 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { gammaINV } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class GammaInv extends BaseFunction { + override minParams = 3; + + override maxParams = 3; + + override calculate( + probability: BaseValueObject, + alpha: BaseValueObject, + beta: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + probability.isArray() ? (probability as ArrayValueObject).getRowCount() : 1, + alpha.isArray() ? (alpha as ArrayValueObject).getRowCount() : 1, + beta.isArray() ? (beta as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + probability.isArray() ? (probability as ArrayValueObject).getColumnCount() : 1, + alpha.isArray() ? (alpha as ArrayValueObject).getColumnCount() : 1, + beta.isArray() ? (beta as ArrayValueObject).getColumnCount() : 1 + ); + + const probabilityArray = expandArrayValueObject(maxRowLength, maxColumnLength, probability, ErrorValueObject.create(ErrorType.NA)); + const alphaArray = expandArrayValueObject(maxRowLength, maxColumnLength, alpha, ErrorValueObject.create(ErrorType.NA)); + const betaArray = expandArrayValueObject(maxRowLength, maxColumnLength, beta, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = probabilityArray.mapValue((probabilityObject, rowIndex, columnIndex) => { + const alphaObject = alphaArray.get(rowIndex, columnIndex) as BaseValueObject; + const betaObject = betaArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (probabilityObject.isError()) { + return probabilityObject; + } + + if (alphaObject.isError()) { + return alphaObject; + } + + if (betaObject.isError()) { + return betaObject; + } + + return this._handleSignleObject(probabilityObject, alphaObject, betaObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + probabilityObject: BaseValueObject, + alphaObject: BaseValueObject, + betaObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(probabilityObject, alphaObject, betaObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_probabilityObject, _alphaObject, _betaObject] = variants as BaseValueObject[]; + + const probabilityValue = +_probabilityObject.getValue(); + const alphaValue = +_alphaObject.getValue(); + const betaValue = +_betaObject.getValue(); + + if (probabilityValue < 0 || probabilityValue > 1 || alphaValue <= 0 || betaValue <= 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const result = gammaINV(probabilityValue, alphaValue, betaValue); + + if (Number.isNaN(result) || !Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/gamma/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/gamma/__tests__/index.spec.ts new file mode 100644 index 000000000000..945977ae3d14 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/gamma/__tests__/index.spec.ts @@ -0,0 +1,115 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Gamma } from '../index'; + +describe('Test gamma function', () => { + const testFunction = new Gamma(FUNCTION_NAMES_STATISTICAL.GAMMA); + + describe('Gamma', () => { + it('Value is normal', () => { + const number = NumberValueObject.create(2.5); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(1.3293403919101043); + }); + + it('Value is 0 or negative integers', () => { + const number = NumberValueObject.create(0); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + + const number2 = NumberValueObject.create(-1); + const result2 = testFunction.calculate(number2); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NUM); + + const number3 = NumberValueObject.create(172); + const result3 = testFunction.calculate(number3); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.NUM); + }); + + it('Value is number string', () => { + const number = StringValueObject.create('-2.5'); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(-0.9453087178298095); + }); + + it('Value is normal string', () => { + const number = StringValueObject.create('test'); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const number = BooleanValueObject.create(true); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(1); + }); + + it('Value is null', () => { + const number = NullValueObject.create(); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + }); + + it('Value is error', () => { + const number = ErrorValueObject.create(ErrorType.NAME); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + }); + + it('Value is array', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual([ + [1, ErrorType.VALUE, 0.9107548563770899, 1, ErrorType.NUM, ErrorType.NUM], + [ErrorType.NUM, 9.33262154439441e+155, 1.19556877982239, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + + const number2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0.001], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(number2); + expect(getObjectValue(result2)).toStrictEqual(999.4237724845955); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/gamma/index.ts b/packages/engine-formula/src/functions/statistical/gamma/index.ts new file mode 100644 index 000000000000..ad3ab52357d8 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/gamma/index.ts @@ -0,0 +1,68 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { gamma } from '../../../basics/statistical'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Gamma extends BaseFunction { + override minParams = 1; + + override maxParams = 1; + + override calculate(number: BaseValueObject): BaseValueObject { + if (number.isArray()) { + const resultArray = (number as ArrayValueObject).mapValue((numberObject) => this._handleSingleObject(numberObject)); + + if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + return this._handleSingleObject(number); + } + + private _handleSingleObject(number: BaseValueObject): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(number); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [numberObject] = variants as BaseValueObject[]; + + const numberValue = +numberObject.getValue(); + + if (numberValue === 0 || (numberValue < 0 && numberValue % 1 === 0)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const result = gamma(numberValue); + + if (Number.isNaN(result) || !Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/gammaln/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/gammaln/__tests__/index.spec.ts new file mode 100644 index 000000000000..650ccf922dd8 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/gammaln/__tests__/index.spec.ts @@ -0,0 +1,117 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Gammaln } from '../index'; + +describe('Test gammaln function', () => { + const testFunction = new Gammaln(FUNCTION_NAMES_STATISTICAL.GAMMALN); + + describe('Gammaln', () => { + it('Value is normal', () => { + const x = NumberValueObject.create(2.5); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual(0.2846828704729183); + }); + + it('Value is 0 or negative integers', () => { + const x = NumberValueObject.create(0); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + + const x2 = NumberValueObject.create(-1); + const result2 = testFunction.calculate(x2); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NUM); + }); + + it('Value is number string', () => { + const x = StringValueObject.create('4'); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual(1.791759469228055); + }); + + it('Value is normal string', () => { + const x = StringValueObject.create('test'); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const x = BooleanValueObject.create(true); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual(0); + }); + + it('Value is null', () => { + const x = NullValueObject.create(); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + }); + + it('Value is error', () => { + const x = ErrorValueObject.create(ErrorType.NAME); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + }); + + it('Value is array', () => { + const x = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual([ + [0, ErrorType.VALUE, -0.09348151082957568, 0, ErrorType.NUM, ErrorType.NUM], + [ErrorType.NUM, 359.1342053696796, 0.17862203839074242, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + + const x2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0.123], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(x2); + expect(getObjectValue(result2)).toStrictEqual(2.036327503417766); + }); + + it('More test', () => { + const x = NumberValueObject.create(2); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual(0); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/gammaln/index.ts b/packages/engine-formula/src/functions/statistical/gammaln/index.ts new file mode 100644 index 000000000000..0091e6572db4 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/gammaln/index.ts @@ -0,0 +1,68 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { gammaln } from '../../../basics/statistical'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Gammaln extends BaseFunction { + override minParams = 1; + + override maxParams = 1; + + override calculate(x: BaseValueObject): BaseValueObject { + if (x.isArray()) { + const resultArray = (x as ArrayValueObject).mapValue((xObject) => this._handleSingleObject(xObject)); + + if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + return this._handleSingleObject(x); + } + + private _handleSingleObject(x: BaseValueObject): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(x); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [xObject] = variants as BaseValueObject[]; + + const xValue = +xObject.getValue(); + + if (xValue <= 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const result = gammaln(xValue); + + if (Math.abs(result) < 1e-15) { + return NumberValueObject.create(0); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/gauss/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/gauss/__tests__/index.spec.ts new file mode 100644 index 000000000000..bf1ca48d7cb1 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/gauss/__tests__/index.spec.ts @@ -0,0 +1,111 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Gauss } from '../index'; + +describe('Test gauss function', () => { + const testFunction = new Gauss(FUNCTION_NAMES_STATISTICAL.GAUSS); + + describe('Gauss', () => { + it('Value is normal', () => { + const z = NumberValueObject.create(2.5); + const result = testFunction.calculate(z); + expect(getObjectValue(result)).toStrictEqual(0.49379033467422384); + }); + + it('Value is 0 or negative integers', () => { + const z = NumberValueObject.create(0); + const result = testFunction.calculate(z); + expect(getObjectValue(result)).toStrictEqual(0); + + const z2 = NumberValueObject.create(-1); + const result2 = testFunction.calculate(z2); + expect(getObjectValue(result2)).toStrictEqual(-0.3413447460685429); + }); + + it('Value is number string', () => { + const z = StringValueObject.create('4'); + const result = testFunction.calculate(z); + expect(getObjectValue(result)).toStrictEqual(0.4999683287581669); + }); + + it('Value is normal string', () => { + const z = StringValueObject.create('test'); + const result = testFunction.calculate(z); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const z = BooleanValueObject.create(true); + const result = testFunction.calculate(z); + expect(getObjectValue(result)).toStrictEqual(0.3413447460685429); + }); + + it('Value is null', () => { + const z = NullValueObject.create(); + const result = testFunction.calculate(z); + expect(getObjectValue(result)).toStrictEqual(0); + }); + + it('Value is error', () => { + const z = ErrorValueObject.create(ErrorType.NAME); + const result = testFunction.calculate(z); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + }); + + it('Value is array', () => { + const z = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(z); + expect(getObjectValue(result)).toStrictEqual([ + [0.3413447460685429, ErrorType.VALUE, 0.39065144757430814, 0.3413447460685429, 0, 0], + [0, 0.5, 0.4903581300546417, ErrorType.VALUE, -0.4986501019683699, ErrorType.NAME], + ]); + + const z2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0.123], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(z2); + expect(getObjectValue(result2)).toStrictEqual(0.04894645101643691); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/gauss/index.ts b/packages/engine-formula/src/functions/statistical/gauss/index.ts new file mode 100644 index 000000000000..26a64b568d52 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/gauss/index.ts @@ -0,0 +1,58 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { normalCDF } from '../../../basics/statistical'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; + +export class Gauss extends BaseFunction { + override minParams = 1; + + override maxParams = 1; + + override calculate(z: BaseValueObject): BaseValueObject { + if (z.isArray()) { + const resultArray = (z as ArrayValueObject).mapValue((zObject) => this._handleSingleObject(zObject)); + + if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + return this._handleSingleObject(z); + } + + private _handleSingleObject(z: BaseValueObject): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(z); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [zObject] = variants as BaseValueObject[]; + + const zValue = +zObject.getValue(); + + const result = normalCDF(zValue, 0, 1) - 0.5; + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/geomean/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/geomean/__tests__/index.spec.ts new file mode 100644 index 000000000000..a0297ac7a6f1 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/geomean/__tests__/index.spec.ts @@ -0,0 +1,98 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Geomean } from '../index'; + +describe('Test geomean function', () => { + const testFunction = new Geomean(FUNCTION_NAMES_STATISTICAL.GEOMEAN); + + describe('Geomean', () => { + it('Value is normal', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [4, 5, 8, 7, 11, 4], + ]), + rowCount: 1, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const number2 = NumberValueObject.create(3); + const result = testFunction.calculate(number, number2); + expect(getObjectValue(result)).toStrictEqual(5.476986969656962); + }); + + it('Value is single cell = null/boolean/string/error/negtive number', () => { + const number = NumberValueObject.create(3); + const number2 = NullValueObject.create(); + const number3 = BooleanValueObject.create(true); + const number4 = StringValueObject.create('test'); + const number5 = ErrorValueObject.create(ErrorType.NAME); + const number6 = NumberValueObject.create(-3); + const result = testFunction.calculate(number, number2, number3, number4); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); + + const result2 = testFunction.calculate(number, number2, number3, number5); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); + + const result3 = testFunction.calculate(number, number2, number3, number6); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.NUM); + }); + + it('Value is not has number', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [true, false, null, 'test', null, null], + ]), + rowCount: 1, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + }); + + it('More test', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/geomean/index.ts b/packages/engine-formula/src/functions/statistical/geomean/index.ts new file mode 100644 index 000000000000..50798cb5a82d --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/geomean/index.ts @@ -0,0 +1,110 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Geomean extends BaseFunction { + override minParams = 1; + + override maxParams = 255; + + override calculate(...variants: BaseValueObject[]): BaseValueObject { + let sum = 1; + let len = 0; + let isNonPositive = false; + + for (let i = 0; i < variants.length; i++) { + const variant = variants[i]; + + if (variant.isArray()) { + let isError = false; + let errorObject = ErrorValueObject.create(ErrorType.VALUE); + + (variant as ArrayValueObject).iterator((valueObject) => { + if (valueObject?.isError()) { + isError = true; + errorObject = valueObject as ErrorValueObject; + return false; + } + + if (valueObject?.isNull() || valueObject?.isBoolean()) { + return true; + } + + const value = (valueObject as BaseValueObject).getValue(); + + if (!isRealNum(value)) { + return true; + } + + if (+value <= 0) { + isNonPositive = true; + } + + sum *= +value; + len++; + }); + + if (isError) { + return errorObject; + } + } else { + if (variant.isError()) { + return variant; + } + + if (variant.isString()) { + const _variant = variant.convertToNumberObjectValue(); + + if (_variant.isError()) { + return _variant; + } + } + + if (variant.isNull() || variant.isBoolean()) { + continue; + } + + const value = variant.getValue(); + + if (!isRealNum(value)) { + continue; + } + + if (+value <= 0) { + isNonPositive = true; + } + + sum *= +value; + len++; + } + } + + if (len === 0 || isNonPositive) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const result = sum ** (1 / len); + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/growth/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/growth/__tests__/index.spec.ts new file mode 100644 index 000000000000..398c2252f31f --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/growth/__tests__/index.spec.ts @@ -0,0 +1,569 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Growth } from '../index'; + +describe('Test growth function', () => { + const testFunction = new Growth(FUNCTION_NAMES_STATISTICAL.GROWTH); + + describe('Growth', () => { + it('Value is normal', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [33100, 47300, 69000, 102000, 150000, 220000], + ]), + rowCount: 1, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [11, 1.2, 1.3, 14, 15, 16], + ]), + rowCount: 1, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const newXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [17, 18], + ]), + rowCount: 1, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const constb = BooleanValueObject.create(true); + const result = testFunction.calculate(knownYs, knownXs, newXs, constb); + expect(getObjectValue(result)).toStrictEqual([ + [136608.33775488546, 145970.01896985146], + ]); + }); + + it('Only knownYs value', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [33100], + [47300], + [69000], + [102000], + [150000], + [220000], + ]), + rowCount: 6, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs); + expect(getObjectValue(result)).toStrictEqual([ + [32618.2037735398], + [47729.42261474784], + [69841.30085621751], + [102197.07337883243], + [149542.48674004586], + [218821.87621459534], + ]); + + const knownYs2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [ErrorType.NAME], + [47300], + [69000], + [102000], + [150000], + [220000], + ]), + rowCount: 6, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(knownYs2); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); + + const knownYs3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null], + [47300], + [69000], + [102000], + [150000], + [220000], + ]), + rowCount: 6, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result3 = testFunction.calculate(knownYs3); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.VALUE); + + const knownYs4 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [true], + [47300], + [69000], + [102000], + [150000], + [220000], + ]), + rowCount: 6, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result4 = testFunction.calculate(knownYs4); + expect(getObjectValue(result4)).toStrictEqual(ErrorType.VALUE); + + const knownYs5 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + ['test'], + [47300], + [69000], + [102000], + [150000], + [220000], + ]), + rowCount: 6, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result5 = testFunction.calculate(knownYs5); + expect(getObjectValue(result5)).toStrictEqual(ErrorType.VALUE); + }); + + it('KnownXs length error', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [2], + [3], + [4], + ]), + rowCount: 4, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [2], + [3], + [4], + [5], + ]), + rowCount: 5, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toStrictEqual(ErrorType.REF); + }); + + it('NewXs length error', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [2], + [3], + [4], + ]), + rowCount: 4, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2], + [2, 3], + [3, 4], + [4, 5], + ]), + rowCount: 4, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const newXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3], + [2, 3, 4], + [3, 4, 5], + [4, 5, 6], + ]), + rowCount: 4, + columnCount: 3, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs, newXs); + expect(getObjectValue(result)).toStrictEqual(ErrorType.REF); + }); + + it('Constb value test', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [33100, 47300, 69000, 102000, 150000, 220000], + ]), + rowCount: 1, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [11, 1.2, 1.3, 14, 15, 16], + ]), + rowCount: 1, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const newXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [17, 18], + ]), + rowCount: 1, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const constb = BooleanValueObject.create(false); + const result = testFunction.calculate(knownYs, knownXs, newXs, constb); + expect(getObjectValue(result)).toStrictEqual([ + [1806822.1964432173, 4216666.612455025], + ]); + + const knownYs2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [33100], + [47300], + [69000], + [102000], + [150000], + [220000], + ]), + rowCount: 6, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(knownYs2, undefined, undefined, constb); + expect(getObjectValue(result2)).toStrictEqual([ + [14.748289539092573], + [217.51204432890742], + [3207.9306080026654], + [47311.48942814059], + [697763.5446119347], + [10290818.78576035], + ]); + + const constb2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + ['test', 1], + [2, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result3 = testFunction.calculate(knownYs2, undefined, undefined, constb2); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.VALUE); + + const result4 = testFunction.calculate(knownYs2, undefined, undefined, constb); + expect(getObjectValue(result4)).toStrictEqual([ + [14.748289539092573], + [217.51204432890742], + [3207.9306080026654], + [47311.48942814059], + [697763.5446119347], + [10290818.78576035], + ]); + }); + + it('Value is error', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [33100, 47300, 69000, 102000, 150000, 220000], + ]), + rowCount: 1, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ErrorValueObject.create(ErrorType.NAME); + const newXs = ErrorValueObject.create(ErrorType.NAME); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + + const result2 = testFunction.calculate(knownYs, undefined, newXs); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); + }); + + it('More test', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2], + [2, 3], + ]), + rowCount: 2, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [3, 4], + [4, 5], + ]), + rowCount: 2, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const newXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [5, 6, 7, 8, 9, 10, 11], + ]), + rowCount: 1, + columnCount: 7, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const constb = BooleanValueObject.create(true); + const result = testFunction.calculate(knownYs, knownXs, newXs, constb); + expect(getObjectValue(result)).toStrictEqual([ + [3.2237097954706266, 5.583629154612603, 9.671129386411891, 16.750887463837827, 29.013388159235713, 50.252662391513546, 87.04016447770724], + ]); + + const newXs2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [5], + [6], + [7], + [8], + [9], + [10], + [11], + [12], + [13], + [14], + [15], + ]), + rowCount: 11, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const constb2 = BooleanValueObject.create(false); + const result2 = testFunction.calculate(knownYs, knownXs, newXs2, constb2); + expect(getObjectValue(result2)).toStrictEqual([ + [2.307651218612649], + [2.727747733175308], + [3.224320744759815], + [3.8112924221868782], + [4.505119396395902], + [5.325254146764445], + [6.294690380529891], + [7.440607695843031], + [8.795133602548706], + [10.396244265088487], + [12.288829221203034], + ]); + + const knownYs2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [2], + [3], + [4], + ]), + rowCount: 4, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2], + [2, 3], + [3, 4], + [4, 5], + ]), + rowCount: 4, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const newXs3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2], + [2, 3], + [3, 4], + [4, 5], + [5, 6], + [6, 7], + [7, 8], + [8, 9], + [9, 10], + [10, 11], + [11, 12], + ]), + rowCount: 11, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result3 = testFunction.calculate(knownYs2, knownXs2, newXs3, constb); + expect(getObjectValue(result3)).toStrictEqual([ + [1.1161231740339033], + [1.7617295898720449], + [2.780778340631825], + [4.389282114679539], + [6.928203230275548], + [10.935729065914693], + [17.2613542397969], + [27.245952089325357], + [43.00600607235712], + [67.88225099390945], + [107.14782470725646], + ]); + + const result4 = testFunction.calculate(knownYs2, knownXs2, newXs3, constb2); + expect(getObjectValue(result4)).toStrictEqual([ + [1.1161231740339057], + [1.7617295898720433], + [2.780778340631814], + [4.389282114679508], + [6.928203230275478], + [10.935729065914547], + [17.261354239796617], + [27.245952089324824], + [43.00600607235614], + [67.88225099390776], + [107.14782470725342], + ]); + + const knownYs3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4], + [2, 3, 4, 5], + ]), + rowCount: 2, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const newXs4 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7], + [2, 3, 4, 5, 6, 7, 8], + ]), + rowCount: 2, + columnCount: 7, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result5 = testFunction.calculate(knownYs3, knownXs3, newXs4, constb); + expect(getObjectValue(result5)).toStrictEqual([ + [1.1161231740339033, 1.7617295898720449, 2.780778340631825, 4.389282114679539, 6.928203230275548, 10.935729065914693, 17.2613542397969], + ]); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/growth/index.ts b/packages/engine-formula/src/functions/statistical/growth/index.ts new file mode 100644 index 000000000000..d756d0144bc2 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/growth/index.ts @@ -0,0 +1,357 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { calculateMmult, inverseMatrixByUSV, matrixTranspose } from '../../../basics/math'; +import { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { BooleanValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Growth extends BaseFunction { + override minParams = 1; + + override maxParams = 4; + + override calculate(knownYs: BaseValueObject, knownXs?: BaseValueObject, newXs?: BaseValueObject, constb?: BaseValueObject): BaseValueObject { + const knownYsRowCount = knownYs.isArray() ? (knownYs as ArrayValueObject).getRowCount() : 1; + const knownYsColumnCount = knownYs.isArray() ? (knownYs as ArrayValueObject).getColumnCount() : 1; + const knownYsValues = this._getValues(knownYs, knownYsRowCount, knownYsColumnCount); + + if (knownYsValues instanceof ErrorValueObject) { + return knownYsValues; + } + + const knownXsValues = this._getKnownXsValues(knownYsRowCount, knownYsColumnCount, knownXs); + + if (knownXsValues instanceof ErrorValueObject) { + return knownXsValues; + } + + const newXsValues = this._getNewXsValues(knownXsValues, knownYsRowCount, knownYsColumnCount, newXs); + + if (newXsValues instanceof ErrorValueObject) { + return newXsValues; + } + + let _constb = constb ?? BooleanValueObject.create(true); + + if (_constb.isArray()) { + _constb = (_constb as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_constb.isString()) { + _constb = _constb.convertToNumberObjectValue(); + } + + if (_constb.isError()) { + return _constb; + } + + const constbValue = +_constb.getValue(); + + return this._getResult(knownYsValues, knownXsValues, newXsValues, constbValue); + } + + private _getResult(knownYsValues: number[][], knownXsValues: number[][], newXsValues: number[][], constbValue: number): BaseValueObject { + if ((knownYsValues.length === 1 && knownXsValues.length > 1) || (knownYsValues[0].length === 1 && knownXsValues[0].length > 1)) { + return this._getResultByMultipleVariables(knownYsValues, knownXsValues, newXsValues, constbValue); + } + + return this._getResultBySimpleVariables(knownYsValues, knownXsValues, newXsValues, constbValue); + } + + private _getResultByMultipleVariables(knownYsValues: number[][], knownXsValues: number[][], newXsValues: number[][], constbValue: number): BaseValueObject { + const isOneRow = knownYsValues.length === 1 && knownYsValues[0].length > 1; + + let logYs: number[][] = []; + let X: number[][] = []; + + if (isOneRow) { + logYs = matrixTranspose(knownYsValues).map((row) => row.map((value) => Math.log(value))); + X = constbValue ? matrixTranspose(knownXsValues).map((row) => [...row, 1]) : matrixTranspose(knownXsValues); + } else { + logYs = knownYsValues.map((row) => row.map((value) => Math.log(value))); + X = constbValue ? knownXsValues.map((row) => [...row, 1]) : knownXsValues; + } + + const XT = matrixTranspose(X); + const XTX = calculateMmult(XT, X); + const XTY = calculateMmult(XT, logYs); + const XTXInv = inverseMatrixByUSV(XTX); + + if (!XTXInv) { + return ErrorValueObject.create(ErrorType.NA); + } + + const coefficients = calculateMmult(XTXInv, XTY).map((row) => row[0]); + + let result: number[][] = []; + + if (isOneRow) { + result = matrixTranspose(newXsValues).map((row) => { + const newX = constbValue ? [...row, 1] : row; + const logY = newX.reduce((acc, value, index) => acc + value * coefficients[index], 0); + return [Math.exp(logY)]; + }); + result = matrixTranspose(result); + } else { + result = newXsValues.map((row) => { + const newX = constbValue ? [...row, 1] : row; + const logY = newX.reduce((acc, value, index) => acc + value * coefficients[index], 0); + return [Math.exp(logY)]; + }); + } + + return ArrayValueObject.createByArray(result); + } + + private _getResultBySimpleVariables(knownYsValues: number[][], knownXsValues: number[][], newXsValues: number[][], constbValue: number): BaseValueObject { + const newXsRowCount = newXsValues.length; + const newXsColumnCount = newXsValues[0].length; + + const knownYsValuesFlat = knownYsValues.flat(); + const knownXsValuesFlat = knownXsValues.flat(); + const newXsValuesFlat = newXsValues.flat(); + const logYs = knownYsValuesFlat.map((value) => Math.log(value)); + + let slope, intercept; + + if (constbValue) { + ({ slope, intercept } = this._getSlopeAndInterceptOfConstbIsTrue(knownXsValuesFlat, logYs)); + } else { + ({ slope, intercept } = this._getSlopeAndInterceptOfConstbIsFalse(knownXsValuesFlat, logYs)); + } + + if (Number.isNaN(slope) && !constbValue) { + slope = 0; + } + + const result: number[][] = []; + + for (let r = 0; r < newXsRowCount; r++) { + const row: number[] = []; + + for (let c = 0; c < newXsColumnCount; c++) { + const value = intercept * (slope ** newXsValuesFlat[r * newXsColumnCount + c]); + row.push(value); + } + + result.push(row); + } + + return ArrayValueObject.createByArray(result); + } + + private _getSlopeAndInterceptOfConstbIsTrue(knownXsValuesFlat: number[], logYs: number[]) { + const n = logYs.length; + + let sumX = 0; + let sumY = 0; + let sumX2 = 0; + let sumXY = 0; + + for (let i = 0; i < n; i++) { + sumX += knownXsValuesFlat[i]; + sumY += logYs[i]; + sumX2 += knownXsValuesFlat[i] * knownXsValuesFlat[i]; + sumXY += knownXsValuesFlat[i] * logYs[i]; + } + + const temp = n * sumXY - sumX * sumY; + const slope = temp / (n * sumX2 - sumX * sumX); + const intercept = 1 / n * sumY - slope * (1 / n) * sumX; + + return { + slope: Math.exp(slope), + intercept: Math.exp(intercept), + }; + } + + private _getSlopeAndInterceptOfConstbIsFalse(knownXsValuesFlat: number[], logYs: number[]) { + const matrixX = [[...knownXsValuesFlat]]; + const matrixY = [...logYs]; + + let rowCount = matrixX.length; + let columnCount = matrixX[0].length; + let minCount = Math.min(rowCount, columnCount); + const newMatrix = new Array(minCount).fill(0); + + for (let i = 0; i < minCount; i++) { + const matrixXRow = matrixX[i]; + + let sumSquare = 0; + + for (let j = 0; j < columnCount; j++) { + sumSquare += matrixXRow[j] ** 2; + } + + const value = matrixXRow[i] < 0 ? Math.sqrt(sumSquare) : -Math.sqrt(sumSquare); + + newMatrix[i] = value; + + if (value !== 0) { + matrixXRow[i] -= value; + + for (let j = i + 1; j < rowCount; j++) { + let sum = 0; + + for (let k = i; k < columnCount; k++) { + sum -= matrixX[j][k] * matrixXRow[k]; + } + + sum /= (value * matrixXRow[i]); + + for (let k = i; k < columnCount; k++) { + matrixX[j][k] -= sum * matrixXRow[k]; + } + } + } + } + + rowCount = matrixX.length; + columnCount = matrixX[0].length; + minCount = Math.min(rowCount, columnCount); + const result = new Array(rowCount).fill(0); + + for (let i = 0; i < minCount; i++) { + const matrixXRow = matrixX[i]; + + let sum = 0; + + for (let j = 0; j < columnCount; j++) { + sum += matrixY[j] * matrixXRow[j]; + } + + sum /= (newMatrix[i] * matrixXRow[i]); + + for (let j = 0; j < columnCount; j++) { + matrixY[j] += sum * matrixXRow[j]; + } + } + + for (let i = newMatrix.length - 1; i >= 0; i--) { + matrixY[i] /= newMatrix[i]; + + const temp = matrixY[i]; + const matrixXRow = matrixX[i]; + + result[i] = temp; + + for (let j = 0; j < i; j++) { + matrixY[j] -= temp * matrixXRow[j]; + } + } + + return { + slope: Math.exp(result[0]), + intercept: Math.exp(0), + }; + } + + private _getKnownXsValues(knownYsRowCount: number, knownYsColumnCount: number, knownXs?: BaseValueObject): number[][] | ErrorValueObject { + if (!knownXs || knownXs.isNull()) { + return this._getNumberValuesByRowsColumns(knownYsRowCount, knownYsColumnCount); + } + + if (knownXs.isError()) { + return knownXs as ErrorValueObject; + } + + const knownXsRowCount = knownXs.isArray() ? (knownXs as ArrayValueObject).getRowCount() : 1; + const knownXsColumnCount = knownXs.isArray() ? (knownXs as ArrayValueObject).getColumnCount() : 1; + + if ( + (knownYsRowCount === 1 && knownXsColumnCount !== knownYsColumnCount) || + (knownYsColumnCount === 1 && knownXsRowCount !== knownYsRowCount) || + (knownYsRowCount !== 1 && knownYsColumnCount !== 1 && (knownXsRowCount !== knownYsRowCount || knownXsColumnCount !== knownYsColumnCount)) + ) { + return ErrorValueObject.create(ErrorType.REF); + } + + return this._getValues(knownXs, knownXsRowCount, knownXsColumnCount); + } + + private _getNewXsValues(knownXsValues: number[][], knownYsRowCount: number, knownYsColumnCount: number, newXs?: BaseValueObject): number[][] | ErrorValueObject { + if (!newXs || newXs.isNull()) { + return knownXsValues; + } + + if (newXs.isError()) { + return newXs as ErrorValueObject; + } + + const newXsRowCount = newXs.isArray() ? (newXs as ArrayValueObject).getRowCount() : 1; + const newXsColumnCount = newXs.isArray() ? (newXs as ArrayValueObject).getColumnCount() : 1; + + if ( + (knownYsRowCount === 1 && knownXsValues.length > 1 && newXsRowCount !== knownXsValues.length) || + (knownYsColumnCount === 1 && knownXsValues[0].length > 1 && newXsColumnCount !== knownXsValues[0].length) + ) { + return ErrorValueObject.create(ErrorType.REF); + } + + return this._getValues(newXs, newXsRowCount, newXsColumnCount); + } + + private _getValues(variant: BaseValueObject, rowCount: number, columnCount: number): number[][] | ErrorValueObject { + const values: number[][] = []; + + for (let r = 0; r < rowCount; r++) { + values[r] = []; + + for (let c = 0; c < columnCount; c++) { + const valueObject = variant.isArray() ? (variant as ArrayValueObject).get(r, c) as BaseValueObject : variant; + + if (valueObject.isError()) { + return valueObject as ErrorValueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean()) { + return ErrorValueObject.create(ErrorType.VALUE); + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + return ErrorValueObject.create(ErrorType.VALUE); + } + + values[r].push(+value); + } + } + + return values; + } + + private _getNumberValuesByRowsColumns(rowCount: number, columnCount: number): number[][] { + const values: number[][] = []; + + let n = 1; + + for (let r = 0; r < rowCount; r++) { + values[r] = []; + + for (let c = 0; c < columnCount; c++) { + values[r].push(n++); + } + } + + return values; + } +} diff --git a/packages/engine-formula/src/functions/statistical/harmean/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/harmean/__tests__/index.spec.ts new file mode 100644 index 000000000000..8e269e35856f --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/harmean/__tests__/index.spec.ts @@ -0,0 +1,98 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Harmean } from '../index'; + +describe('Test harmean function', () => { + const testFunction = new Harmean(FUNCTION_NAMES_STATISTICAL.HARMEAN); + + describe('Harmean', () => { + it('Value is normal', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [4, 5, 8, 7, 11, 4], + ]), + rowCount: 1, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const number2 = NumberValueObject.create(3); + const result = testFunction.calculate(number, number2); + expect(getObjectValue(result)).toStrictEqual(5.028375962061728); + }); + + it('Value is single cell = null/boolean/string/error/negtive number', () => { + const number = NumberValueObject.create(3); + const number2 = NullValueObject.create(); + const number3 = BooleanValueObject.create(true); + const number4 = StringValueObject.create('test'); + const number5 = ErrorValueObject.create(ErrorType.NAME); + const number6 = NumberValueObject.create(-3); + const result = testFunction.calculate(number, number2, number3, number4); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); + + const result2 = testFunction.calculate(number, number2, number3, number5); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); + + const result3 = testFunction.calculate(number, number2, number3, number6); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.NUM); + }); + + it('Value is not has number', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [true, false, null, 'test', null, null], + ]), + rowCount: 1, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NA); + }); + + it('More test', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/harmean/index.ts b/packages/engine-formula/src/functions/statistical/harmean/index.ts new file mode 100644 index 000000000000..84cac8310b2d --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/harmean/index.ts @@ -0,0 +1,114 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Harmean extends BaseFunction { + override minParams = 1; + + override maxParams = 255; + + override calculate(...variants: BaseValueObject[]): BaseValueObject { + let sum = 0; + let len = 0; + let isNonPositive = false; + + for (let i = 0; i < variants.length; i++) { + const variant = variants[i]; + + if (variant.isArray()) { + let isError = false; + let errorObject = ErrorValueObject.create(ErrorType.VALUE); + + (variant as ArrayValueObject).iterator((valueObject) => { + if (valueObject?.isError()) { + isError = true; + errorObject = valueObject as ErrorValueObject; + return false; + } + + if (valueObject?.isNull() || valueObject?.isBoolean()) { + return true; + } + + const value = (valueObject as BaseValueObject).getValue(); + + if (!isRealNum(value)) { + return true; + } + + if (+value <= 0) { + isNonPositive = true; + } + + sum += 1 / +value; + len++; + }); + + if (isError) { + return errorObject; + } + } else { + if (variant.isError()) { + return variant; + } + + if (variant.isString()) { + const _variant = variant.convertToNumberObjectValue(); + + if (_variant.isError()) { + return _variant; + } + } + + if (variant.isNull() || variant.isBoolean()) { + continue; + } + + const value = variant.getValue(); + + if (!isRealNum(value)) { + continue; + } + + if (+value <= 0) { + isNonPositive = true; + } + + sum += 1 / +value; + len++; + } + } + + if (len === 0) { + return ErrorValueObject.create(ErrorType.NA); + } + + if (isNonPositive) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const result = len / sum; + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/hypgeom-dist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/hypgeom-dist/__tests__/index.spec.ts new file mode 100644 index 000000000000..51d18d468352 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/hypgeom-dist/__tests__/index.spec.ts @@ -0,0 +1,258 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { HypgeomDist } from '../index'; + +describe('Test hypgeomDist function', () => { + const testFunction = new HypgeomDist(FUNCTION_NAMES_STATISTICAL.HYPGEOM_DIST); + + describe('HypgeomDist', () => { + it('Value is normal', () => { + const sampleS = NumberValueObject.create(1); + const numberSample = NumberValueObject.create(4); + const populationS = NumberValueObject.create(8); + const numberPop = NumberValueObject.create(20); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop, cumulative); + expect(getObjectValue(result)).toBe(0.46542827657378744); + }); + + it('Value is large number', () => { + const sampleS = NumberValueObject.create(1); + const numberSample = NumberValueObject.create(100000); + const populationS = NumberValueObject.create(1000000); + const numberPop = NumberValueObject.create(10000000); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop, cumulative); + expect(getObjectValue(result)).toBe(0); + }); + + it('SampleS value test', () => { + const sampleS = NumberValueObject.create(-1); + const numberSample = NumberValueObject.create(4); + const populationS = NumberValueObject.create(8); + const numberPop = NumberValueObject.create(20); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const sampleS2 = NumberValueObject.create(5); + const result2 = testFunction.calculate(sampleS2, numberSample, populationS, numberPop, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + + const sampleS3 = BooleanValueObject.create(true); + const result3 = testFunction.calculate(sampleS3, numberSample, populationS, numberPop, cumulative); + expect(getObjectValue(result3)).toBe(0.46542827657378744); + + const sampleS4 = NullValueObject.create(); + const result4 = testFunction.calculate(sampleS4, numberSample, populationS, numberPop, cumulative); + expect(getObjectValue(result4)).toBe(0.1021671826625387); + + const sampleS5 = StringValueObject.create('test'); + const result5 = testFunction.calculate(sampleS5, numberSample, populationS, numberPop, cumulative); + expect(getObjectValue(result5)).toBe(ErrorType.VALUE); + + const sampleS6 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(sampleS6, numberSample, populationS, numberPop, cumulative); + expect(getObjectValue(result6)).toBe(ErrorType.NAME); + }); + + it('NumberSample value test', () => { + const sampleS = NumberValueObject.create(1); + const numberSample = NumberValueObject.create(-1); + const populationS = NumberValueObject.create(8); + const numberPop = NumberValueObject.create(20); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const numberSample2 = NumberValueObject.create(22); + const result2 = testFunction.calculate(sampleS, numberSample2, populationS, numberPop, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + + const numberSample3 = BooleanValueObject.create(true); + const result3 = testFunction.calculate(sampleS, numberSample3, populationS, numberPop, cumulative); + expect(getObjectValue(result3)).toBe(1); + + const numberSample4 = NullValueObject.create(); + const result4 = testFunction.calculate(sampleS, numberSample4, populationS, numberPop, cumulative); + expect(getObjectValue(result4)).toBe(ErrorType.NUM); + + const numberSample5 = StringValueObject.create('test'); + const result5 = testFunction.calculate(sampleS, numberSample5, populationS, numberPop, cumulative); + expect(getObjectValue(result5)).toBe(ErrorType.VALUE); + + const numberSample6 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(sampleS, numberSample6, populationS, numberPop, cumulative); + expect(getObjectValue(result6)).toBe(ErrorType.NAME); + }); + + it('PopulationS value test', () => { + const sampleS = NumberValueObject.create(1); + const numberSample = NumberValueObject.create(4); + const populationS = NumberValueObject.create(-1); + const numberPop = NumberValueObject.create(20); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const populationS2 = NumberValueObject.create(21); + const result2 = testFunction.calculate(sampleS, numberSample, populationS2, numberPop, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + + const populationS3 = BooleanValueObject.create(true); + const result3 = testFunction.calculate(sampleS, numberSample, populationS3, numberPop, cumulative); + expect(getObjectValue(result3)).toBe(1); + + const populationS4 = NullValueObject.create(); + const result4 = testFunction.calculate(sampleS, numberSample, populationS4, numberPop, cumulative); + expect(getObjectValue(result4)).toBe(ErrorType.NUM); + + const populationS5 = StringValueObject.create('test'); + const result5 = testFunction.calculate(sampleS, numberSample, populationS5, numberPop, cumulative); + expect(getObjectValue(result5)).toBe(ErrorType.VALUE); + + const populationS6 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(sampleS, numberSample, populationS6, numberPop, cumulative); + expect(getObjectValue(result6)).toBe(ErrorType.NAME); + }); + + it('NumberPop value test', () => { + const sampleS = NumberValueObject.create(1); + const numberSample = NumberValueObject.create(4); + const populationS = NumberValueObject.create(8); + const numberPop = NumberValueObject.create(-20); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const numberPop2 = BooleanValueObject.create(true); + const result2 = testFunction.calculate(sampleS, numberSample, populationS, numberPop2, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + + const numberPop3 = NullValueObject.create(); + const result3 = testFunction.calculate(sampleS, numberSample, populationS, numberPop3, cumulative); + expect(getObjectValue(result3)).toBe(ErrorType.NUM); + + const numberPop4 = StringValueObject.create('test'); + const result4 = testFunction.calculate(sampleS, numberSample, populationS, numberPop4, cumulative); + expect(getObjectValue(result4)).toBe(ErrorType.VALUE); + + const numberPop5 = ErrorValueObject.create(ErrorType.NAME); + const result5 = testFunction.calculate(sampleS, numberSample, populationS, numberPop5, cumulative); + expect(getObjectValue(result5)).toBe(ErrorType.NAME); + }); + + it('Cumulative value test', () => { + const sampleS = NumberValueObject.create(1); + const numberSample = NumberValueObject.create(4); + const populationS = NumberValueObject.create(8); + const numberPop = NumberValueObject.create(20); + const cumulative = BooleanValueObject.create(false); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop, cumulative); + expect(getObjectValue(result)).toBe(0.3632610939112487); + + const cumulative2 = NullValueObject.create(); + const result2 = testFunction.calculate(sampleS, numberSample, populationS, numberPop, cumulative2); + expect(getObjectValue(result2)).toBe(0.3632610939112487); + + const cumulative3 = StringValueObject.create('test'); + const result3 = testFunction.calculate(sampleS, numberSample, populationS, numberPop, cumulative3); + expect(getObjectValue(result3)).toBe(ErrorType.VALUE); + + const cumulative4 = ErrorValueObject.create(ErrorType.NAME); + const result4 = testFunction.calculate(sampleS, numberSample, populationS, numberPop, cumulative4); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const sampleS = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const numberSample = NumberValueObject.create(4); + const populationS = NumberValueObject.create(8); + const numberPop = NumberValueObject.create(20); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop, cumulative); + expect(getObjectValue(result)).toStrictEqual([ + [0.46542827657378744, ErrorType.VALUE, 0.46542827657378744, 0.46542827657378744, 0.1021671826625387, 0.1021671826625387], + [0.1021671826625387, ErrorType.NUM, 0.8468524251805986, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + + const sampleS2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [4], + [8], + [20], + ]), + rowCount: 4, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const numberSample2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [4], + [8], + [20], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(sampleS2, numberSample2, populationS, numberPop, cumulative); + expect(getObjectValue(result2)).toStrictEqual([ + [0.46542827657378744], + [0.8867587520838295], + [1], + [ErrorType.NA], + ]); + }); + + it('More test', () => { + const sampleS = NumberValueObject.create(20); + const numberSample = NumberValueObject.create(20); + const populationS = NumberValueObject.create(20); + const numberPop = NumberValueObject.create(20); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(sampleS, numberSample, populationS, numberPop, cumulative); + expect(getObjectValue(result)).toBe(1); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/hypgeom-dist/index.ts b/packages/engine-formula/src/functions/statistical/hypgeom-dist/index.ts new file mode 100644 index 000000000000..94e274757ad4 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/hypgeom-dist/index.ts @@ -0,0 +1,145 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { hypergeometricCDF, hypergeometricPDF } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class HypgeomDist extends BaseFunction { + override minParams = 5; + + override maxParams = 5; + + override calculate( + sampleS: BaseValueObject, + numberSample: BaseValueObject, + populationS: BaseValueObject, + numberPop: BaseValueObject, + cumulative: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + sampleS.isArray() ? (sampleS as ArrayValueObject).getRowCount() : 1, + numberSample.isArray() ? (numberSample as ArrayValueObject).getRowCount() : 1, + populationS.isArray() ? (populationS as ArrayValueObject).getRowCount() : 1, + numberPop.isArray() ? (numberPop as ArrayValueObject).getRowCount() : 1, + cumulative.isArray() ? (cumulative as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + sampleS.isArray() ? (sampleS as ArrayValueObject).getColumnCount() : 1, + numberSample.isArray() ? (numberSample as ArrayValueObject).getColumnCount() : 1, + populationS.isArray() ? (populationS as ArrayValueObject).getColumnCount() : 1, + numberPop.isArray() ? (numberPop as ArrayValueObject).getColumnCount() : 1, + cumulative.isArray() ? (cumulative as ArrayValueObject).getColumnCount() : 1 + ); + + const sampleSArray = expandArrayValueObject(maxRowLength, maxColumnLength, sampleS, ErrorValueObject.create(ErrorType.NA)); + const numberSampleArray = expandArrayValueObject(maxRowLength, maxColumnLength, numberSample, ErrorValueObject.create(ErrorType.NA)); + const populationSArray = expandArrayValueObject(maxRowLength, maxColumnLength, populationS, ErrorValueObject.create(ErrorType.NA)); + const numberPopArray = expandArrayValueObject(maxRowLength, maxColumnLength, numberPop, ErrorValueObject.create(ErrorType.NA)); + const cumulativeArray = expandArrayValueObject(maxRowLength, maxColumnLength, cumulative, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = sampleSArray.mapValue((sampleSObject, rowIndex, columnIndex) => { + const numberSampleObject = numberSampleArray.get(rowIndex, columnIndex) as BaseValueObject; + const populationSObject = populationSArray.get(rowIndex, columnIndex) as BaseValueObject; + const numberPopObject = numberPopArray.get(rowIndex, columnIndex) as BaseValueObject; + const cumulativeObject = cumulativeArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (sampleSObject.isError()) { + return sampleSObject; + } + + if (numberSampleObject.isError()) { + return numberSampleObject; + } + + if (populationSObject.isError()) { + return populationSObject; + } + + if (numberPopObject.isError()) { + return numberPopObject; + } + + if (cumulativeObject.isError()) { + return cumulativeObject; + } + + return this._handleSignleObject(sampleSObject, numberSampleObject, populationSObject, numberPopObject, cumulativeObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + sampleSObject: BaseValueObject, + numberSampleObject: BaseValueObject, + populationSObject: BaseValueObject, + numberPopObject: BaseValueObject, + cumulativeObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(sampleSObject, numberSampleObject, populationSObject, numberPopObject, cumulativeObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_sampleSObject, _numberSampleObject, _populationSObject, _numberPopObject, _cumulativeObject] = variants as BaseValueObject[]; + + const sampleSValue = Math.floor(+_sampleSObject.getValue()); + const numberSampleValue = Math.floor(+_numberSampleObject.getValue()); + const populationSValue = Math.floor(+_populationSObject.getValue()); + const numberPopValue = Math.floor(+_numberPopObject.getValue()); + const cumulativeValue = +_cumulativeObject.getValue(); + + if ( + sampleSValue < 0 || + sampleSValue > numberSampleValue || + sampleSValue > populationSValue || + sampleSValue < numberSampleValue - numberPopValue + populationSValue || + numberSampleValue <= 0 || + numberSampleValue > numberPopValue || + populationSValue <= 0 || + populationSValue > numberPopValue || + numberPopValue <= 0 + ) { + return ErrorValueObject.create(ErrorType.NUM); + } + + let result; + + if (cumulativeValue) { + result = hypergeometricCDF(sampleSValue, numberSampleValue, populationSValue, numberPopValue); + } else { + result = hypergeometricPDF(sampleSValue, numberSampleValue, populationSValue, numberPopValue); + } + + if (Number.isNaN(result)) { + result = 0; + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/intercept/index.ts b/packages/engine-formula/src/functions/statistical/intercept/index.ts index 793852a7b380..bafe35e61159 100644 --- a/packages/engine-formula/src/functions/statistical/intercept/index.ts +++ b/packages/engine-formula/src/functions/statistical/intercept/index.ts @@ -54,7 +54,7 @@ export class Intercept extends BaseFunction { } if (knownYsRowCount * knownYsColumnCount === 1 || knownXsRowCount * knownXsColumnCount === 1) { - if (knownYs.isNull() || knownXs.isNull()) { + if (_knownYs.isNull() || _knownXs.isNull()) { return ErrorValueObject.create(ErrorType.VALUE); } diff --git a/packages/engine-formula/src/functions/statistical/kurt/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/kurt/__tests__/index.spec.ts new file mode 100644 index 000000000000..2e99a6749b4c --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/kurt/__tests__/index.spec.ts @@ -0,0 +1,133 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Kurt } from '../index'; + +describe('Test kurt function', () => { + const testFunction = new Kurt(FUNCTION_NAMES_STATISTICAL.KURT); + + describe('Kurt', () => { + it('Value is normal', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9], + ]), + rowCount: 3, + columnCount: 3, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(-1.2000000000000006); + }); + + it('Value length < 4', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3], + ]), + rowCount: 1, + columnCount: 3, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.DIV_BY_ZERO); + }); + + it('Value is single cell = null/boolean/string/error/negtive number', () => { + const number = NumberValueObject.create(3); + const number2 = NullValueObject.create(); + const number3 = BooleanValueObject.create(true); + const number4 = StringValueObject.create('test'); + const number5 = ErrorValueObject.create(ErrorType.NAME); + const number6 = NumberValueObject.create(-3); + const result = testFunction.calculate(number, number2, number3, number4); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); + + const result2 = testFunction.calculate(number, number2, number3, number5); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); + + const result3 = testFunction.calculate(number, number2, number3, number6); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.DIV_BY_ZERO); + }); + + it('Value is not has number', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [true, false, null, 'test', null, null], + ]), + rowCount: 1, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.DIV_BY_ZERO); + }); + + it('Stdev is 0', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 1, 1], + [1, 1, 1], + [1, 1, 1], + ]), + rowCount: 3, + columnCount: 3, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.DIV_BY_ZERO); + }); + + it('More test', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/kurt/index.ts b/packages/engine-formula/src/functions/statistical/kurt/index.ts new file mode 100644 index 000000000000..f8419e1a6177 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/kurt/index.ts @@ -0,0 +1,110 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Kurt extends BaseFunction { + override minParams = 1; + + override maxParams = 255; + + override calculate(...variants: BaseValueObject[]): BaseValueObject { + const values: number[] = []; + + let sum = 0; + + for (let i = 0; i < variants.length; i++) { + const variant = variants[i]; + + if (variant.isError()) { + return variant; + } + + if (variant.isString()) { + const _variant = variant.convertToNumberObjectValue(); + + if (_variant.isError()) { + return _variant; + } + } + + const rowCount = variant.isArray() ? (variant as ArrayValueObject).getRowCount() : 1; + const columnCount = variant.isArray() ? (variant as ArrayValueObject).getColumnCount() : 1; + + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const valueObject = variant.isArray() ? (variant as ArrayValueObject).get(r, c) as BaseValueObject : variant; + + if (valueObject.isError()) { + return valueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + values.push(+value); + sum += +value; + } + } + } + + if (values.length <= 3) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + return this._getResult(values, sum); + } + + private _getResult(values: number[], sum: number): BaseValueObject { + const n = values.length; + const mean = sum / n; + + let sum2 = 0; + + for (let i = 0; i < n; i++) { + sum2 += (values[i] - mean) ** 2; + } + + const stdev = Math.sqrt(sum2 / (n - 1)); + + if (stdev === 0) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + let sum3 = 0; + + for (let i = 0; i < n; i++) { + sum3 += ((values[i] - mean) / stdev) ** 4; + } + + const result = n * (n + 1) / ((n - 1) * (n - 2) * (n - 3)) * sum3 - 3 * ((n - 1) ** 2) / ((n - 2) * (n - 3)); + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/large/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/large/__tests__/index.spec.ts new file mode 100644 index 000000000000..a05d870a9a9a --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/large/__tests__/index.spec.ts @@ -0,0 +1,143 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Large } from '../index'; + +describe('Test large function', () => { + const testFunction = new Large(FUNCTION_NAMES_STATISTICAL.LARGE); + + describe('Large', () => { + it('Value is normal', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(2.5); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(8); + }); + + it('Value is number string', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + ['\'1', '\'2', '\'3', '\'4', '\'5', '\'6', '\'7', '\'8', '\'9', '\'10'], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(2.5); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + }); + + it('Array value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, null, true, false, 'test', 6, 7, 8, 9, ErrorType.NAME], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(2.5); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null, true, false, 'test'], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(array2, k); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NUM); + }); + + it('K value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(0.1); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + + const k2 = NumberValueObject.create(11); + const result2 = testFunction.calculate(array, k2); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NUM); + + const k3 = BooleanValueObject.create(true); + const result3 = testFunction.calculate(array, k3); + expect(getObjectValue(result3)).toStrictEqual(10); + + const k4 = NullValueObject.create(); + const result4 = testFunction.calculate(array, k4); + expect(getObjectValue(result4)).toStrictEqual(ErrorType.NUM); + + const k5 = StringValueObject.create('test'); + const result5 = testFunction.calculate(array, k5); + expect(getObjectValue(result5)).toStrictEqual(ErrorType.VALUE); + + const k6 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(array, k6); + expect(getObjectValue(result6)).toStrictEqual(ErrorType.NAME); + + const k7 = ArrayValueObject.create('{1,2,3}'); + const result7 = testFunction.calculate(array, k7); + expect(getObjectValue(result7)).toStrictEqual([ + [10, 9, 8], + ]); + + const k8 = ArrayValueObject.create('{1}'); + const result8 = testFunction.calculate(array, k8); + expect(getObjectValue(result8)).toStrictEqual(10); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/large/index.ts b/packages/engine-formula/src/functions/statistical/large/index.ts new file mode 100644 index 000000000000..da4740530ba0 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/large/index.ts @@ -0,0 +1,105 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Large extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate(array: BaseValueObject, k: BaseValueObject): BaseValueObject { + const arrayValues = this._getValues(array); + + if (k.isArray()) { + const resultArray = (k as ArrayValueObject).mapValue((kObject) => this._handleSingleObject(arrayValues, kObject)); + + if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + return this._handleSingleObject(arrayValues, k); + } + + private _handleSingleObject(array: number[] | ErrorValueObject, k: BaseValueObject): BaseValueObject { + if (array instanceof ErrorValueObject) { + return array; + } + + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(k); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [kObject] = variants as BaseValueObject[]; + + let kValue = +kObject.getValue(); + + if (kValue < 1 || kValue > array.length) { + return ErrorValueObject.create(ErrorType.NUM); + } + + kValue = Math.ceil(kValue); + + return NumberValueObject.create(array[kValue - 1]); + } + + private _getValues(array: BaseValueObject): number[] | ErrorValueObject { + const rowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; + const columnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; + + const values: number[] = []; + + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const valueObject = array.isArray() ? (array as ArrayValueObject).get(r, c) as BaseValueObject : array; + + if (valueObject.isError()) { + return valueObject as ErrorValueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean() || valueObject.isString()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + values.push(+value); + } + } + + if (values.length === 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return values.sort((a, b) => b - a); + } +} diff --git a/packages/engine-formula/src/functions/statistical/lognorm-dist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/lognorm-dist/__tests__/index.spec.ts new file mode 100644 index 000000000000..f24a605dd198 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/lognorm-dist/__tests__/index.spec.ts @@ -0,0 +1,130 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { LognormDist } from '../index'; + +describe('Test lognormDist function', () => { + const testFunction = new LognormDist(FUNCTION_NAMES_STATISTICAL.LOGNORM_DIST); + + describe('LognormDist', () => { + it('Value is normal', () => { + const x = NumberValueObject.create(15.2069); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, mean, standardDev, cumulative); + expect(getObjectValue(result)).toBe(0.20623272748031884); + }); + + it('StandardDev value test', () => { + const x = NumberValueObject.create(15.2069); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(0); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, mean, standardDev, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Cumulative value test', () => { + const x = NumberValueObject.create(15.2069); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const cumulative = BooleanValueObject.create(false); + const result = testFunction.calculate(x, mean, standardDev, cumulative); + expect(getObjectValue(result)).toBe(0.004687651063329815); + }); + + it('Value is normal string', () => { + const x = StringValueObject.create('test'); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, mean, standardDev, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const x = BooleanValueObject.create(true); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, mean, standardDev, cumulative); + expect(getObjectValue(result)).toBe(0.06680720126885809); + }); + + it('Value is null', () => { + const x = NullValueObject.create(); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, mean, standardDev, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Value is error', () => { + const x = ErrorValueObject.create(ErrorType.NAME); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, mean, standardDev, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(15.2069); + const mean2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, mean2, standardDev, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const standardDev2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(x2, mean, standardDev2, cumulative); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const cumulative2 = ErrorValueObject.create(ErrorType.NAME); + const result4 = testFunction.calculate(x2, mean, standardDev, cumulative2); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const x = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, mean, standardDev, cumulative); + expect(getObjectValue(result)).toStrictEqual([ + [0.06680720126885809, ErrorType.VALUE, 0.07377406798431951, 0.06680720126885809, ErrorType.NUM, ErrorType.NUM], + [ErrorType.NUM, 0.3636544740101908, 0.09896660651880768, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/lognorm-dist/index.ts b/packages/engine-formula/src/functions/statistical/lognorm-dist/index.ts new file mode 100644 index 000000000000..b90ed74ecae2 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/lognorm-dist/index.ts @@ -0,0 +1,120 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ErrorType } from '../../../basics/error-type'; +import { lognormalCDF, lognormalPDF } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; + +export class LognormDist extends BaseFunction { + override minParams = 4; + + override maxParams = 4; + + override calculate( + x: BaseValueObject, + mean: BaseValueObject, + standardDev: BaseValueObject, + cumulative: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getRowCount() : 1, + mean.isArray() ? (mean as ArrayValueObject).getRowCount() : 1, + standardDev.isArray() ? (standardDev as ArrayValueObject).getRowCount() : 1, + cumulative.isArray() ? (cumulative as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getColumnCount() : 1, + mean.isArray() ? (mean as ArrayValueObject).getColumnCount() : 1, + standardDev.isArray() ? (standardDev as ArrayValueObject).getColumnCount() : 1, + cumulative.isArray() ? (cumulative as ArrayValueObject).getColumnCount() : 1 + ); + + const xArray = expandArrayValueObject(maxRowLength, maxColumnLength, x, ErrorValueObject.create(ErrorType.NA)); + const meanArray = expandArrayValueObject(maxRowLength, maxColumnLength, mean, ErrorValueObject.create(ErrorType.NA)); + const standardDevArray = expandArrayValueObject(maxRowLength, maxColumnLength, standardDev, ErrorValueObject.create(ErrorType.NA)); + const cumulativeArray = expandArrayValueObject(maxRowLength, maxColumnLength, cumulative, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = xArray.mapValue((xObject, rowIndex, columnIndex) => { + const meanObject = meanArray.get(rowIndex, columnIndex) as BaseValueObject; + const standardDevObject = standardDevArray.get(rowIndex, columnIndex) as BaseValueObject; + const cumulativeObject = cumulativeArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (xObject.isError()) { + return xObject; + } + + if (meanObject.isError()) { + return meanObject; + } + + if (standardDevObject.isError()) { + return standardDevObject; + } + + if (cumulativeObject.isError()) { + return cumulativeObject; + } + + return this._handleSignleObject(xObject, meanObject, standardDevObject, cumulativeObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + xObject: BaseValueObject, + meanObject: BaseValueObject, + standardDevObject: BaseValueObject, + cumulativeObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(xObject, meanObject, standardDevObject, cumulativeObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_xObject, _meanObject, _standardDevObject, _cumulativeObject] = variants as BaseValueObject[]; + + const xValue = +_xObject.getValue(); + const meanValue = +_meanObject.getValue(); + const standardDevValue = +_standardDevObject.getValue(); + const cumulativeValue = +_cumulativeObject.getValue(); + + if (xValue <= 0 || standardDevValue <= 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + let result; + + if (cumulativeValue) { + result = lognormalCDF(xValue, meanValue, standardDevValue); + } else { + result = lognormalPDF(xValue, meanValue, standardDevValue); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/lognorm-inv/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/lognorm-inv/__tests__/index.spec.ts new file mode 100644 index 000000000000..a45c75319807 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/lognorm-inv/__tests__/index.spec.ts @@ -0,0 +1,118 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { LognormInv } from '../index'; + +describe('Test lognormInv function', () => { + const testFunction = new LognormInv(FUNCTION_NAMES_STATISTICAL.LOGNORM_INV); + + describe('LognormInv', () => { + it('Value is normal', () => { + const probability = NumberValueObject.create(0.2069); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const result = testFunction.calculate(probability, mean, standardDev); + expect(getObjectValue(result)).toBe(15.349777717590833); + }); + + it('StandardDev value test', () => { + const probability = NumberValueObject.create(0.2069); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(0); + const result = testFunction.calculate(probability, mean, standardDev); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Value is normal string', () => { + const probability = StringValueObject.create('test'); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const result = testFunction.calculate(probability, mean, standardDev); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const probability = BooleanValueObject.create(true); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const result = testFunction.calculate(probability, mean, standardDev); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Value is null', () => { + const probability = NullValueObject.create(); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const result = testFunction.calculate(probability, mean, standardDev); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Value is error', () => { + const probability = ErrorValueObject.create(ErrorType.NAME); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const result = testFunction.calculate(probability, mean, standardDev); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const probability2 = NumberValueObject.create(0.2069); + const mean2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(probability2, mean2, standardDev); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const standardDev2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(probability2, mean, standardDev2); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const probability = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const mean = NumberValueObject.create(6); + const standardDev = NumberValueObject.create(4); + const result = testFunction.calculate(probability, mean, standardDev); + expect(getObjectValue(result)).toStrictEqual([ + [ErrorType.NUM, ErrorType.VALUE, ErrorType.NUM, ErrorType.NUM, ErrorType.NUM, ErrorType.NUM], + [ErrorType.NUM, ErrorType.NUM, ErrorType.NUM, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + }); + + it('More test', () => { + const probability = NumberValueObject.create(0.012548); + const mean = NumberValueObject.create(100000); + const standardDev = NumberValueObject.create(1.987); + const result = testFunction.calculate(probability, mean, standardDev); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/lognorm-inv/index.ts b/packages/engine-formula/src/functions/statistical/lognorm-inv/index.ts new file mode 100644 index 000000000000..c03b74b59bcf --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/lognorm-inv/index.ts @@ -0,0 +1,107 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { lognormalINV } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class LognormInv extends BaseFunction { + override minParams = 3; + + override maxParams = 3; + + override calculate( + probability: BaseValueObject, + mean: BaseValueObject, + standardDev: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + probability.isArray() ? (probability as ArrayValueObject).getRowCount() : 1, + mean.isArray() ? (mean as ArrayValueObject).getRowCount() : 1, + standardDev.isArray() ? (standardDev as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + probability.isArray() ? (probability as ArrayValueObject).getColumnCount() : 1, + mean.isArray() ? (mean as ArrayValueObject).getColumnCount() : 1, + standardDev.isArray() ? (standardDev as ArrayValueObject).getColumnCount() : 1 + ); + + const probabilityArray = expandArrayValueObject(maxRowLength, maxColumnLength, probability, ErrorValueObject.create(ErrorType.NA)); + const meanArray = expandArrayValueObject(maxRowLength, maxColumnLength, mean, ErrorValueObject.create(ErrorType.NA)); + const standardDevArray = expandArrayValueObject(maxRowLength, maxColumnLength, standardDev, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = probabilityArray.mapValue((probabilityObject, rowIndex, columnIndex) => { + const meanObject = meanArray.get(rowIndex, columnIndex) as BaseValueObject; + const standardDevObject = standardDevArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (probabilityObject.isError()) { + return probabilityObject; + } + + if (meanObject.isError()) { + return meanObject; + } + + if (standardDevObject.isError()) { + return standardDevObject; + } + + return this._handleSignleObject(probabilityObject, meanObject, standardDevObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + probabilityObject: BaseValueObject, + meanObject: BaseValueObject, + standardDevObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(probabilityObject, meanObject, standardDevObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_probabilityObject, _meanObject, _standardDevObject] = variants as BaseValueObject[]; + + const probabilityValue = +_probabilityObject.getValue(); + const meanValue = +_meanObject.getValue(); + const standardDevValue = +_standardDevObject.getValue(); + + if (probabilityValue <= 0 || probabilityValue >= 1 || standardDevValue <= 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const result = lognormalINV(probabilityValue, meanValue, standardDevValue); + + if (Number.isNaN(result) || !Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/median/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/median/__tests__/index.spec.ts new file mode 100644 index 000000000000..99a22d51ee8f --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/median/__tests__/index.spec.ts @@ -0,0 +1,109 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Median } from '../index'; + +describe('Test median function', () => { + const testFunction = new Median(FUNCTION_NAMES_STATISTICAL.MEDIAN); + + describe('Median', () => { + it('Value is normal', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9], + ]), + rowCount: 3, + columnCount: 3, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(5); + }); + + it('Value is single cell = null/boolean/string/error/negtive number', () => { + const number = NumberValueObject.create(3); + const number2 = NullValueObject.create(); + const number3 = BooleanValueObject.create(true); + const number4 = StringValueObject.create('test'); + const number5 = ErrorValueObject.create(ErrorType.NAME); + const number6 = NumberValueObject.create(-3); + const result = testFunction.calculate(number, number2, number3, number4); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); + + const result2 = testFunction.calculate(number, number2, number3, number5); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); + + const result3 = testFunction.calculate(number, number2, number3, number6); + expect(getObjectValue(result3)).toStrictEqual(0); + }); + + it('Value is not has number', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [true, false, null, 'test', null, null], + ]), + rowCount: 1, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + }); + + it('More test', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + + const number2 = NumberValueObject.create(1); + const number3 = NumberValueObject.create(2); + const number4 = StringValueObject.create('3'); + const result2 = testFunction.calculate(number2, number3, number4); + expect(getObjectValue(result2)).toStrictEqual(2); + + const number5 = StringValueObject.create('test'); + const result3 = testFunction.calculate(number2, number3, number5); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.VALUE); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/median/index.ts b/packages/engine-formula/src/functions/statistical/median/index.ts new file mode 100644 index 000000000000..6ab4b36b5f57 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/median/index.ts @@ -0,0 +1,111 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Median extends BaseFunction { + override minParams = 1; + + override maxParams = 255; + + override calculate(...variants: BaseValueObject[]): BaseValueObject { + const values: number[] = []; + + for (let i = 0; i < variants.length; i++) { + const variant = variants[i]; + + if (variant.isArray()) { + let isError = false; + let errorObject = ErrorValueObject.create(ErrorType.VALUE); + + (variant as ArrayValueObject).iterator((valueObject) => { + if (valueObject?.isError()) { + isError = true; + errorObject = valueObject as ErrorValueObject; + return false; + } + + if (valueObject?.isNull() || valueObject?.isBoolean()) { + return true; + } + + const value = (valueObject as BaseValueObject).getValue(); + + if (!isRealNum(value)) { + return true; + } + + values.push(+value); + }); + + if (isError) { + return errorObject; + } + } else { + if (variant.isError()) { + return variant; + } + + if (variant.isNull() || variant.isBoolean()) { + continue; + } + + if (variant.isString()) { + const _variant = variant.convertToNumberObjectValue(); + + if (_variant.isError()) { + return _variant; + } + } + + const value = variant.getValue(); + + if (!isRealNum(value)) { + continue; + } + + values.push(+value); + } + } + + if (values.length === 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return this._getResult(values.sort((a, b) => a - b)); + } + + private _getResult(values: number[]): BaseValueObject { + const n = values.length; + + let result: number; + + if (n % 2 === 0) { + const mid = n / 2; + result = (values[mid - 1] + values[mid]) / 2; + } else { + result = values[Math.floor(n / 2)]; + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/mode-mult/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/mode-mult/__tests__/index.spec.ts new file mode 100644 index 000000000000..41fc4c061408 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/mode-mult/__tests__/index.spec.ts @@ -0,0 +1,119 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { ModeMult } from '../index'; + +describe('Test modeMult function', () => { + const testFunction = new ModeMult(FUNCTION_NAMES_STATISTICAL.MODE_MULT); + + describe('ModeMult', () => { + it('Value is normal', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3], + [2, 3, 4], + [4, 5, 6], + ]), + rowCount: 3, + columnCount: 3, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual([ + [2], + [3], + [4], + ]); + + const number2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3], + [4, 5, 6], + [7, 8, 8], + ]), + rowCount: 3, + columnCount: 3, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(number2); + expect(getObjectValue(result2)).toStrictEqual(8); + }); + + it('Value is single cell = null/boolean/string/error/negtive number', () => { + const number = NumberValueObject.create(3); + const number2 = NullValueObject.create(); + const number3 = BooleanValueObject.create(true); + const number4 = StringValueObject.create('test'); + const number5 = ErrorValueObject.create(ErrorType.NAME); + const number6 = NumberValueObject.create(-3); + const result = testFunction.calculate(number, number2, number3, number4); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); + + const result2 = testFunction.calculate(number, number2, number3, number5); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); + + const result3 = testFunction.calculate(number, number2, number3, number6); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.NA); + }); + + it('Value is not has number', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [true, false, null, 'test', null, null], + ]), + rowCount: 1, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NA); + }); + + it('More test', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/mode-mult/index.ts b/packages/engine-formula/src/functions/statistical/mode-mult/index.ts new file mode 100644 index 000000000000..fafbc71fd338 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/mode-mult/index.ts @@ -0,0 +1,109 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +type valueMapType = Record; + +export class ModeMult extends BaseFunction { + override minParams = 1; + + override maxParams = 255; + + override calculate(...variants: BaseValueObject[]): BaseValueObject { + const valueMap: valueMapType = {}; + + let order = 0; + let maxCount = 1; + + for (let i = 0; i < variants.length; i++) { + const variant = variants[i]; + + if (variant.isError()) { + return variant; + } + + if (variant.isString()) { + const _variant = variant.convertToNumberObjectValue(); + + if (_variant.isError()) { + return _variant; + } + } + + const rowCount = variant.isArray() ? (variant as ArrayValueObject).getRowCount() : 1; + const columnCount = variant.isArray() ? (variant as ArrayValueObject).getColumnCount() : 1; + + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const valueObject = variant.isArray() ? (variant as ArrayValueObject).get(r, c) as BaseValueObject : variant; + + if (valueObject.isError()) { + return valueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean() || valueObject.isString()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + if (valueMap[+value]) { + valueMap[+value].count++; + + if (valueMap[+value].count > maxCount) { + maxCount = valueMap[+value].count; + } + } else { + valueMap[+value] = { count: 1, order: order++ }; + } + } + } + } + + if (order === 0 || maxCount === 1) { + return new ErrorValueObject(ErrorType.NA); + } + + return this._getResult(valueMap, maxCount); + } + + private _getResult(valueMap: valueMapType, maxCount: number): BaseValueObject { + const result = Object.entries(valueMap) + .filter(([_, { count }]) => count === maxCount) + .sort((a, b) => a[1].order - b[1].order) + .map(([value]) => +value); + + if (result.length === 1) { + return NumberValueObject.create(result[0]); + } + + return ArrayValueObject.createByArray(result.map((value) => [value])); + } +} diff --git a/packages/engine-formula/src/functions/statistical/mode-sngl/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/mode-sngl/__tests__/index.spec.ts new file mode 100644 index 000000000000..ff2233456743 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/mode-sngl/__tests__/index.spec.ts @@ -0,0 +1,99 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { ModeSngl } from '../index'; + +describe('Test modeSngl function', () => { + const testFunction = new ModeSngl(FUNCTION_NAMES_STATISTICAL.MODE_SNGL); + + describe('ModeSngl', () => { + it('Value is normal', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3], + [2, 3, 4], + [4, 5, 6], + ]), + rowCount: 3, + columnCount: 3, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(2); + }); + + it('Value is single cell = null/boolean/string/error/negtive number', () => { + const number = NumberValueObject.create(3); + const number2 = NullValueObject.create(); + const number3 = BooleanValueObject.create(true); + const number4 = StringValueObject.create('test'); + const number5 = ErrorValueObject.create(ErrorType.NAME); + const number6 = NumberValueObject.create(-3); + const result = testFunction.calculate(number, number2, number3, number4); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); + + const result2 = testFunction.calculate(number, number2, number3, number5); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); + + const result3 = testFunction.calculate(number, number2, number3, number6); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.NA); + }); + + it('Value is not has number', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [true, false, null, 'test', null, null], + ]), + rowCount: 1, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NA); + }); + + it('More test', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/mode-sngl/index.ts b/packages/engine-formula/src/functions/statistical/mode-sngl/index.ts new file mode 100644 index 000000000000..918281b742bc --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/mode-sngl/index.ts @@ -0,0 +1,105 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +type valueMapType = Record; + +export class ModeSngl extends BaseFunction { + override minParams = 1; + + override maxParams = 255; + + override calculate(...variants: BaseValueObject[]): BaseValueObject { + const valueMap: valueMapType = {}; + + let order = 0; + let maxCount = 1; + + for (let i = 0; i < variants.length; i++) { + const variant = variants[i]; + + if (variant.isError()) { + return variant; + } + + if (variant.isString()) { + const _variant = variant.convertToNumberObjectValue(); + + if (_variant.isError()) { + return _variant; + } + } + + const rowCount = variant.isArray() ? (variant as ArrayValueObject).getRowCount() : 1; + const columnCount = variant.isArray() ? (variant as ArrayValueObject).getColumnCount() : 1; + + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const valueObject = variant.isArray() ? (variant as ArrayValueObject).get(r, c) as BaseValueObject : variant; + + if (valueObject.isError()) { + return valueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean() || valueObject.isString()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + if (valueMap[+value]) { + valueMap[+value].count++; + + if (valueMap[+value].count > maxCount) { + maxCount = valueMap[+value].count; + } + } else { + valueMap[+value] = { count: 1, order: order++ }; + } + } + } + } + + if (order === 0 || maxCount === 1) { + return new ErrorValueObject(ErrorType.NA); + } + + return this._getResult(valueMap, maxCount); + } + + private _getResult(valueMap: valueMapType, maxCount: number): BaseValueObject { + const result = Object.entries(valueMap) + .filter(([_, { count }]) => count === maxCount) + .sort((a, b) => a[1].order - b[1].order) + .map(([value]) => +value); + + return NumberValueObject.create(result[0]); + } +} diff --git a/packages/engine-formula/src/functions/statistical/negbinom-dist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/negbinom-dist/__tests__/index.spec.ts new file mode 100644 index 000000000000..9ca6f2f7d291 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/negbinom-dist/__tests__/index.spec.ts @@ -0,0 +1,166 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { NegbinomDist } from '../index'; + +describe('Test negbinomDist function', () => { + const testFunction = new NegbinomDist(FUNCTION_NAMES_STATISTICAL.NEGBINOM_DIST); + + describe('NegbinomDist', () => { + it('Value is normal', () => { + const numberF = NumberValueObject.create(6); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(0.5); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(numberF, numberS, probabilityS, cumulative); + expect(getObjectValue(result)).toBe(0.2272491455078125); + }); + + it('NumberF and numberS value test', () => { + const numberF = NumberValueObject.create(-6); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(0.5); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(numberF, numberS, probabilityS, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const numberF2 = NumberValueObject.create(11); + const numberS2 = NumberValueObject.create(0.1); + const result2 = testFunction.calculate(numberF2, numberS2, probabilityS, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + }); + + it('ProbabilityS value test', () => { + const numberF = NumberValueObject.create(6); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(-0.5); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(numberF, numberS, probabilityS, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const probabilityS2 = NumberValueObject.create(1.5); + const result2 = testFunction.calculate(numberF, numberS, probabilityS2, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + + const probabilityS3 = NumberValueObject.create(0); + const result3 = testFunction.calculate(numberF, numberS, probabilityS3, cumulative); + expect(getObjectValue(result3)).toBe(ErrorType.NUM); + + const probabilityS4 = NumberValueObject.create(1); + const result4 = testFunction.calculate(numberF, numberS, probabilityS4, cumulative); + expect(getObjectValue(result4)).toBe(ErrorType.NUM); + }); + + it('Cumulative value test', () => { + const numberF = NumberValueObject.create(6); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(0.5); + const cumulative = BooleanValueObject.create(false); + const result = testFunction.calculate(numberF, numberS, probabilityS, cumulative); + expect(getObjectValue(result)).toBe(0.0763702392578125); + + const numberF2 = NumberValueObject.create(0); + const numberS2 = NumberValueObject.create(0); + const result2 = testFunction.calculate(numberF2, numberS2, probabilityS, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + + const numberF3 = NumberValueObject.create(1); + const numberS3 = NumberValueObject.create(1); + const result3 = testFunction.calculate(numberF3, numberS3, probabilityS, cumulative); + expect(getObjectValue(result3)).toBe(0.25); + }); + + it('Value is normal string', () => { + const numberF = StringValueObject.create('test'); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(0.5); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(numberF, numberS, probabilityS, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const numberF = BooleanValueObject.create(true); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(0.5); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(numberF, numberS, probabilityS, cumulative); + expect(getObjectValue(result)).toBe(0.005859375); + }); + + it('Value is null', () => { + const numberF = NullValueObject.create(); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(0.5); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(numberF, numberS, probabilityS, cumulative); + expect(getObjectValue(result)).toBe(0.0009765625); + }); + + it('Value is error', () => { + const numberF = ErrorValueObject.create(ErrorType.NAME); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(0.5); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(numberF, numberS, probabilityS, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const numberF2 = NumberValueObject.create(6); + const numberS2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(numberF2, numberS2, probabilityS, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const probabilityS2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(numberF2, numberS, probabilityS2, cumulative); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const cumulative2 = ErrorValueObject.create(ErrorType.NAME); + const result4 = testFunction.calculate(numberF2, numberS, probabilityS, cumulative2); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const numberF = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const numberS = NumberValueObject.create(10); + const probabilityS = NumberValueObject.create(0.5); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(numberF, numberS, probabilityS, cumulative); + expect(getObjectValue(result)).toStrictEqual([ + [0.005859375, ErrorType.VALUE, 0.005859375, 0.005859375, 0.0009765625, 0.0009765625], + [0.0009765625, 0.9999999999999999, 0.019287109375, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/negbinom-dist/index.ts b/packages/engine-formula/src/functions/statistical/negbinom-dist/index.ts new file mode 100644 index 000000000000..e9eec0cf3ea2 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/negbinom-dist/index.ts @@ -0,0 +1,120 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { negbinomialCDF, negbinomialPDF } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class NegbinomDist extends BaseFunction { + override minParams = 4; + + override maxParams = 4; + + override calculate( + numberF: BaseValueObject, + numberS: BaseValueObject, + probabilityS: BaseValueObject, + cumulative: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + numberF.isArray() ? (numberF as ArrayValueObject).getRowCount() : 1, + numberS.isArray() ? (numberS as ArrayValueObject).getRowCount() : 1, + probabilityS.isArray() ? (probabilityS as ArrayValueObject).getRowCount() : 1, + cumulative.isArray() ? (cumulative as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + numberF.isArray() ? (numberF as ArrayValueObject).getColumnCount() : 1, + numberS.isArray() ? (numberS as ArrayValueObject).getColumnCount() : 1, + probabilityS.isArray() ? (probabilityS as ArrayValueObject).getColumnCount() : 1, + cumulative.isArray() ? (cumulative as ArrayValueObject).getColumnCount() : 1 + ); + + const numberFArray = expandArrayValueObject(maxRowLength, maxColumnLength, numberF, ErrorValueObject.create(ErrorType.NA)); + const numberSArray = expandArrayValueObject(maxRowLength, maxColumnLength, numberS, ErrorValueObject.create(ErrorType.NA)); + const probabilitySArray = expandArrayValueObject(maxRowLength, maxColumnLength, probabilityS, ErrorValueObject.create(ErrorType.NA)); + const cumulativeArray = expandArrayValueObject(maxRowLength, maxColumnLength, cumulative, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = numberFArray.mapValue((numberFObject, rowIndex, columnIndex) => { + const numberSObject = numberSArray.get(rowIndex, columnIndex) as BaseValueObject; + const probabilitySObject = probabilitySArray.get(rowIndex, columnIndex) as BaseValueObject; + const cumulativeObject = cumulativeArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (numberFObject.isError()) { + return numberFObject; + } + + if (numberSObject.isError()) { + return numberSObject; + } + + if (probabilitySObject.isError()) { + return probabilitySObject; + } + + if (cumulativeObject.isError()) { + return cumulativeObject; + } + + return this._handleSignleObject(numberFObject, numberSObject, probabilitySObject, cumulativeObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + numberFObject: BaseValueObject, + numberSObject: BaseValueObject, + probabilitySObject: BaseValueObject, + cumulativeObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(numberFObject, numberSObject, probabilitySObject, cumulativeObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_numberFObject, _numberSObject, _probabilitySObject, _cumulativeObject] = variants as BaseValueObject[]; + + const numberFValue = Math.floor(+_numberFObject.getValue()); + const numberSValue = Math.floor(+_numberSObject.getValue()); + const probabilitySValue = +_probabilitySObject.getValue(); + const cumulativeValue = +_cumulativeObject.getValue(); + + if (numberFValue < 0 || numberSValue < 1 || probabilitySValue <= 0 || probabilitySValue >= 1) { + return ErrorValueObject.create(ErrorType.NUM); + } + + let result; + + if (cumulativeValue) { + result = negbinomialCDF(numberFValue, numberSValue, probabilitySValue); + } else { + result = negbinomialPDF(numberFValue, numberSValue, probabilitySValue); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/norm-dist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/norm-dist/__tests__/index.spec.ts index 8fbac21f5629..3e872d65d4c0 100644 --- a/packages/engine-formula/src/functions/statistical/norm-dist/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/norm-dist/__tests__/index.spec.ts @@ -89,6 +89,19 @@ describe('Test normDist function', () => { const cumulative = BooleanValueObject.create(true); const result = testFunction.calculate(x, mean, standardDev, cumulative); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(15.2069); + const mean2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, mean2, standardDev, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const standardDev2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(x2, mean, standardDev2, cumulative); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const cumulative2 = ErrorValueObject.create(ErrorType.NAME); + const result4 = testFunction.calculate(x2, mean, standardDev, cumulative2); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/norm-dist/index.ts b/packages/engine-formula/src/functions/statistical/norm-dist/index.ts index 1cae84f44bc4..ac1bf29ec8eb 100644 --- a/packages/engine-formula/src/functions/statistical/norm-dist/index.ts +++ b/packages/engine-formula/src/functions/statistical/norm-dist/index.ts @@ -58,6 +58,22 @@ export class NormDist extends BaseFunction { const standardDevObject = standardDevArray.get(rowIndex, columnIndex) as BaseValueObject; const cumulativeObject = cumulativeArray.get(rowIndex, columnIndex) as BaseValueObject; + if (xObject.isError()) { + return xObject; + } + + if (meanObject.isError()) { + return meanObject; + } + + if (standardDevObject.isError()) { + return standardDevObject; + } + + if (cumulativeObject.isError()) { + return cumulativeObject; + } + return this._handleSignleObject(xObject, meanObject, standardDevObject, cumulativeObject); }); diff --git a/packages/engine-formula/src/functions/statistical/norm-inv/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/norm-inv/__tests__/index.spec.ts index 955c3090a774..42f7a7b807b5 100644 --- a/packages/engine-formula/src/functions/statistical/norm-inv/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/norm-inv/__tests__/index.spec.ts @@ -74,6 +74,15 @@ describe('Test normInv function', () => { const standardDev = NumberValueObject.create(4); const result = testFunction.calculate(probability, mean, standardDev); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const probability2 = NumberValueObject.create(0.2069); + const mean2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(probability2, mean2, standardDev); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const standardDev2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(probability2, mean, standardDev2); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/norm-inv/index.ts b/packages/engine-formula/src/functions/statistical/norm-inv/index.ts index 2dbe7d017aef..4a0d954a0e97 100644 --- a/packages/engine-formula/src/functions/statistical/norm-inv/index.ts +++ b/packages/engine-formula/src/functions/statistical/norm-inv/index.ts @@ -53,6 +53,18 @@ export class NormInv extends BaseFunction { const meanObject = meanArray.get(rowIndex, columnIndex) as BaseValueObject; const standardDevObject = standardDevArray.get(rowIndex, columnIndex) as BaseValueObject; + if (probabilityObject.isError()) { + return probabilityObject; + } + + if (meanObject.isError()) { + return meanObject; + } + + if (standardDevObject.isError()) { + return standardDevObject; + } + return this._handleSignleObject(probabilityObject, meanObject, standardDevObject); }); diff --git a/packages/engine-formula/src/functions/statistical/norm-s-dist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/norm-s-dist/__tests__/index.spec.ts index 37bb0f92e57d..a115b217ba12 100644 --- a/packages/engine-formula/src/functions/statistical/norm-s-dist/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/statistical/norm-s-dist/__tests__/index.spec.ts @@ -68,6 +68,11 @@ describe('Test normSDist function', () => { const cumulative = BooleanValueObject.create(true); const result = testFunction.calculate(z, cumulative); expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const z2 = NumberValueObject.create(1.2069); + const cumulative2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(z2, cumulative2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); }); it('Value is array', () => { diff --git a/packages/engine-formula/src/functions/statistical/norm-s-dist/index.ts b/packages/engine-formula/src/functions/statistical/norm-s-dist/index.ts index c20f15b2186c..bc019e985040 100644 --- a/packages/engine-formula/src/functions/statistical/norm-s-dist/index.ts +++ b/packages/engine-formula/src/functions/statistical/norm-s-dist/index.ts @@ -48,6 +48,14 @@ export class NormSDist extends BaseFunction { const resultArray = zArray.mapValue((zObject, rowIndex, columnIndex) => { const cumulativeObject = cumulativeArray.get(rowIndex, columnIndex) as BaseValueObject; + if (zObject.isError()) { + return zObject; + } + + if (cumulativeObject.isError()) { + return cumulativeObject; + } + return this._handleSignleObject(zObject, cumulativeObject); }); diff --git a/packages/engine-formula/src/functions/statistical/pearson/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/pearson/__tests__/index.spec.ts new file mode 100644 index 000000000000..4653375cf2a7 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/pearson/__tests__/index.spec.ts @@ -0,0 +1,311 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { NullValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Pearson } from '../index'; + +describe('Test pearson function', () => { + const testFunction = new Pearson(FUNCTION_NAMES_STATISTICAL.PEARSON); + + describe('Pearson', () => { + it('Value is normal', () => { + const array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array1, array2); + expect(getObjectValue(result)).toBe(0.8355334373537249); + }); + + it('Value length is equal to 1', () => { + const array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array1, array2); + expect(getObjectValue(result)).toBe(ErrorType.DIV_BY_ZERO); + }); + + it('Value length is not equal', () => { + const array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + ]), + rowCount: 2, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array1, array2); + expect(getObjectValue(result)).toBe(ErrorType.NA); + }); + + it('Value is error', () => { + const array1 = ErrorValueObject.create(ErrorType.NAME); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array1, array2); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const array3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array4 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(array3, array4); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const array5 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [ErrorType.NAME, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array6 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result3 = testFunction.calculate(array5, array6); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const array7 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array8 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [ErrorType.NAME, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result4 = testFunction.calculate(array7, array8); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); + }); + + it('Value is null', () => { + const array1 = NullValueObject.create(); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array1, array2); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + + const array3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array4 = NullValueObject.create(); + const result2 = testFunction.calculate(array3, array4); + expect(getObjectValue(result2)).toBe(ErrorType.VALUE); + }); + + it('Value is can not calculate', () => { + const array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, null], + [11, 'test'], + [10, true], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [false, 47.65], + [null, 18.44], + ['test', 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array1, array2); + expect(getObjectValue(result)).toBe(ErrorType.DIV_BY_ZERO); + }); + + it('Array2Variance === 0', () => { + const array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [2], + [1], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [1], + [1], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array1, array2); + expect(getObjectValue(result)).toBe(ErrorType.DIV_BY_ZERO); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/pearson/index.ts b/packages/engine-formula/src/functions/statistical/pearson/index.ts new file mode 100644 index 000000000000..04e989d522b6 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/pearson/index.ts @@ -0,0 +1,125 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ErrorType } from '../../../basics/error-type'; +import { getTwoArrayNumberValues } from '../../../basics/statistical'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; + +export class Pearson extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate(array1: BaseValueObject, array2: BaseValueObject): BaseValueObject { + const array1RowCount = array1.isArray() ? (array1 as ArrayValueObject).getRowCount() : 1; + const array1ColumnCount = array1.isArray() ? (array1 as ArrayValueObject).getColumnCount() : 1; + + const array2RowCount = array2.isArray() ? (array2 as ArrayValueObject).getRowCount() : 1; + const array2ColumnCount = array2.isArray() ? (array2 as ArrayValueObject).getColumnCount() : 1; + + let _array1 = array1; + + if (array1.isArray() && array1RowCount === 1 && array1ColumnCount === 1) { + _array1 = (array1 as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_array1.isError()) { + return _array1; + } + + let _array2 = array2; + + if (array2.isArray() && array2RowCount === 1 && array2ColumnCount === 1) { + _array2 = (array2 as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_array2.isError()) { + return _array2; + } + + if (array1RowCount * array1ColumnCount === 1 || array2RowCount * array2ColumnCount === 1) { + if (_array1.isNull() || _array2.isNull()) { + return ErrorValueObject.create(ErrorType.VALUE); + } + + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + if (array1RowCount * array1ColumnCount !== array2RowCount * array2ColumnCount) { + return ErrorValueObject.create(ErrorType.NA); + } + + const { + isError, + errorObject, + array1Values, + array2Values, + noCalculate, + } = getTwoArrayNumberValues( + array1, + array2, + array1RowCount * array1ColumnCount, + array1ColumnCount, + array2ColumnCount + ); + + if (isError) { + return errorObject as ErrorValueObject; + } + + if (noCalculate) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + return this._getResult(array1Values, array2Values); + } + + private _getResult(array1: number[], array2: number[]): BaseValueObject { + const n = array1.length; + + let sumX = 0; + let sumY = 0; + + for (let i = 0; i < n; i++) { + sumX += array1[i]; + sumY += array2[i]; + } + + const meanX = sumX / n; + const meanY = sumY / n; + + let num = 0; + let den1 = 0; + let den2 = 0; + + for (let i = 0; i < n; i++) { + num += (array1[i] - meanX) * (array2[i] - meanY); + den1 += (array1[i] - meanX) ** 2; + den2 += (array2[i] - meanY) ** 2; + } + + if (den1 === 0 || den2 === 0) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + const result = num / Math.sqrt(den1 * den2); + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/percentile-exc/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/percentile-exc/__tests__/index.spec.ts new file mode 100644 index 000000000000..0dc07d912315 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/percentile-exc/__tests__/index.spec.ts @@ -0,0 +1,160 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { PercentileExc } from '../index'; + +describe('Test percentileExc function', () => { + const testFunction = new PercentileExc(FUNCTION_NAMES_STATISTICAL.PERCENTILE_EXC); + + describe('PercentileExc', () => { + it('Value is normal', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(0.3); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(3.3); + }); + + it('Value is number string', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + ['\'1', '\'2', '\'3', '\'4', '\'5', '\'6', '\'7', '\'8', '\'9', '\'10'], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(0.3); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + }); + + it('Array value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, null, true, false, 'test', 6, 7, 8, 9, ErrorType.NAME], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(0.3); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null, true, false, 'test'], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(array2, k); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NUM); + }); + + it('K value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(0.1); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(1.1); + + const k2 = NumberValueObject.create(0.9); + const result2 = testFunction.calculate(array, k2); + expect(getObjectValue(result2)).toStrictEqual(9.9); + + const k3 = BooleanValueObject.create(true); + const result3 = testFunction.calculate(array, k3); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.NUM); + + const k4 = NullValueObject.create(); + const result4 = testFunction.calculate(array, k4); + expect(getObjectValue(result4)).toStrictEqual(ErrorType.NUM); + + const k5 = StringValueObject.create('test'); + const result5 = testFunction.calculate(array, k5); + expect(getObjectValue(result5)).toStrictEqual(ErrorType.VALUE); + + const k6 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(array, k6); + expect(getObjectValue(result6)).toStrictEqual(ErrorType.NAME); + + const k7 = ArrayValueObject.create('{0.09,0.5,3}'); + const result7 = testFunction.calculate(array, k7); + expect(getObjectValue(result7)).toStrictEqual([ + [ErrorType.NUM, 5.5, ErrorType.NUM], + ]); + + const k8 = ArrayValueObject.create('{0.123}'); + const result8 = testFunction.calculate(array, k8); + expect(getObjectValue(result8)).toStrictEqual(1.353); + }); + + it('More test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9], + ]), + rowCount: 1, + columnCount: 9, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(0.3); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(3); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/percentile-exc/index.ts b/packages/engine-formula/src/functions/statistical/percentile-exc/index.ts new file mode 100644 index 000000000000..7e41a55c9c47 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/percentile-exc/index.ts @@ -0,0 +1,115 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class PercentileExc extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate(array: BaseValueObject, k: BaseValueObject): BaseValueObject { + const arrayValues = this._getValues(array); + + if (k.isArray()) { + const resultArray = (k as ArrayValueObject).mapValue((kObject) => this._handleSingleObject(arrayValues, kObject)); + + if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + return this._handleSingleObject(arrayValues, k); + } + + private _handleSingleObject(array: number[] | ErrorValueObject, k: BaseValueObject): BaseValueObject { + if (array instanceof ErrorValueObject) { + return array; + } + + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(k); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [kObject] = variants as BaseValueObject[]; + + const kValue = +kObject.getValue(); + + const n = array.length; + + if (kValue < 1 / (n + 1) || kValue > 1 - 1 / (n + 1)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const kValueIndex = kValue * (n + 1) - 1; + const integerPart = Math.floor(kValueIndex); + const fractionPart = kValueIndex - integerPart; + + if (fractionPart === 0) { + return NumberValueObject.create(array[integerPart]); + } + + const result = array[integerPart] + fractionPart * (array[integerPart + 1] - array[integerPart]); + + return NumberValueObject.create(result); + } + + private _getValues(array: BaseValueObject): number[] | ErrorValueObject { + const rowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; + const columnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; + + const values: number[] = []; + + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const valueObject = array.isArray() ? (array as ArrayValueObject).get(r, c) as BaseValueObject : array; + + if (valueObject.isError()) { + return valueObject as ErrorValueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean() || valueObject.isString()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + values.push(+value); + } + } + + if (values.length === 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return values.sort((a, b) => a - b); + } +} diff --git a/packages/engine-formula/src/functions/statistical/percentile-inc/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/percentile-inc/__tests__/index.spec.ts new file mode 100644 index 000000000000..c72fd8f41d93 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/percentile-inc/__tests__/index.spec.ts @@ -0,0 +1,143 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { PercentileInc } from '../index'; + +describe('Test percentileInc function', () => { + const testFunction = new PercentileInc(FUNCTION_NAMES_STATISTICAL.PERCENTILE_INC); + + describe('PercentileInc', () => { + it('Value is normal', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(0.3); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(3.6999999999999997); + }); + + it('Value is number string', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + ['\'1', '\'2', '\'3', '\'4', '\'5', '\'6', '\'7', '\'8', '\'9', '\'10'], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(0.3); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + }); + + it('Array value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, null, true, false, 'test', 6, 7, 8, 9, ErrorType.NAME], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(0.3); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null, true, false, 'test'], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(array2, k); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NUM); + }); + + it('K value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(0.1); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(1.9); + + const k2 = NumberValueObject.create(0.9); + const result2 = testFunction.calculate(array, k2); + expect(getObjectValue(result2)).toStrictEqual(9.1); + + const k3 = BooleanValueObject.create(true); + const result3 = testFunction.calculate(array, k3); + expect(getObjectValue(result3)).toStrictEqual(10); + + const k4 = NullValueObject.create(); + const result4 = testFunction.calculate(array, k4); + expect(getObjectValue(result4)).toStrictEqual(1); + + const k5 = StringValueObject.create('test'); + const result5 = testFunction.calculate(array, k5); + expect(getObjectValue(result5)).toStrictEqual(ErrorType.VALUE); + + const k6 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(array, k6); + expect(getObjectValue(result6)).toStrictEqual(ErrorType.NAME); + + const k7 = ArrayValueObject.create('{0.09,0.5,3}'); + const result7 = testFunction.calculate(array, k7); + expect(getObjectValue(result7)).toStrictEqual([ + [1.81, 5.5, ErrorType.NUM], + ]); + + const k8 = ArrayValueObject.create('{0.123}'); + const result8 = testFunction.calculate(array, k8); + expect(getObjectValue(result8)).toStrictEqual(2.107); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/percentile-inc/index.ts b/packages/engine-formula/src/functions/statistical/percentile-inc/index.ts new file mode 100644 index 000000000000..5cd737af8a11 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/percentile-inc/index.ts @@ -0,0 +1,115 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class PercentileInc extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate(array: BaseValueObject, k: BaseValueObject): BaseValueObject { + const arrayValues = this._getValues(array); + + if (k.isArray()) { + const resultArray = (k as ArrayValueObject).mapValue((kObject) => this._handleSingleObject(arrayValues, kObject)); + + if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + return this._handleSingleObject(arrayValues, k); + } + + private _handleSingleObject(array: number[] | ErrorValueObject, k: BaseValueObject): BaseValueObject { + if (array instanceof ErrorValueObject) { + return array; + } + + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(k); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [kObject] = variants as BaseValueObject[]; + + const kValue = +kObject.getValue(); + + const n = array.length; + + if (kValue < 0 || kValue > 1) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const kValueIndex = kValue * (n - 1); + const integerPart = Math.floor(kValueIndex); + const fractionPart = kValueIndex - integerPart; + + if (fractionPart === 0) { + return NumberValueObject.create(array[integerPart]); + } + + const result = array[integerPart] + fractionPart * (array[integerPart + 1] - array[integerPart]); + + return NumberValueObject.create(result); + } + + private _getValues(array: BaseValueObject): number[] | ErrorValueObject { + const rowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; + const columnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; + + const values: number[] = []; + + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const valueObject = array.isArray() ? (array as ArrayValueObject).get(r, c) as BaseValueObject : array; + + if (valueObject.isError()) { + return valueObject as ErrorValueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean() || valueObject.isString()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + values.push(+value); + } + } + + if (values.length === 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return values.sort((a, b) => a - b); + } +} diff --git a/packages/engine-formula/src/functions/statistical/percentrank-exc/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/percentrank-exc/__tests__/index.spec.ts new file mode 100644 index 000000000000..830a944fa4fc --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/percentrank-exc/__tests__/index.spec.ts @@ -0,0 +1,213 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { PercentrankExc } from '../index'; + +describe('Test percentrankExc function', () => { + const testFunction = new PercentrankExc(FUNCTION_NAMES_STATISTICAL.PERCENTRANK_EXC); + + describe('PercentrankExc', () => { + it('Value is normal', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = NumberValueObject.create(3.3); + const significance = NullValueObject.create(); + const result = testFunction.calculate(array, x, significance); + expect(getObjectValue(result)).toStrictEqual(0.3); + }); + + it('Array value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, null, true, false, 'test', 6, 7, 8, 9, ErrorType.NAME], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = NumberValueObject.create(3.3); + const result = testFunction.calculate(array, x); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null, true, false, 'test'], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(array2, x); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NA); + + const array3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [-1], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result3 = testFunction.calculate(array3, x); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.NA); + + const x2 = NumberValueObject.create(-1); + const result4 = testFunction.calculate(array3, x2); + expect(getObjectValue(result4)).toStrictEqual(1); + }); + + it('X value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = NumberValueObject.create(0.1); + const result = testFunction.calculate(array, x); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NA); + + const x2 = NumberValueObject.create(11); + const result2 = testFunction.calculate(array, x2); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NA); + + const x3 = BooleanValueObject.create(true); + const result3 = testFunction.calculate(array, x3); + expect(getObjectValue(result3)).toStrictEqual(0.09); + + const x4 = NullValueObject.create(); + const result4 = testFunction.calculate(array, x4); + expect(getObjectValue(result4)).toStrictEqual(ErrorType.NA); + + const x5 = StringValueObject.create('test'); + const result5 = testFunction.calculate(array, x5); + expect(getObjectValue(result5)).toStrictEqual(ErrorType.VALUE); + + const x6 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(array, x6); + expect(getObjectValue(result6)).toStrictEqual(ErrorType.NAME); + + const x7 = ArrayValueObject.create('{2,5.5,13}'); + const result7 = testFunction.calculate(array, x7); + expect(getObjectValue(result7)).toStrictEqual([ + [0.181, 0.5, ErrorType.NA], + ]); + + const k8 = ArrayValueObject.create('{5.123}'); + const result8 = testFunction.calculate(array, k8); + expect(getObjectValue(result8)).toStrictEqual(0.465); + }); + + it('Significance value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = NumberValueObject.create(5.123); + const significance = NumberValueObject.create(10); + const result = testFunction.calculate(array, x, significance); + expect(getObjectValue(result)).toStrictEqual(0.4657272727); + + const significance2 = BooleanValueObject.create(true); + const result2 = testFunction.calculate(array, x, significance2); + expect(getObjectValue(result2)).toStrictEqual(0.4); + + const significance3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result3 = testFunction.calculate(array, x, significance3); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.NUM); + + const significance4 = StringValueObject.create('test'); + const result4 = testFunction.calculate(array, x, significance4); + expect(getObjectValue(result4)).toStrictEqual(ErrorType.VALUE); + + const significance5 = ErrorValueObject.create(ErrorType.NAME); + const result5 = testFunction.calculate(array, x, significance5); + expect(getObjectValue(result5)).toStrictEqual(ErrorType.NAME); + + const significance6 = ArrayValueObject.create('{2,5.5,13}'); + const result6 = testFunction.calculate(array, x, significance6); + expect(getObjectValue(result6)).toStrictEqual([ + [0.46, 0.46572, 0.4657272727272], + ]); + }); + + it('More test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null, 'test'], + ]), + rowCount: 1, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = StringValueObject.create('test'); + const significance = NullValueObject.create(); + const result = testFunction.calculate(array, x, significance); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/percentrank-exc/index.ts b/packages/engine-formula/src/functions/statistical/percentrank-exc/index.ts new file mode 100644 index 000000000000..0417134f019b --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/percentrank-exc/index.ts @@ -0,0 +1,165 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { floor } from '../../../engine/utils/math-kit'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class PercentrankExc extends BaseFunction { + override minParams = 2; + + override maxParams = 3; + + override calculate(array: BaseValueObject, x: BaseValueObject, significance?: BaseValueObject): BaseValueObject { + const arrayValues = this._getValues(array); + + let _significance = significance ?? NumberValueObject.create(3); + + if (_significance.isNull()) { + _significance = NumberValueObject.create(3); + } + + const maxRowLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getRowCount() : 1, + _significance.isArray() ? (_significance as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getColumnCount() : 1, + _significance.isArray() ? (_significance as ArrayValueObject).getColumnCount() : 1 + ); + + const xArray = expandArrayValueObject(maxRowLength, maxColumnLength, x, ErrorValueObject.create(ErrorType.NA)); + const significanceArray = expandArrayValueObject(maxRowLength, maxColumnLength, _significance, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = xArray.mapValue((xObject, rowIndex, columnIndex) => { + const significanceObject = significanceArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (xObject.isError()) { + return xObject; + } + + if (significanceObject.isError()) { + return significanceObject; + } + + return this._handleSingleObject(arrayValues, xObject, significanceObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSingleObject(array: number[] | ErrorValueObject, x: BaseValueObject, significance: BaseValueObject): BaseValueObject { + if (array instanceof ErrorValueObject) { + return array; + } + + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(x, significance); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [xObject, significanceObject] = variants as BaseValueObject[]; + + const xValue = +xObject.getValue(); + const significanceValue = Math.floor(+significanceObject.getValue()); + + const n = array.length; + + if (n === 0 || xValue < array[0] || xValue > array[n - 1]) { + return ErrorValueObject.create(ErrorType.NA); + } + + if (n === 1) { + if (xValue === array[0]) { + return NumberValueObject.create(1); + } else { + return ErrorValueObject.create(ErrorType.NA); + } + } + + let result = 0; + let match = false; + let i = 0; + + while (!match && i < n) { + if (xValue === array[i]) { + result = (i + 1) / (n + 1); + match = true; + } else if (xValue > array[i] && i + 1 < n && xValue < array[i + 1]) { + result = (i + 1 + (xValue - array[i]) / (array[i + 1] - array[i])) / (n + 1); + match = true; + } + + i++; + } + + if (!match) { + return ErrorValueObject.create(ErrorType.NA); + } + + if (significanceValue < 1) { + return ErrorValueObject.create(ErrorType.NUM); + } + + result = floor(result, significanceValue); + + return NumberValueObject.create(result); + } + + private _getValues(array: BaseValueObject): number[] | ErrorValueObject { + const rowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; + const columnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; + + const values: number[] = []; + + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const valueObject = array.isArray() ? (array as ArrayValueObject).get(r, c) as BaseValueObject : array; + + if (valueObject.isError()) { + return valueObject as ErrorValueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + values.push(+value); + } + } + + return values.sort((a, b) => a - b); + } +} diff --git a/packages/engine-formula/src/functions/statistical/percentrank-inc/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/percentrank-inc/__tests__/index.spec.ts new file mode 100644 index 000000000000..fbd9a2be3e98 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/percentrank-inc/__tests__/index.spec.ts @@ -0,0 +1,213 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { PercentrankInc } from '../index'; + +describe('Test percentrankInc function', () => { + const testFunction = new PercentrankInc(FUNCTION_NAMES_STATISTICAL.PERCENTRANK_INC); + + describe('PercentrankInc', () => { + it('Value is normal', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = NumberValueObject.create(3.3); + const significance = NullValueObject.create(); + const result = testFunction.calculate(array, x, significance); + expect(getObjectValue(result)).toStrictEqual(0.255); + }); + + it('Array value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, null, true, false, 'test', 6, 7, 8, 9, ErrorType.NAME], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = NumberValueObject.create(3.3); + const result = testFunction.calculate(array, x); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null, true, false, 'test'], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(array2, x); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NA); + + const array3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [-1], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result3 = testFunction.calculate(array3, x); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.NA); + + const x2 = NumberValueObject.create(-1); + const result4 = testFunction.calculate(array3, x2); + expect(getObjectValue(result4)).toStrictEqual(1); + }); + + it('X value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = NumberValueObject.create(0.1); + const result = testFunction.calculate(array, x); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NA); + + const x2 = NumberValueObject.create(11); + const result2 = testFunction.calculate(array, x2); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NA); + + const x3 = BooleanValueObject.create(true); + const result3 = testFunction.calculate(array, x3); + expect(getObjectValue(result3)).toStrictEqual(0); + + const x4 = NullValueObject.create(); + const result4 = testFunction.calculate(array, x4); + expect(getObjectValue(result4)).toStrictEqual(ErrorType.NA); + + const x5 = StringValueObject.create('test'); + const result5 = testFunction.calculate(array, x5); + expect(getObjectValue(result5)).toStrictEqual(ErrorType.VALUE); + + const x6 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(array, x6); + expect(getObjectValue(result6)).toStrictEqual(ErrorType.NAME); + + const x7 = ArrayValueObject.create('{2,5.5,13}'); + const result7 = testFunction.calculate(array, x7); + expect(getObjectValue(result7)).toStrictEqual([ + [0.111, 0.5, ErrorType.NA], + ]); + + const k8 = ArrayValueObject.create('{5.123}'); + const result8 = testFunction.calculate(array, k8); + expect(getObjectValue(result8)).toStrictEqual(0.458); + }); + + it('Significance value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = NumberValueObject.create(5.123); + const significance = NumberValueObject.create(10); + const result = testFunction.calculate(array, x, significance); + expect(getObjectValue(result)).toStrictEqual(0.4581111111); + + const significance2 = BooleanValueObject.create(true); + const result2 = testFunction.calculate(array, x, significance2); + expect(getObjectValue(result2)).toStrictEqual(0.4); + + const significance3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result3 = testFunction.calculate(array, x, significance3); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.NUM); + + const significance4 = StringValueObject.create('test'); + const result4 = testFunction.calculate(array, x, significance4); + expect(getObjectValue(result4)).toStrictEqual(ErrorType.VALUE); + + const significance5 = ErrorValueObject.create(ErrorType.NAME); + const result5 = testFunction.calculate(array, x, significance5); + expect(getObjectValue(result5)).toStrictEqual(ErrorType.NAME); + + const significance6 = ArrayValueObject.create('{2,5.5,13}'); + const result6 = testFunction.calculate(array, x, significance6); + expect(getObjectValue(result6)).toStrictEqual([ + [0.45, 0.45811, 0.4581111111111], + ]); + }); + + it('More test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null, 'test'], + ]), + rowCount: 1, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = StringValueObject.create('test'); + const significance = NullValueObject.create(); + const result = testFunction.calculate(array, x, significance); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/percentrank-inc/index.ts b/packages/engine-formula/src/functions/statistical/percentrank-inc/index.ts new file mode 100644 index 000000000000..9a1d5f81f20d --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/percentrank-inc/index.ts @@ -0,0 +1,165 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { floor } from '../../../engine/utils/math-kit'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class PercentrankInc extends BaseFunction { + override minParams = 2; + + override maxParams = 3; + + override calculate(array: BaseValueObject, x: BaseValueObject, significance?: BaseValueObject): BaseValueObject { + const arrayValues = this._getValues(array); + + let _significance = significance ?? NumberValueObject.create(3); + + if (_significance.isNull()) { + _significance = NumberValueObject.create(3); + } + + const maxRowLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getRowCount() : 1, + _significance.isArray() ? (_significance as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getColumnCount() : 1, + _significance.isArray() ? (_significance as ArrayValueObject).getColumnCount() : 1 + ); + + const xArray = expandArrayValueObject(maxRowLength, maxColumnLength, x, ErrorValueObject.create(ErrorType.NA)); + const significanceArray = expandArrayValueObject(maxRowLength, maxColumnLength, _significance, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = xArray.mapValue((xObject, rowIndex, columnIndex) => { + const significanceObject = significanceArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (xObject.isError()) { + return xObject; + } + + if (significanceObject.isError()) { + return significanceObject; + } + + return this._handleSingleObject(arrayValues, xObject, significanceObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSingleObject(array: number[] | ErrorValueObject, x: BaseValueObject, significance: BaseValueObject): BaseValueObject { + if (array instanceof ErrorValueObject) { + return array; + } + + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(x, significance); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [xObject, significanceObject] = variants as BaseValueObject[]; + + const xValue = +xObject.getValue(); + const significanceValue = Math.floor(+significanceObject.getValue()); + + const n = array.length; + + if (n === 0 || xValue < array[0] || xValue > array[n - 1]) { + return ErrorValueObject.create(ErrorType.NA); + } + + if (n === 1) { + if (xValue === array[0]) { + return NumberValueObject.create(1); + } else { + return ErrorValueObject.create(ErrorType.NA); + } + } + + let result = 0; + let match = false; + let i = 0; + + while (!match && i < n) { + if (xValue === array[i]) { + result = i / (n - 1); + match = true; + } else if (xValue > array[i] && i + 1 < n && xValue < array[i + 1]) { + result = (i + (xValue - array[i]) / (array[i + 1] - array[i])) / (n - 1); + match = true; + } + + i++; + } + + if (!match) { + return ErrorValueObject.create(ErrorType.NA); + } + + if (significanceValue < 1) { + return ErrorValueObject.create(ErrorType.NUM); + } + + result = floor(result, significanceValue); + + return NumberValueObject.create(result); + } + + private _getValues(array: BaseValueObject): number[] | ErrorValueObject { + const rowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; + const columnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; + + const values: number[] = []; + + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const valueObject = array.isArray() ? (array as ArrayValueObject).get(r, c) as BaseValueObject : array; + + if (valueObject.isError()) { + return valueObject as ErrorValueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + values.push(+value); + } + } + + return values.sort((a, b) => a - b); + } +} diff --git a/packages/engine-formula/src/functions/statistical/permut/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/permut/__tests__/index.spec.ts new file mode 100644 index 000000000000..7a44d1e42bd4 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/permut/__tests__/index.spec.ts @@ -0,0 +1,111 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Permut } from '../index'; + +describe('Test permut function', () => { + const testFunction = new Permut(FUNCTION_NAMES_STATISTICAL.PERMUT); + + describe('Permut', () => { + it('Value is normal number', () => { + const number = NumberValueObject.create(8); + const numberChosen = NumberValueObject.create(2); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(56); + }); + + it('Value is big number', () => { + const number = NumberValueObject.create(1000000); + const numberChosen = NumberValueObject.create(2000); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Value is number negative', () => { + const number = NumberValueObject.create(8); + const numberChosen = NumberValueObject.create(-2); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Value is number string', () => { + const number = NumberValueObject.create(8); + const numberChosen = StringValueObject.create('1.5'); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(8); + }); + + it('Value is normal string', () => { + const number = NumberValueObject.create(8); + const numberChosen = StringValueObject.create('test'); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const number = NumberValueObject.create(8); + const numberChosen = BooleanValueObject.create(true); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(8); + }); + it('Value is blank cell', () => { + const number = NumberValueObject.create(8); + const numberChosen = NullValueObject.create(); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(1); + }); + it('Value is error', () => { + const number = ErrorValueObject.create(ErrorType.NAME); + const numberChosen = NumberValueObject.create(2); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const number2 = NumberValueObject.create(8); + const numberChosen2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(number2, numberChosen2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const numberChosen = NumberValueObject.create(2); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toStrictEqual([ + [ErrorType.NUM, ErrorType.VALUE, ErrorType.NUM, ErrorType.NUM, ErrorType.NUM, ErrorType.NUM], + [ErrorType.NUM, 9900, 2, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/permut/index.ts b/packages/engine-formula/src/functions/statistical/permut/index.ts new file mode 100644 index 000000000000..b689cd43c0a0 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/permut/index.ts @@ -0,0 +1,89 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Permut extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate(number: BaseValueObject, numberChosen: BaseValueObject): BaseValueObject { + const maxRowLength = Math.max( + number.isArray() ? (number as ArrayValueObject).getRowCount() : 1, + numberChosen.isArray() ? (numberChosen as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + number.isArray() ? (number as ArrayValueObject).getColumnCount() : 1, + numberChosen.isArray() ? (numberChosen as ArrayValueObject).getColumnCount() : 1 + ); + + const numberArray = expandArrayValueObject(maxRowLength, maxColumnLength, number, ErrorValueObject.create(ErrorType.NA)); + const numberChosenArray = expandArrayValueObject(maxRowLength, maxColumnLength, numberChosen, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = numberArray.mapValue((numberObject, rowIndex, columnIndex) => { + const numberChosenObject = numberChosenArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (numberObject.isError()) { + return numberObject; + } + + if (numberChosenObject.isError()) { + return numberChosenObject; + } + + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(numberObject, numberChosenObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_numberObject, _numberChosenObject] = variants as BaseValueObject[]; + + const numberValue = Math.floor(+_numberObject.getValue()); + const numberChosenValue = Math.floor(+_numberChosenObject.getValue()); + + if (numberValue < 0 || numberValue >= 2147483647 || numberChosenValue < 0 || numberValue < numberChosenValue) { + return ErrorValueObject.create(ErrorType.NUM); + } + + let result = 1; + + for (let i = numberValue - numberChosenValue + 1; i <= numberValue; i++) { + result *= i; + } + + if (!Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return NumberValueObject.create(result); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } +} diff --git a/packages/engine-formula/src/functions/statistical/permutationa/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/permutationa/__tests__/index.spec.ts new file mode 100644 index 000000000000..3708ff25fd15 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/permutationa/__tests__/index.spec.ts @@ -0,0 +1,122 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Permutationa } from '../index'; + +describe('Test permutationa function', () => { + const testFunction = new Permutationa(FUNCTION_NAMES_STATISTICAL.PERMUTATIONA); + + describe('Permutationa', () => { + it('Value is normal number', () => { + const number = NumberValueObject.create(8); + const numberChosen = NumberValueObject.create(2); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(64); + }); + + it('Value is big number', () => { + const number = NumberValueObject.create(1000000); + const numberChosen = NumberValueObject.create(2000); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Value is number negative', () => { + const number = NumberValueObject.create(8); + const numberChosen = NumberValueObject.create(-2); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Value is number string', () => { + const number = NumberValueObject.create(8); + const numberChosen = StringValueObject.create('1.5'); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(8); + }); + + it('Value is normal string', () => { + const number = NumberValueObject.create(8); + const numberChosen = StringValueObject.create('test'); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const number = NumberValueObject.create(8); + const numberChosen = BooleanValueObject.create(true); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(8); + }); + it('Value is blank cell', () => { + const number = NumberValueObject.create(8); + const numberChosen = NullValueObject.create(); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(1); + }); + it('Value is error', () => { + const number = ErrorValueObject.create(ErrorType.NAME); + const numberChosen = NumberValueObject.create(2); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const number2 = NumberValueObject.create(8); + const numberChosen2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(number2, numberChosen2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const numberChosen = NumberValueObject.create(2); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toStrictEqual([ + [1, ErrorType.VALUE, 1, 1, 0, 0], + [0, 10000, 4, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + }); + + it('More test', () => { + const number = NumberValueObject.create(0); + const numberChosen = NumberValueObject.create(0); + const result = testFunction.calculate(number, numberChosen); + expect(getObjectValue(result)).toBe(1); + + const numberChosen2 = NumberValueObject.create(1); + const result2 = testFunction.calculate(number, numberChosen2); + expect(getObjectValue(result2)).toBe(0); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/permutationa/index.ts b/packages/engine-formula/src/functions/statistical/permutationa/index.ts new file mode 100644 index 000000000000..a536fa63d4a1 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/permutationa/index.ts @@ -0,0 +1,94 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Permutationa extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate(number: BaseValueObject, numberChosen: BaseValueObject): BaseValueObject { + const maxRowLength = Math.max( + number.isArray() ? (number as ArrayValueObject).getRowCount() : 1, + numberChosen.isArray() ? (numberChosen as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + number.isArray() ? (number as ArrayValueObject).getColumnCount() : 1, + numberChosen.isArray() ? (numberChosen as ArrayValueObject).getColumnCount() : 1 + ); + + const numberArray = expandArrayValueObject(maxRowLength, maxColumnLength, number, ErrorValueObject.create(ErrorType.NA)); + const numberChosenArray = expandArrayValueObject(maxRowLength, maxColumnLength, numberChosen, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = numberArray.mapValue((numberObject, rowIndex, columnIndex) => { + const numberChosenObject = numberChosenArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (numberObject.isError()) { + return numberObject; + } + + if (numberChosenObject.isError()) { + return numberChosenObject; + } + + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(numberObject, numberChosenObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_numberObject, _numberChosenObject] = variants as BaseValueObject[]; + + const numberValue = Math.floor(+_numberObject.getValue()); + const numberChosenValue = Math.floor(+_numberChosenObject.getValue()); + + if (numberValue < 0 || numberValue >= 2147483647 || numberChosenValue < 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + // for excel + if (numberValue === 0) { + if (numberChosenValue === 0) { + return NumberValueObject.create(1); + } else { + return NumberValueObject.create(0); + } + } + + const result = numberValue ** numberChosenValue; + + if (!Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return NumberValueObject.create(result); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } +} diff --git a/packages/engine-formula/src/functions/statistical/phi/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/phi/__tests__/index.spec.ts new file mode 100644 index 000000000000..4bfea625e1eb --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/phi/__tests__/index.spec.ts @@ -0,0 +1,111 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Phi } from '../index'; + +describe('Test phi function', () => { + const testFunction = new Phi(FUNCTION_NAMES_STATISTICAL.PHI); + + describe('Phi', () => { + it('Value is normal', () => { + const x = NumberValueObject.create(2.5); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual(0.01752830049356854); + }); + + it('Value is 0 or negative integers', () => { + const x = NumberValueObject.create(0); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual(0.3989422804014327); + + const x2 = NumberValueObject.create(-1); + const result2 = testFunction.calculate(x2); + expect(getObjectValue(result2)).toStrictEqual(0.24197072451914337); + }); + + it('Value is number string', () => { + const x = StringValueObject.create('4'); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual(0.00013383022576488537); + }); + + it('Value is normal string', () => { + const x = StringValueObject.create('test'); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const x = BooleanValueObject.create(true); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual(0.24197072451914337); + }); + + it('Value is null', () => { + const x = NullValueObject.create(); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual(0.3989422804014327); + }); + + it('Value is error', () => { + const x = ErrorValueObject.create(ErrorType.NAME); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + }); + + it('Value is array', () => { + const x = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(x); + expect(getObjectValue(result)).toStrictEqual([ + [0.24197072451914337, ErrorType.VALUE, 0.18723541817072956, 0.24197072451914337, 0.3989422804014327, 0.3989422804014327], + [0.3989422804014327, 0, 0.02581657547158769, ErrorType.VALUE, 0.0044318484119380075, ErrorType.NAME], + ]); + + const x2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0.123], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(x2); + expect(getObjectValue(result2)).toStrictEqual(0.3959358668649187); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/phi/index.ts b/packages/engine-formula/src/functions/statistical/phi/index.ts new file mode 100644 index 000000000000..b0b44193cff4 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/phi/index.ts @@ -0,0 +1,57 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Phi extends BaseFunction { + override minParams = 1; + + override maxParams = 1; + + override calculate(x: BaseValueObject): BaseValueObject { + if (x.isArray()) { + const resultArray = (x as ArrayValueObject).mapValue((xObject) => this._handleSingleObject(xObject)); + + if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + return this._handleSingleObject(x); + } + + private _handleSingleObject(x: BaseValueObject): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(x); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [xObject] = variants as BaseValueObject[]; + + const xValue = +xObject.getValue(); + + const result = Math.exp(-0.5 * xValue * xValue) / Math.sqrt(2 * Math.PI); + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/poisson-dist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/poisson-dist/__tests__/index.spec.ts new file mode 100644 index 000000000000..b31959f22edc --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/poisson-dist/__tests__/index.spec.ts @@ -0,0 +1,145 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { PoissonDist } from '../index'; + +describe('Test poissonDist function', () => { + const testFunction = new PoissonDist(FUNCTION_NAMES_STATISTICAL.POISSON_DIST); + + describe('PoissonDist', () => { + it('Value is normal', () => { + const x = NumberValueObject.create(2); + const mean = NumberValueObject.create(5); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, mean, cumulative); + expect(getObjectValue(result)).toBe(0.12465201948308113); + }); + + it('X and mean value test', () => { + const x = NumberValueObject.create(-2); + const mean = NumberValueObject.create(5); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, mean, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const x2 = NumberValueObject.create(2); + const mean2 = NumberValueObject.create(-5); + const result2 = testFunction.calculate(x2, mean2, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + }); + + it('Cumulative value test', () => { + const x = NumberValueObject.create(2); + const mean = NumberValueObject.create(5); + const cumulative = BooleanValueObject.create(false); + const result = testFunction.calculate(x, mean, cumulative); + expect(getObjectValue(result)).toBe(0.08422433748856833); + }); + + it('Value is normal string', () => { + const x = StringValueObject.create('test'); + const mean = NumberValueObject.create(5); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, mean, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const x = BooleanValueObject.create(true); + const mean = NumberValueObject.create(5); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, mean, cumulative); + expect(getObjectValue(result)).toBe(0.040427681994512805); + }); + + it('Value is null', () => { + const x = NullValueObject.create(); + const mean = NumberValueObject.create(5); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, mean, cumulative); + expect(getObjectValue(result)).toBe(0.006737946999085467); + }); + + it('Value is error', () => { + const x = ErrorValueObject.create(ErrorType.NAME); + const mean = NumberValueObject.create(5); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, mean, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(2); + const mean2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, mean2, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const cumulative2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(x2, mean, cumulative2); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const x = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const mean = NumberValueObject.create(5); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, mean, cumulative); + expect(getObjectValue(result)).toStrictEqual([ + [0.040427681994512805, ErrorType.VALUE, 0.040427681994512805, 0.040427681994512805, 0.006737946999085467, 0.006737946999085467], + [0.006737946999085467, 1, 0.12465201948308113, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + }); + + it('More test', () => { + const x = NumberValueObject.create(17.16017); + const mean = NumberValueObject.create(0.1); + const cumulative = BooleanValueObject.create(false); + const result = testFunction.calculate(x, mean, cumulative); + expect(getObjectValue(result)).toBe(2.543911722940471e-32); + + const mean2 = NumberValueObject.create(2); + const result2 = testFunction.calculate(x, mean2, cumulative); + expect(getObjectValue(result2)).toBe(4.987150189520231e-11); + + const x2 = NumberValueObject.create(0.25); + const mean3 = NumberValueObject.create(0); + const result3 = testFunction.calculate(x2, mean3, cumulative); + expect(getObjectValue(result3)).toBe(1); + + const x3 = NumberValueObject.create(139.7316); + const mean4 = NumberValueObject.create(161); + const result4 = testFunction.calculate(x3, mean4, cumulative); + expect(getObjectValue(result4)).toBe(0.00698880992304486); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/poisson-dist/index.ts b/packages/engine-formula/src/functions/statistical/poisson-dist/index.ts new file mode 100644 index 000000000000..9035fbd507ea --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/poisson-dist/index.ts @@ -0,0 +1,109 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { poissonCDF, poissonPDF } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class PoissonDist extends BaseFunction { + override minParams = 3; + + override maxParams = 3; + + override calculate( + x: BaseValueObject, + mean: BaseValueObject, + cumulative: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getRowCount() : 1, + mean.isArray() ? (mean as ArrayValueObject).getRowCount() : 1, + cumulative.isArray() ? (cumulative as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getColumnCount() : 1, + mean.isArray() ? (mean as ArrayValueObject).getColumnCount() : 1, + cumulative.isArray() ? (cumulative as ArrayValueObject).getColumnCount() : 1 + ); + + const xArray = expandArrayValueObject(maxRowLength, maxColumnLength, x, ErrorValueObject.create(ErrorType.NA)); + const meanArray = expandArrayValueObject(maxRowLength, maxColumnLength, mean, ErrorValueObject.create(ErrorType.NA)); + const cumulativeArray = expandArrayValueObject(maxRowLength, maxColumnLength, cumulative, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = xArray.mapValue((xObject, rowIndex, columnIndex) => { + const meanObject = meanArray.get(rowIndex, columnIndex) as BaseValueObject; + const cumulativeObject = cumulativeArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (xObject.isError()) { + return xObject; + } + + if (meanObject.isError()) { + return meanObject; + } + + if (cumulativeObject.isError()) { + return cumulativeObject; + } + + return this._handleSignleObject(xObject, meanObject, cumulativeObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + xObject: BaseValueObject, + meanObject: BaseValueObject, + cumulativeObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(xObject, meanObject, cumulativeObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_xObject, _meanObject, _cumulativeObject] = variants as BaseValueObject[]; + + const xValue = Math.floor(+_xObject.getValue()); + const meanValue = +_meanObject.getValue(); + const cumulativeValue = +_cumulativeObject.getValue(); + + if (xValue < 0 || meanValue < 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + let result; + + if (cumulativeValue) { + result = poissonCDF(xValue, meanValue); + } else { + result = poissonPDF(xValue, meanValue); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/prob/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/prob/__tests__/index.spec.ts new file mode 100644 index 000000000000..5fc7a1cf205b --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/prob/__tests__/index.spec.ts @@ -0,0 +1,261 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Prob } from '../index'; + +describe('Test prob function', () => { + const testFunction = new Prob(FUNCTION_NAMES_STATISTICAL.PROB); + + describe('Prob', () => { + it('Value is normal', () => { + const xRange = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0, 1, 2, 3], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const probRange = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0.2, 0.3, 0.1, 0.4], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const lowerLimit = NumberValueObject.create(2); + const upperLimit = NullValueObject.create(); + const result = testFunction.calculate(xRange, probRange, lowerLimit, upperLimit); + expect(getObjectValue(result)).toBe(0.1); + }); + + it('XRange and probRange value test', () => { + let xRange = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0, 1, 2, 3, null], + ]), + rowCount: 1, + columnCount: 5, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + let probRange = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0.2, 0.3, 0.1, 0.4], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const lowerLimit = NumberValueObject.create(2); + let result = testFunction.calculate(xRange, probRange, lowerLimit); + expect(getObjectValue(result)).toBe(ErrorType.NA); + + xRange = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + probRange = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + result = testFunction.calculate(xRange, probRange, lowerLimit); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + + xRange = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null, true, false, 'test'], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + probRange = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0.2, 0.3, 0.1, 0.4], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + result = testFunction.calculate(xRange, probRange, lowerLimit); + expect(getObjectValue(result)).toBe(ErrorType.DIV_BY_ZERO); + + xRange = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [ErrorType.NAME, 1, 2, 3], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + result = testFunction.calculate(xRange, probRange, lowerLimit); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const xRange2 = ErrorValueObject.create(ErrorType.NAME); + const probRange2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0.2, 0.3, 0.1, 0.4], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(xRange2, probRange2, lowerLimit); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const xRange3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0, 1, 2, 3], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const probRange3 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(xRange3, probRange3, lowerLimit); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const probRange4 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0.2, 0.3, 0.1, 1], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result4 = testFunction.calculate(xRange3, probRange4, lowerLimit); + expect(getObjectValue(result4)).toBe(ErrorType.NUM); + }); + + it('LowerLimit and upperLimit value test', () => { + const xRange = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0, 1, 2, 3], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const probRange = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0.2, 0.3, 0.1, 0.4], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const lowerLimit = NumberValueObject.create(2); + const upperLimit = NumberValueObject.create(1); + const result = testFunction.calculate(xRange, probRange, lowerLimit, upperLimit); + expect(getObjectValue(result)).toBe(0); + + const lowerLimit2 = BooleanValueObject.create(true); + const result2 = testFunction.calculate(xRange, probRange, lowerLimit2, upperLimit); + expect(getObjectValue(result2)).toBe(0.3); + + const lowerLimit3 = NullValueObject.create(); + const result3 = testFunction.calculate(xRange, probRange, lowerLimit3, upperLimit); + expect(getObjectValue(result3)).toBe(0.5); + + const lowerLimit4 = StringValueObject.create('test'); + const result4 = testFunction.calculate(xRange, probRange, lowerLimit4, upperLimit); + expect(getObjectValue(result4)).toBe(ErrorType.VALUE); + + const lowerLimit5 = ErrorValueObject.create(ErrorType.NAME); + const result5 = testFunction.calculate(xRange, probRange, lowerLimit5, upperLimit); + expect(getObjectValue(result5)).toBe(ErrorType.NAME); + + const lowerLimit6 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [-3, 1, 100, true, false, 'test', null, ErrorType.NAME], + ]), + rowCount: 1, + columnCount: 8, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result6 = testFunction.calculate(xRange, probRange, lowerLimit6, upperLimit); + expect(getObjectValue(result6)).toStrictEqual([ + [0.5, 0.3, 0, 0.3, 0.5, ErrorType.VALUE, 0.5, ErrorType.NAME], + ]); + + const upperLimit2 = ErrorValueObject.create(ErrorType.NAME); + const result7 = testFunction.calculate(xRange, probRange, lowerLimit, upperLimit2); + expect(getObjectValue(result7)).toBe(ErrorType.NAME); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/prob/index.ts b/packages/engine-formula/src/functions/statistical/prob/index.ts new file mode 100644 index 000000000000..8d26993a6511 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/prob/index.ts @@ -0,0 +1,215 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ErrorType } from '../../../basics/error-type'; +import { getTwoArrayNumberValues } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; + +export class Prob extends BaseFunction { + override minParams = 3; + + override maxParams = 4; + + override calculate(xRange: BaseValueObject, probRange: BaseValueObject, lowerLimit: BaseValueObject, upperLimit?: BaseValueObject): BaseValueObject { + const { isError, errorObject, xRangeValues, probRangeValues } = this._handleXRangeAndProbRange(xRange, probRange); + + let _upperLimit = upperLimit ?? lowerLimit; + + if (upperLimit?.isNull()) { + _upperLimit = lowerLimit; + } + + const maxRowLength = Math.max( + lowerLimit.isArray() ? (lowerLimit as ArrayValueObject).getRowCount() : 1, + _upperLimit.isArray() ? (_upperLimit as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + lowerLimit.isArray() ? (lowerLimit as ArrayValueObject).getColumnCount() : 1, + _upperLimit.isArray() ? (_upperLimit as ArrayValueObject).getColumnCount() : 1 + ); + + const lowerLimitArray = expandArrayValueObject(maxRowLength, maxColumnLength, lowerLimit, ErrorValueObject.create(ErrorType.NA)); + const upperLimitArray = expandArrayValueObject(maxRowLength, maxColumnLength, _upperLimit, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = lowerLimitArray.mapValue((lowerLimitObject, rowIndex, columnIndex) => { + const upperLimitObject = upperLimitArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (xRange.isError()) { + return xRange; + } + + if (probRange.isError()) { + return probRange; + } + + if (lowerLimitObject.isError()) { + return lowerLimitObject; + } + + if (upperLimitObject.isError()) { + return upperLimitObject; + } + + if (isError) { + return errorObject as ErrorValueObject; + } + + return this._handleSignleObject(xRangeValues as number[], probRangeValues as number[], lowerLimitObject, upperLimitObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + xRangeValues: number[], + probRangeValues: number[], + lowerLimit: BaseValueObject, + upperLimit: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(lowerLimit, upperLimit); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [lowerLimitObject, upperLimitObject] = variants as BaseValueObject[]; + + const lowerLimitValue = +lowerLimitObject.getValue(); + const upperLimitValue = +upperLimitObject.getValue(); + + if (probRangeValues.reduce((acc, val) => acc + val, 0) !== 1) { + return ErrorValueObject.create(ErrorType.NUM); + } + + let sum = 0; + + for (let i = 0; i < xRangeValues.length; i++) { + if (xRangeValues[i] >= lowerLimitValue && xRangeValues[i] <= upperLimitValue) { + sum += probRangeValues[i]; + } + } + + return NumberValueObject.create(sum); + } + + // eslint-disable-next-line + private _handleXRangeAndProbRange(xRange: BaseValueObject, probRange: BaseValueObject) { + const xRangeRowCount = xRange.isArray() ? (xRange as ArrayValueObject).getRowCount() : 1; + const xRangeColumnCount = xRange.isArray() ? (xRange as ArrayValueObject).getColumnCount() : 1; + + const probRangeRowCount = probRange.isArray() ? (probRange as ArrayValueObject).getRowCount() : 1; + const probRangeColumnCount = probRange.isArray() ? (probRange as ArrayValueObject).getColumnCount() : 1; + + let _xRange = xRange; + + if (xRange.isArray() && xRangeRowCount === 1 && xRangeColumnCount === 1) { + _xRange = (xRange as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_xRange.isError()) { + return { + isError: true, + errorObject: _xRange as ErrorValueObject, + xRangeValues: [], + probRangeValues: [], + }; + } + + let _probRange = probRange; + + if (probRange.isArray() && probRangeRowCount === 1 && probRangeColumnCount === 1) { + _probRange = (probRange as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_probRange.isError()) { + return { + isError: true, + errorObject: _probRange as ErrorValueObject, + xRangeValues: [], + probRangeValues: [], + }; + } + + if (xRangeRowCount * xRangeColumnCount === 1 || probRangeRowCount * probRangeColumnCount === 1) { + if (_xRange.isNull() || _probRange.isNull()) { + return { + isError: true, + errorObject: ErrorValueObject.create(ErrorType.VALUE), + xRangeValues: [], + probRangeValues: [], + }; + } + } + + if (xRangeRowCount * xRangeColumnCount !== probRangeRowCount * probRangeColumnCount) { + return { + isError: true, + errorObject: ErrorValueObject.create(ErrorType.NA), + xRangeValues: [], + probRangeValues: [], + }; + } + + const { + isError, + errorObject, + array1Values: xRangeValues, + array2Values: probRangeValues, + noCalculate, + } = getTwoArrayNumberValues( + xRange, + probRange, + xRangeRowCount * xRangeColumnCount, + xRangeColumnCount, + probRangeColumnCount + ); + + if (isError) { + return { + isError: true, + errorObject, + xRangeValues: [], + probRangeValues: [], + }; + } + + if (noCalculate) { + return { + isError: true, + errorObject: ErrorValueObject.create(ErrorType.DIV_BY_ZERO), + xRangeValues: [], + probRangeValues: [], + }; + } + + return { + isError: false, + errorObject: null, + xRangeValues, + probRangeValues, + }; + } +} diff --git a/packages/engine-formula/src/functions/statistical/quartile-exc/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/quartile-exc/__tests__/index.spec.ts new file mode 100644 index 000000000000..d27b4e9372ac --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/quartile-exc/__tests__/index.spec.ts @@ -0,0 +1,158 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { QuartileExc } from '../index'; + +describe('Test quartileExc function', () => { + const testFunction = new QuartileExc(FUNCTION_NAMES_STATISTICAL.QUARTILE_EXC); + + describe('QuartileExc', () => { + it('Value is normal', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const quart = NumberValueObject.create(1); + const result = testFunction.calculate(array, quart); + expect(getObjectValue(result)).toStrictEqual(2.75); + }); + + it('Array value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, null, true, false, 'test', 6, 7, 8, 9, ErrorType.NAME], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const quart = NumberValueObject.create(1); + const result = testFunction.calculate(array, quart); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null, true, false, 'test'], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(array2, quart); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NUM); + }); + + it('Quart value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const quart = NumberValueObject.create(0.1); + const result = testFunction.calculate(array, quart); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + + const quart2 = NumberValueObject.create(4.1); + const result2 = testFunction.calculate(array, quart2); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NUM); + + const quart3 = BooleanValueObject.create(true); + const result3 = testFunction.calculate(array, quart3); + expect(getObjectValue(result3)).toStrictEqual(2.75); + + const quart4 = NullValueObject.create(); + const result4 = testFunction.calculate(array, quart4); + expect(getObjectValue(result4)).toStrictEqual(ErrorType.NUM); + + const quart5 = StringValueObject.create('test'); + const result5 = testFunction.calculate(array, quart5); + expect(getObjectValue(result5)).toStrictEqual(ErrorType.VALUE); + + const quart6 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(array, quart6); + expect(getObjectValue(result6)).toStrictEqual(ErrorType.NAME); + + const quart7 = ArrayValueObject.create('{0.09,-5,3}'); + const result7 = testFunction.calculate(array, quart7); + expect(getObjectValue(result7)).toStrictEqual([ + [ErrorType.NUM, ErrorType.NUM, 8.25], + ]); + + const quart8 = ArrayValueObject.create('{2}'); + const result8 = testFunction.calculate(array, quart8); + expect(getObjectValue(result8)).toStrictEqual(5.5); + }); + + it('More test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9], + ]), + rowCount: 1, + columnCount: 9, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const quart = NumberValueObject.create(2); + const result = testFunction.calculate(array, quart); + expect(getObjectValue(result)).toStrictEqual(5); + + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2], + ]), + rowCount: 1, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const quart2 = NumberValueObject.create(1); + const result2 = testFunction.calculate(array2, quart2); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NUM); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/quartile-exc/index.ts b/packages/engine-formula/src/functions/statistical/quartile-exc/index.ts new file mode 100644 index 000000000000..d98388dc62bc --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/quartile-exc/index.ts @@ -0,0 +1,120 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; + +export class QuartileExc extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate(array: BaseValueObject, quart: BaseValueObject): BaseValueObject { + const arrayValues = this._getValues(array); + + if (quart.isArray()) { + const resultArray = (quart as ArrayValueObject).mapValue((quartObject) => this._handleSingleObject(arrayValues, quartObject)); + + if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + return this._handleSingleObject(arrayValues, quart); + } + + private _handleSingleObject(array: number[] | ErrorValueObject, quart: BaseValueObject): BaseValueObject { + if (array instanceof ErrorValueObject) { + return array; + } + + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(quart); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [quartObject] = variants as BaseValueObject[]; + + const quartValue = Math.floor(+quartObject.getValue()); + + if (quartValue <= 0 || quartValue >= 4) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const k = quartValue / 4; + const n = array.length; + + if (k < 1 / (n + 1) || k > 1 - 1 / (n + 1)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const kIndex = k * (n + 1) - 1; + const integerPart = Math.floor(kIndex); + const fractionPart = kIndex - integerPart; + + if (fractionPart === 0) { + return NumberValueObject.create(array[integerPart]); + } + + const result = array[integerPart] + fractionPart * (array[integerPart + 1] - array[integerPart]); + + return NumberValueObject.create(result); + } + + private _getValues(array: BaseValueObject): number[] | ErrorValueObject { + const rowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; + const columnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; + + const values: number[] = []; + + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const valueObject = array.isArray() ? (array as ArrayValueObject).get(r, c) as BaseValueObject : array; + + if (valueObject.isError()) { + return valueObject as ErrorValueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + values.push(+value); + } + } + + if (values.length === 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return values.sort((a, b) => a - b); + } +} diff --git a/packages/engine-formula/src/functions/statistical/quartile-inc/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/quartile-inc/__tests__/index.spec.ts new file mode 100644 index 000000000000..974e04d4b390 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/quartile-inc/__tests__/index.spec.ts @@ -0,0 +1,126 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { QuartileInc } from '../index'; + +describe('Test quartileInc function', () => { + const testFunction = new QuartileInc(FUNCTION_NAMES_STATISTICAL.QUARTILE_INC); + + describe('QuartileInc', () => { + it('Value is normal', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const quart = NumberValueObject.create(1); + const result = testFunction.calculate(array, quart); + expect(getObjectValue(result)).toStrictEqual(3.25); + }); + + it('Array value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, null, true, false, 'test', 6, 7, 8, 9, ErrorType.NAME], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const quart = NumberValueObject.create(1); + const result = testFunction.calculate(array, quart); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null, true, false, 'test'], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(array2, quart); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NUM); + }); + + it('Quart value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const quart = NumberValueObject.create(0.1); + const result = testFunction.calculate(array, quart); + expect(getObjectValue(result)).toStrictEqual(1); + + const quart2 = NumberValueObject.create(4.1); + const result2 = testFunction.calculate(array, quart2); + expect(getObjectValue(result2)).toStrictEqual(10); + + const quart3 = BooleanValueObject.create(true); + const result3 = testFunction.calculate(array, quart3); + expect(getObjectValue(result3)).toStrictEqual(3.25); + + const quart4 = NullValueObject.create(); + const result4 = testFunction.calculate(array, quart4); + expect(getObjectValue(result4)).toStrictEqual(1); + + const quart5 = StringValueObject.create('test'); + const result5 = testFunction.calculate(array, quart5); + expect(getObjectValue(result5)).toStrictEqual(ErrorType.VALUE); + + const quart6 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(array, quart6); + expect(getObjectValue(result6)).toStrictEqual(ErrorType.NAME); + + const quart7 = ArrayValueObject.create('{0.09,-5,3}'); + const result7 = testFunction.calculate(array, quart7); + expect(getObjectValue(result7)).toStrictEqual([ + [1, ErrorType.NUM, 7.75], + ]); + + const quart8 = ArrayValueObject.create('{2}'); + const result8 = testFunction.calculate(array, quart8); + expect(getObjectValue(result8)).toStrictEqual(5.5); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/quartile-inc/index.ts b/packages/engine-formula/src/functions/statistical/quartile-inc/index.ts new file mode 100644 index 000000000000..043c2152518c --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/quartile-inc/index.ts @@ -0,0 +1,116 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; + +export class QuartileInc extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate(array: BaseValueObject, quart: BaseValueObject): BaseValueObject { + const arrayValues = this._getValues(array); + + if (quart.isArray()) { + const resultArray = (quart as ArrayValueObject).mapValue((quartObject) => this._handleSingleObject(arrayValues, quartObject)); + + if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + return this._handleSingleObject(arrayValues, quart); + } + + private _handleSingleObject(array: number[] | ErrorValueObject, quart: BaseValueObject): BaseValueObject { + if (array instanceof ErrorValueObject) { + return array; + } + + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(quart); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [quartObject] = variants as BaseValueObject[]; + + const quartValue = Math.floor(+quartObject.getValue()); + + if (quartValue < 0 || quartValue > 4) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const k = quartValue / 4; + const n = array.length; + + const kIndex = k * (n - 1); + const integerPart = Math.floor(kIndex); + const fractionPart = kIndex - integerPart; + + if (fractionPart === 0) { + return NumberValueObject.create(array[integerPart]); + } + + const result = array[integerPart] + fractionPart * (array[integerPart + 1] - array[integerPart]); + + return NumberValueObject.create(result); + } + + private _getValues(array: BaseValueObject): number[] | ErrorValueObject { + const rowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; + const columnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; + + const values: number[] = []; + + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const valueObject = array.isArray() ? (array as ArrayValueObject).get(r, c) as BaseValueObject : array; + + if (valueObject.isError()) { + return valueObject as ErrorValueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + values.push(+value); + } + } + + if (values.length === 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return values.sort((a, b) => a - b); + } +} diff --git a/packages/engine-formula/src/functions/statistical/rsq/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/rsq/__tests__/index.spec.ts new file mode 100644 index 000000000000..080e061ee2ca --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/rsq/__tests__/index.spec.ts @@ -0,0 +1,311 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { NullValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Rsq } from '../index'; + +describe('Test rsq function', () => { + const testFunction = new Rsq(FUNCTION_NAMES_STATISTICAL.RSQ); + + describe('Rsq', () => { + it('Value is normal', () => { + const array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array1, array2); + expect(getObjectValue(result)).toBe(0.6981161249361308); + }); + + it('Value length is equal to 1', () => { + const array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array1, array2); + expect(getObjectValue(result)).toBe(ErrorType.DIV_BY_ZERO); + }); + + it('Value length is not equal', () => { + const array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + ]), + rowCount: 2, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array1, array2); + expect(getObjectValue(result)).toBe(ErrorType.NA); + }); + + it('Value is error', () => { + const array1 = ErrorValueObject.create(ErrorType.NAME); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array1, array2); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const array3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array4 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(array3, array4); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const array5 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [ErrorType.NAME, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array6 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result3 = testFunction.calculate(array5, array6); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const array7 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array8 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [ErrorType.NAME, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result4 = testFunction.calculate(array7, array8); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); + }); + + it('Value is null', () => { + const array1 = NullValueObject.create(); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array1, array2); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + + const array3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array4 = NullValueObject.create(); + const result2 = testFunction.calculate(array3, array4); + expect(getObjectValue(result2)).toBe(ErrorType.VALUE); + }); + + it('Value is can not calculate', () => { + const array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, null], + [11, 'test'], + [10, true], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [false, 47.65], + [null, 18.44], + ['test', 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array1, array2); + expect(getObjectValue(result)).toBe(ErrorType.DIV_BY_ZERO); + }); + + it('Array2Variance === 0', () => { + const array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [2], + [1], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [1], + [1], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array1, array2); + expect(getObjectValue(result)).toBe(ErrorType.DIV_BY_ZERO); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/rsq/index.ts b/packages/engine-formula/src/functions/statistical/rsq/index.ts new file mode 100644 index 000000000000..b26bf25c71a7 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/rsq/index.ts @@ -0,0 +1,127 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { getTwoArrayNumberValues } from '../../../basics/statistical'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Rsq extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate(array1: BaseValueObject, array2: BaseValueObject): BaseValueObject { + const array1RowCount = array1.isArray() ? (array1 as ArrayValueObject).getRowCount() : 1; + const array1ColumnCount = array1.isArray() ? (array1 as ArrayValueObject).getColumnCount() : 1; + + const array2RowCount = array2.isArray() ? (array2 as ArrayValueObject).getRowCount() : 1; + const array2ColumnCount = array2.isArray() ? (array2 as ArrayValueObject).getColumnCount() : 1; + + let _array1 = array1; + + if (array1.isArray() && array1RowCount === 1 && array1ColumnCount === 1) { + _array1 = (array1 as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_array1.isError()) { + return _array1; + } + + let _array2 = array2; + + if (array2.isArray() && array2RowCount === 1 && array2ColumnCount === 1) { + _array2 = (array2 as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_array2.isError()) { + return _array2; + } + + if (array1RowCount * array1ColumnCount === 1 || array2RowCount * array2ColumnCount === 1) { + if (_array1.isNull() || _array2.isNull()) { + return ErrorValueObject.create(ErrorType.VALUE); + } + } + + if (array1RowCount * array1ColumnCount !== array2RowCount * array2ColumnCount) { + return ErrorValueObject.create(ErrorType.NA); + } + + const { + isError, + errorObject, + array1Values, + array2Values, + noCalculate, + } = getTwoArrayNumberValues( + array1, + array2, + array1RowCount * array1ColumnCount, + array1ColumnCount, + array2ColumnCount + ); + + if (isError) { + return errorObject as ErrorValueObject; + } + + if (noCalculate) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + return this._getResult(array1Values, array2Values); + } + + private _getResult(array1: number[], array2: number[]): BaseValueObject { + if (array1.length === 0) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + const n = array1.length; + + let sumX = 0; + let sumY = 0; + + for (let i = 0; i < n; i++) { + sumX += array1[i]; + sumY += array2[i]; + } + + const meanX = sumX / n; + const meanY = sumY / n; + + let num = 0; + let den1 = 0; + let den2 = 0; + + for (let i = 0; i < n; i++) { + num += (array1[i] - meanX) * (array2[i] - meanY); + den1 += (array1[i] - meanX) ** 2; + den2 += (array2[i] - meanY) ** 2; + } + + if (den1 === 0 || den2 === 0) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + const result = (num / Math.sqrt(den1 * den2)) ** 2; + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/skew-p/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/skew-p/__tests__/index.spec.ts new file mode 100644 index 000000000000..1ce85c3724e1 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/skew-p/__tests__/index.spec.ts @@ -0,0 +1,133 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { SkewP } from '../index'; + +describe('Test skewP function', () => { + const testFunction = new SkewP(FUNCTION_NAMES_STATISTICAL.SKEW_P); + + describe('SkewP', () => { + it('Value is normal', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9], + ]), + rowCount: 3, + columnCount: 3, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(4.9343245538895844e-17); + }); + + it('Value length < 3', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2], + ]), + rowCount: 1, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.DIV_BY_ZERO); + }); + + it('Value is single cell = null/boolean/string/error/negtive number', () => { + const number = NumberValueObject.create(3); + const number2 = NullValueObject.create(); + const number3 = BooleanValueObject.create(true); + const number4 = StringValueObject.create('test'); + const number5 = ErrorValueObject.create(ErrorType.NAME); + const number6 = NumberValueObject.create(-3); + const result = testFunction.calculate(number, number2, number3, number4); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); + + const result2 = testFunction.calculate(number, number2, number3, number5); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); + + const result3 = testFunction.calculate(number, number2, number3, number6); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.DIV_BY_ZERO); + }); + + it('Value is not has number', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [true, false, null, 'test', null, null], + ]), + rowCount: 1, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.DIV_BY_ZERO); + }); + + it('Stdev is 0', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 1, 1], + [1, 1, 1], + [1, 1, 1], + ]), + rowCount: 3, + columnCount: 3, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.DIV_BY_ZERO); + }); + + it('More test', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/skew-p/index.ts b/packages/engine-formula/src/functions/statistical/skew-p/index.ts new file mode 100644 index 000000000000..5d08985739ce --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/skew-p/index.ts @@ -0,0 +1,110 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class SkewP extends BaseFunction { + override minParams = 1; + + override maxParams = 255; + + override calculate(...variants: BaseValueObject[]): BaseValueObject { + const values: number[] = []; + + let sum = 0; + + for (let i = 0; i < variants.length; i++) { + const variant = variants[i]; + + if (variant.isError()) { + return variant; + } + + if (variant.isString()) { + const _variant = variant.convertToNumberObjectValue(); + + if (_variant.isError()) { + return _variant; + } + } + + const rowCount = variant.isArray() ? (variant as ArrayValueObject).getRowCount() : 1; + const columnCount = variant.isArray() ? (variant as ArrayValueObject).getColumnCount() : 1; + + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const valueObject = variant.isArray() ? (variant as ArrayValueObject).get(r, c) as BaseValueObject : variant; + + if (valueObject.isError()) { + return valueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + values.push(+value); + sum += +value; + } + } + } + + if (values.length <= 2) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + return this._getResult(values, sum); + } + + private _getResult(values: number[], sum: number): BaseValueObject { + const n = values.length; + const mean = sum / n; + + let sum2 = 0; + + for (let i = 0; i < n; i++) { + sum2 += (values[i] - mean) ** 2; + } + + const stdev = Math.sqrt(sum2 / n); + + if (stdev === 0) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + let sum3 = 0; + + for (let i = 0; i < n; i++) { + sum3 += ((values[i] - mean) / stdev) ** 3; + } + + const result = sum3 / n; + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/skew/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/skew/__tests__/index.spec.ts new file mode 100644 index 000000000000..008852679603 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/skew/__tests__/index.spec.ts @@ -0,0 +1,133 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Skew } from '../index'; + +describe('Test skew function', () => { + const testFunction = new Skew(FUNCTION_NAMES_STATISTICAL.SKEW); + + describe('Skew', () => { + it('Value is normal', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9], + ]), + rowCount: 3, + columnCount: 3, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(7.137148015447435e-17); + }); + + it('Value length < 3', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2], + ]), + rowCount: 1, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.DIV_BY_ZERO); + }); + + it('Value is single cell = null/boolean/string/error/negtive number', () => { + const number = NumberValueObject.create(3); + const number2 = NullValueObject.create(); + const number3 = BooleanValueObject.create(true); + const number4 = StringValueObject.create('test'); + const number5 = ErrorValueObject.create(ErrorType.NAME); + const number6 = NumberValueObject.create(-3); + const result = testFunction.calculate(number, number2, number3, number4); + expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE); + + const result2 = testFunction.calculate(number, number2, number3, number5); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME); + + const result3 = testFunction.calculate(number, number2, number3, number6); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.DIV_BY_ZERO); + }); + + it('Value is not has number', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [true, false, null, 'test', null, null], + ]), + rowCount: 1, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.DIV_BY_ZERO); + }); + + it('Stdev is 0', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 1, 1], + [1, 1, 1], + [1, 1, 1], + ]), + rowCount: 3, + columnCount: 3, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.DIV_BY_ZERO); + }); + + it('More test', () => { + const number = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(number); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/skew/index.ts b/packages/engine-formula/src/functions/statistical/skew/index.ts new file mode 100644 index 000000000000..58190ba62205 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/skew/index.ts @@ -0,0 +1,110 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Skew extends BaseFunction { + override minParams = 1; + + override maxParams = 255; + + override calculate(...variants: BaseValueObject[]): BaseValueObject { + const values: number[] = []; + + let sum = 0; + + for (let i = 0; i < variants.length; i++) { + const variant = variants[i]; + + if (variant.isError()) { + return variant; + } + + if (variant.isString()) { + const _variant = variant.convertToNumberObjectValue(); + + if (_variant.isError()) { + return _variant; + } + } + + const rowCount = variant.isArray() ? (variant as ArrayValueObject).getRowCount() : 1; + const columnCount = variant.isArray() ? (variant as ArrayValueObject).getColumnCount() : 1; + + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const valueObject = variant.isArray() ? (variant as ArrayValueObject).get(r, c) as BaseValueObject : variant; + + if (valueObject.isError()) { + return valueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + values.push(+value); + sum += +value; + } + } + } + + if (values.length <= 2) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + return this._getResult(values, sum); + } + + private _getResult(values: number[], sum: number): BaseValueObject { + const n = values.length; + const mean = sum / n; + + let sum2 = 0; + + for (let i = 0; i < n; i++) { + sum2 += (values[i] - mean) ** 2; + } + + const stdev = Math.sqrt(sum2 / (n - 1)); + + if (stdev === 0) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + let sum3 = 0; + + for (let i = 0; i < n; i++) { + sum3 += ((values[i] - mean) / stdev) ** 3; + } + + const result = n / ((n - 1) * (n - 2)) * sum3; + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/slope/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/slope/__tests__/index.spec.ts new file mode 100644 index 000000000000..34f0689b78b6 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/slope/__tests__/index.spec.ts @@ -0,0 +1,311 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { NullValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Slope } from '../index'; + +describe('Test slope function', () => { + const testFunction = new Slope(FUNCTION_NAMES_STATISTICAL.SLOPE); + + describe('Slope', () => { + it('Value is normal', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toBe(0.9840117714340344); + }); + + it('Value length is equal to 1', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toBe(ErrorType.DIV_BY_ZERO); + }); + + it('Value length is not equal', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + ]), + rowCount: 2, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toBe(ErrorType.NA); + }); + + it('Value is error', () => { + const knownYs = ErrorValueObject.create(ErrorType.NAME); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const knownYs2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(knownYs2, knownXs2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const knownYs3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [ErrorType.NAME, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result3 = testFunction.calculate(knownYs3, knownXs3); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const knownYs4 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs4 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [ErrorType.NAME, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result4 = testFunction.calculate(knownYs4, knownXs4); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); + }); + + it('Value is null', () => { + const knownYs = NullValueObject.create(); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + + const knownYs2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs2 = NullValueObject.create(); + const result2 = testFunction.calculate(knownYs2, knownXs2); + expect(getObjectValue(result2)).toBe(ErrorType.VALUE); + }); + + it('Value is can not calculate', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, null], + [11, 'test'], + [10, true], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [false, 47.65], + [null, 18.44], + ['test', 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toBe(ErrorType.DIV_BY_ZERO); + }); + + it('Array2Variance === 0', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [2], + [1], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [1], + [1], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toBe(ErrorType.DIV_BY_ZERO); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/slope/index.ts b/packages/engine-formula/src/functions/statistical/slope/index.ts new file mode 100644 index 000000000000..4eddf26b8073 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/slope/index.ts @@ -0,0 +1,123 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ErrorType } from '../../../basics/error-type'; +import { getTwoArrayNumberValues } from '../../../basics/statistical'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; + +export class Slope extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate(knownYs: BaseValueObject, knownXs: BaseValueObject): BaseValueObject { + const knownYsRowCount = knownYs.isArray() ? (knownYs as ArrayValueObject).getRowCount() : 1; + const knownYsColumnCount = knownYs.isArray() ? (knownYs as ArrayValueObject).getColumnCount() : 1; + + const knownXsRowCount = knownXs.isArray() ? (knownXs as ArrayValueObject).getRowCount() : 1; + const knownXsColumnCount = knownXs.isArray() ? (knownXs as ArrayValueObject).getColumnCount() : 1; + + let _knownYs = knownYs; + + if (knownYs.isArray() && knownYsRowCount === 1 && knownYsColumnCount === 1) { + _knownYs = (knownYs as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_knownYs.isError()) { + return _knownYs; + } + + let _knownXs = knownXs; + + if (knownXs.isArray() && knownXsRowCount === 1 && knownXsColumnCount === 1) { + _knownXs = (knownXs as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_knownXs.isError()) { + return _knownXs; + } + + if (knownYsRowCount * knownYsColumnCount === 1 || knownXsRowCount * knownXsColumnCount === 1) { + if (_knownYs.isNull() || _knownXs.isNull()) { + return ErrorValueObject.create(ErrorType.VALUE); + } + + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + if (knownYsRowCount * knownYsColumnCount !== knownXsRowCount * knownXsColumnCount) { + return ErrorValueObject.create(ErrorType.NA); + } + + const { + isError, + errorObject, + array1Values, + array2Values, + noCalculate, + } = getTwoArrayNumberValues( + knownYs, + knownXs, + knownYsRowCount * knownYsColumnCount, + knownYsColumnCount, + knownXsColumnCount + ); + + if (isError) { + return errorObject as ErrorValueObject; + } + + if (noCalculate) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + return this._getResult(array1Values, array2Values); + } + + private _getResult(knownYs: number[], knownXs: number[]): BaseValueObject { + const n = knownYs.length; + + let knownYsSum = 0; + let knownXsSum = 0; + + for (let i = 0; i < n; i++) { + knownYsSum += knownYs[i]; + knownXsSum += knownXs[i]; + } + + const knownYsMean = knownYsSum / n; + const knownXsMean = knownXsSum / n; + + let num = 0; + let den = 0; + + for (let i = 0; i < n; i++) { + num += (knownYs[i] - knownYsMean) * (knownXs[i] - knownXsMean); + den += (knownXs[i] - knownXsMean) ** 2; + } + + if (den === 0) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + const result = num / den; + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/small/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/small/__tests__/index.spec.ts new file mode 100644 index 000000000000..8103c82e5d59 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/small/__tests__/index.spec.ts @@ -0,0 +1,143 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Small } from '../index'; + +describe('Test small function', () => { + const testFunction = new Small(FUNCTION_NAMES_STATISTICAL.SMALL); + + describe('Small', () => { + it('Value is normal', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(2.5); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(2); + }); + + it('Value is number string', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + ['\'1', '\'2', '\'3', '\'4', '\'5', '\'6', '\'7', '\'8', '\'9', '\'10'], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(2.5); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + }); + + it('Array value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, null, true, false, 'test', 6, 7, 8, 9, ErrorType.NAME], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(2.5); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null, true, false, 'test'], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(array2, k); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NUM); + }); + + it('K value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const k = NumberValueObject.create(0.1); + const result = testFunction.calculate(array, k); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NUM); + + const k2 = NumberValueObject.create(11); + const result2 = testFunction.calculate(array, k2); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NUM); + + const k3 = BooleanValueObject.create(true); + const result3 = testFunction.calculate(array, k3); + expect(getObjectValue(result3)).toStrictEqual(1); + + const k4 = NullValueObject.create(); + const result4 = testFunction.calculate(array, k4); + expect(getObjectValue(result4)).toStrictEqual(ErrorType.NUM); + + const k5 = StringValueObject.create('test'); + const result5 = testFunction.calculate(array, k5); + expect(getObjectValue(result5)).toStrictEqual(ErrorType.VALUE); + + const k6 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(array, k6); + expect(getObjectValue(result6)).toStrictEqual(ErrorType.NAME); + + const k7 = ArrayValueObject.create('{1,2,3}'); + const result7 = testFunction.calculate(array, k7); + expect(getObjectValue(result7)).toStrictEqual([ + [1, 2, 3], + ]); + + const k8 = ArrayValueObject.create('{1}'); + const result8 = testFunction.calculate(array, k8); + expect(getObjectValue(result8)).toStrictEqual(1); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/small/index.ts b/packages/engine-formula/src/functions/statistical/small/index.ts new file mode 100644 index 000000000000..3cade149834b --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/small/index.ts @@ -0,0 +1,105 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Small extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate(array: BaseValueObject, k: BaseValueObject): BaseValueObject { + const arrayValues = this._getValues(array); + + if (k.isArray()) { + const resultArray = (k as ArrayValueObject).mapValue((kObject) => this._handleSingleObject(arrayValues, kObject)); + + if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + return this._handleSingleObject(arrayValues, k); + } + + private _handleSingleObject(array: number[] | ErrorValueObject, k: BaseValueObject): BaseValueObject { + if (array instanceof ErrorValueObject) { + return array; + } + + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(k); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [kObject] = variants as BaseValueObject[]; + + let kValue = +kObject.getValue(); + + if (kValue < 1 || kValue > array.length) { + return ErrorValueObject.create(ErrorType.NUM); + } + + kValue = Math.floor(kValue); + + return NumberValueObject.create(array[kValue - 1]); + } + + private _getValues(array: BaseValueObject): number[] | ErrorValueObject { + const rowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; + const columnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; + + const values: number[] = []; + + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const valueObject = array.isArray() ? (array as ArrayValueObject).get(r, c) as BaseValueObject : array; + + if (valueObject.isError()) { + return valueObject as ErrorValueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean() || valueObject.isString()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + values.push(+value); + } + } + + if (values.length === 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return values.sort((a, b) => a - b); + } +} diff --git a/packages/engine-formula/src/functions/statistical/standardize/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/standardize/__tests__/index.spec.ts new file mode 100644 index 000000000000..5c7517d7a0d6 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/standardize/__tests__/index.spec.ts @@ -0,0 +1,110 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Standardize } from '../index'; + +describe('Test standardize function', () => { + const testFunction = new Standardize(FUNCTION_NAMES_STATISTICAL.STANDARDIZE); + + describe('Standardize', () => { + it('Value is normal', () => { + const x = NumberValueObject.create(42); + const mean = NumberValueObject.create(40); + const standardDev = NumberValueObject.create(1.5); + const result = testFunction.calculate(x, mean, standardDev); + expect(getObjectValue(result)).toBe(1.3333333333333333); + }); + + it('StandardDev value test', () => { + const x = NumberValueObject.create(42); + const mean = NumberValueObject.create(40); + const standardDev = NumberValueObject.create(0); + const result = testFunction.calculate(x, mean, standardDev); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Value is normal string', () => { + const x = StringValueObject.create('test'); + const mean = NumberValueObject.create(40); + const standardDev = NumberValueObject.create(1.5); + const result = testFunction.calculate(x, mean, standardDev); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const x = BooleanValueObject.create(true); + const mean = NumberValueObject.create(40); + const standardDev = NumberValueObject.create(1.5); + const result = testFunction.calculate(x, mean, standardDev); + expect(getObjectValue(result)).toBe(-26); + }); + + it('Value is null', () => { + const x = NullValueObject.create(); + const mean = NumberValueObject.create(40); + const standardDev = NumberValueObject.create(1.5); + const result = testFunction.calculate(x, mean, standardDev); + expect(getObjectValue(result)).toBe(-26.666666666666668); + }); + + it('Value is error', () => { + const x = ErrorValueObject.create(ErrorType.NAME); + const mean = NumberValueObject.create(40); + const standardDev = NumberValueObject.create(1.5); + const result = testFunction.calculate(x, mean, standardDev); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(42); + const mean2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, mean2, standardDev); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const standardDev2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(x2, mean, standardDev2); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const x = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const mean = NumberValueObject.create(40); + const standardDev = NumberValueObject.create(1.5); + const result = testFunction.calculate(x, mean, standardDev); + expect(getObjectValue(result)).toStrictEqual([ + [-26, ErrorType.VALUE, -25.846666666666668, -26, -26.666666666666668, -26.666666666666668], + [-26.666666666666668, 40, -25.106666666666666, ErrorType.VALUE, -28.666666666666668, ErrorType.NAME], + ]); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/standardize/index.ts b/packages/engine-formula/src/functions/statistical/standardize/index.ts new file mode 100644 index 000000000000..ee75c09c506a --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/standardize/index.ts @@ -0,0 +1,102 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ErrorType } from '../../../basics/error-type'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; + +export class Standardize extends BaseFunction { + override minParams = 3; + + override maxParams = 3; + + override calculate( + x: BaseValueObject, + mean: BaseValueObject, + standardDev: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getRowCount() : 1, + mean.isArray() ? (mean as ArrayValueObject).getRowCount() : 1, + standardDev.isArray() ? (standardDev as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getColumnCount() : 1, + mean.isArray() ? (mean as ArrayValueObject).getColumnCount() : 1, + standardDev.isArray() ? (standardDev as ArrayValueObject).getColumnCount() : 1 + ); + + const xArray = expandArrayValueObject(maxRowLength, maxColumnLength, x, ErrorValueObject.create(ErrorType.NA)); + const meanArray = expandArrayValueObject(maxRowLength, maxColumnLength, mean, ErrorValueObject.create(ErrorType.NA)); + const standardDevArray = expandArrayValueObject(maxRowLength, maxColumnLength, standardDev, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = xArray.mapValue((xObject, rowIndex, columnIndex) => { + const meanObject = meanArray.get(rowIndex, columnIndex) as BaseValueObject; + const standardDevObject = standardDevArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (xObject.isError()) { + return xObject; + } + + if (meanObject.isError()) { + return meanObject; + } + + if (standardDevObject.isError()) { + return standardDevObject; + } + + return this._handleSignleObject(xObject, meanObject, standardDevObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + xObject: BaseValueObject, + meanObject: BaseValueObject, + standardDevObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(xObject, meanObject, standardDevObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_xObject, _meanObject, _standardDevObject] = variants as BaseValueObject[]; + + const xValue = +_xObject.getValue(); + const meanValue = +_meanObject.getValue(); + const standardDevValue = +_standardDevObject.getValue(); + + if (standardDevValue <= 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const result = (xValue - meanValue) / standardDevValue; + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/steyx/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/steyx/__tests__/index.spec.ts new file mode 100644 index 000000000000..d16c2af6fdac --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/steyx/__tests__/index.spec.ts @@ -0,0 +1,354 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { NullValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Steyx } from '../index'; + +describe('Test steyx function', () => { + const testFunction = new Steyx(FUNCTION_NAMES_STATISTICAL.STEYX); + + describe('Steyx', () => { + it('Value is normal', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toBe(10.95439821888396); + }); + + it('Value length is equal to 1', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toBe(ErrorType.DIV_BY_ZERO); + }); + + it('Value length is not equal', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + ]), + rowCount: 2, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toBe(ErrorType.NA); + }); + + it('Value is error', () => { + const knownYs = ErrorValueObject.create(ErrorType.NAME); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const knownYs2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(knownYs2, knownXs2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const knownYs3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [ErrorType.NAME, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result3 = testFunction.calculate(knownYs3, knownXs3); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const knownYs4 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs4 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [ErrorType.NAME, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result4 = testFunction.calculate(knownYs4, knownXs4); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); + }); + + it('Value is null', () => { + const knownYs = NullValueObject.create(); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [45.35, 47.65], + [17.56, 18.44], + [16.09, 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + + const knownYs2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, 35], + [11, 25], + [10, 23], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs2 = NullValueObject.create(); + const result2 = testFunction.calculate(knownYs2, knownXs2); + expect(getObjectValue(result2)).toBe(ErrorType.VALUE); + }); + + it('Value is can not calculate', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [58, null], + [11, 'test'], + [10, true], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [false, 47.65], + [null, 18.44], + ['test', 16.91], + ]), + rowCount: 3, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toBe(ErrorType.DIV_BY_ZERO); + }); + + it('Array2Variance === 0', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [2], + [1], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1], + [1], + [1], + ]), + rowCount: 3, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toBe(ErrorType.DIV_BY_ZERO); + }); + + it('More test', () => { + const knownYs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [30.329, 44], + [31.34199, 45], + [32.35498, 46], + [33.36797, 47], + [34.38095, 48], + [35.39394, 49], + [36.40693, 50], + [37.41991, 51], + [38.4329, 53], + ]), + rowCount: 9, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const knownXs = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null, -0.15], + [null, -0.16], + [null, -0.17], + [null, -0.18], + [null, -0.19], + [null, null], + [null, null], + [null, null], + [null, null], + ]), + rowCount: 9, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(knownYs, knownXs); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/steyx/index.ts b/packages/engine-formula/src/functions/statistical/steyx/index.ts new file mode 100644 index 000000000000..832db9749385 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/steyx/index.ts @@ -0,0 +1,131 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { getTwoArrayNumberValues } from '../../../basics/statistical'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class Steyx extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate(knownYs: BaseValueObject, knownXs: BaseValueObject): BaseValueObject { + const knownYsRowCount = knownYs.isArray() ? (knownYs as ArrayValueObject).getRowCount() : 1; + const knownYsColumnCount = knownYs.isArray() ? (knownYs as ArrayValueObject).getColumnCount() : 1; + + const knownXsRowCount = knownXs.isArray() ? (knownXs as ArrayValueObject).getRowCount() : 1; + const knownXsColumnCount = knownXs.isArray() ? (knownXs as ArrayValueObject).getColumnCount() : 1; + + let _knownYs = knownYs; + + if (knownYs.isArray() && knownYsRowCount === 1 && knownYsColumnCount === 1) { + _knownYs = (knownYs as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_knownYs.isError()) { + return _knownYs; + } + + let _knownXs = knownXs; + + if (knownXs.isArray() && knownXsRowCount === 1 && knownXsColumnCount === 1) { + _knownXs = (knownXs as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_knownXs.isError()) { + return _knownXs; + } + + if (knownYsRowCount * knownYsColumnCount === 1 || knownXsRowCount * knownXsColumnCount === 1) { + if (_knownYs.isNull() || _knownXs.isNull()) { + return ErrorValueObject.create(ErrorType.VALUE); + } + } + + if (knownYsRowCount * knownYsColumnCount !== knownXsRowCount * knownXsColumnCount) { + return ErrorValueObject.create(ErrorType.NA); + } + + const { + isError, + errorObject, + array1Values, + array2Values, + noCalculate, + } = getTwoArrayNumberValues( + knownYs, + knownXs, + knownYsRowCount * knownYsColumnCount, + knownYsColumnCount, + knownXsColumnCount + ); + + if (isError) { + return errorObject as ErrorValueObject; + } + + if (noCalculate) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + return this._getResult(array1Values, array2Values); + } + + private _getResult(knownYs: number[], knownXs: number[]): BaseValueObject { + const n = knownYs.length; + + if (n <= 2) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + let knownYsSum = 0; + let knownXsSum = 0; + + for (let i = 0; i < n; i++) { + knownYsSum += knownYs[i]; + knownXsSum += knownXs[i]; + } + + const knownYsMean = knownYsSum / n; + const knownXsMean = knownXsSum / n; + + let num = 0; + let knownYsPowSum = 0; + let knownXsPowSum = 0; + + for (let i = 0; i < n; i++) { + num += (knownYs[i] - knownYsMean) * (knownXs[i] - knownXsMean); + knownYsPowSum += (knownYs[i] - knownYsMean) ** 2; + knownXsPowSum += (knownXs[i] - knownXsMean) ** 2; + } + + if (knownXsPowSum === 0) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + const result = Math.sqrt((knownYsPowSum - (num ** 2) / knownXsPowSum) / (n - 2)); + + if (Number.isNaN(result) || !Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/t-dist-2t/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/t-dist-2t/__tests__/index.spec.ts new file mode 100644 index 000000000000..a6876029daee --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/t-dist-2t/__tests__/index.spec.ts @@ -0,0 +1,110 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { TDist2t } from '../index'; + +describe('Test tDist2t function', () => { + const testFunction = new TDist2t(FUNCTION_NAMES_STATISTICAL.T_DIST_2T); + + describe('TDist2t', () => { + it('Value is normal', () => { + const x = NumberValueObject.create(1); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toBe(0.4226497308104018); + }); + + it('DegFreedom value test', () => { + const x = NumberValueObject.create(1); + const degFreedom = NumberValueObject.create(0); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const degFreedom2 = NumberValueObject.create(10 ** 10 + 1); + const result2 = testFunction.calculate(x, degFreedom2); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + }); + + it('Value is normal string', () => { + const x = StringValueObject.create('test'); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const x = BooleanValueObject.create(true); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toBe(0.4226497308104018); + }); + + it('Value is null', () => { + const x = NullValueObject.create(); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toBe(1); + }); + + it('Value is error', () => { + const x = ErrorValueObject.create(ErrorType.NAME); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(1); + const degFreedom2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, degFreedom2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const x = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toStrictEqual([ + [0.4226497308104018, ErrorType.VALUE, 0.3437456155496856, 0.4226497308104018, 1, 1], + [1, 0.00009998500249955772, 0.14415950895030902, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + }); + + it('More test', () => { + const x = NumberValueObject.create(0.1); + const degFreedom = NumberValueObject.create(900000000); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toBe(0.9203442914779052); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/t-dist-2t/index.ts b/packages/engine-formula/src/functions/statistical/t-dist-2t/index.ts new file mode 100644 index 000000000000..48b232e750f9 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/t-dist-2t/index.ts @@ -0,0 +1,96 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { studentTCDF } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class TDist2t extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate( + x: BaseValueObject, + degFreedom: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getRowCount() : 1, + degFreedom.isArray() ? (degFreedom as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getColumnCount() : 1, + degFreedom.isArray() ? (degFreedom as ArrayValueObject).getColumnCount() : 1 + ); + + const xArray = expandArrayValueObject(maxRowLength, maxColumnLength, x, ErrorValueObject.create(ErrorType.NA)); + const degFreedomArray = expandArrayValueObject(maxRowLength, maxColumnLength, degFreedom, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = xArray.mapValue((xObject, rowIndex, columnIndex) => { + const degFreedomObject = degFreedomArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (xObject.isError()) { + return xObject; + } + + if (degFreedomObject.isError()) { + return degFreedomObject; + } + + return this._handleSignleObject(xObject, degFreedomObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + xObject: BaseValueObject, + degFreedomObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(xObject, degFreedomObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_xObject, _degFreedomObject] = variants as BaseValueObject[]; + + const xValue = +_xObject.getValue(); + const degFreedomValue = Math.floor(+_degFreedomObject.getValue()); + + if (xValue < 0 || degFreedomValue < 1 || degFreedomValue > 10 ** 10) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const result = studentTCDF(-xValue, degFreedomValue) * 2; + + if (Number.isNaN(result) || !Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/t-dist-rt/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/t-dist-rt/__tests__/index.spec.ts new file mode 100644 index 000000000000..b9b3eaf5872d --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/t-dist-rt/__tests__/index.spec.ts @@ -0,0 +1,110 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { TDistRt } from '../index'; + +describe('Test tDistRt function', () => { + const testFunction = new TDistRt(FUNCTION_NAMES_STATISTICAL.T_DIST_RT); + + describe('TDistRt', () => { + it('Value is normal', () => { + const x = NumberValueObject.create(1); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toBe(0.2113248654052009); + }); + + it('DegFreedom value test', () => { + const x = NumberValueObject.create(1); + const degFreedom = NumberValueObject.create(0); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const degFreedom2 = NumberValueObject.create(10 ** 10 + 1); + const result2 = testFunction.calculate(x, degFreedom2); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + }); + + it('Value is normal string', () => { + const x = StringValueObject.create('test'); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const x = BooleanValueObject.create(true); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toBe(0.2113248654052009); + }); + + it('Value is null', () => { + const x = NullValueObject.create(); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toBe(0.5); + }); + + it('Value is error', () => { + const x = ErrorValueObject.create(ErrorType.NAME); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(1); + const degFreedom2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, degFreedom2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const x = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toStrictEqual([ + [0.2113248654052009, ErrorType.VALUE, 0.1718728077748428, 0.2113248654052009, 0.5, 0.5], + [0.5, 0.00004999250124977886, 0.07207975447515451, ErrorType.VALUE, 0.9522670168686455, ErrorType.NAME], + ]); + }); + + it('More test', () => { + const x = NumberValueObject.create(0.1); + const degFreedom = NumberValueObject.create(900000000); + const result = testFunction.calculate(x, degFreedom); + expect(getObjectValue(result)).toBe(0.4601721457389526); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/t-dist-rt/index.ts b/packages/engine-formula/src/functions/statistical/t-dist-rt/index.ts new file mode 100644 index 000000000000..683c558a13db --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/t-dist-rt/index.ts @@ -0,0 +1,96 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { studentTCDF } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class TDistRt extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate( + x: BaseValueObject, + degFreedom: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getRowCount() : 1, + degFreedom.isArray() ? (degFreedom as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getColumnCount() : 1, + degFreedom.isArray() ? (degFreedom as ArrayValueObject).getColumnCount() : 1 + ); + + const xArray = expandArrayValueObject(maxRowLength, maxColumnLength, x, ErrorValueObject.create(ErrorType.NA)); + const degFreedomArray = expandArrayValueObject(maxRowLength, maxColumnLength, degFreedom, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = xArray.mapValue((xObject, rowIndex, columnIndex) => { + const degFreedomObject = degFreedomArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (xObject.isError()) { + return xObject; + } + + if (degFreedomObject.isError()) { + return degFreedomObject; + } + + return this._handleSignleObject(xObject, degFreedomObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + xObject: BaseValueObject, + degFreedomObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(xObject, degFreedomObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_xObject, _degFreedomObject] = variants as BaseValueObject[]; + + const xValue = +_xObject.getValue(); + const degFreedomValue = Math.floor(+_degFreedomObject.getValue()); + + if (degFreedomValue < 1 || degFreedomValue > 10 ** 10) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const result = studentTCDF(-xValue, degFreedomValue); + + if (Number.isNaN(result) || !Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/t-dist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/t-dist/__tests__/index.spec.ts new file mode 100644 index 000000000000..700a1829936d --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/t-dist/__tests__/index.spec.ts @@ -0,0 +1,130 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { TDist } from '../index'; + +describe('Test tDist function', () => { + const testFunction = new TDist(FUNCTION_NAMES_STATISTICAL.T_DIST); + + describe('TDist', () => { + it('Value is normal', () => { + const x = NumberValueObject.create(1); + const degFreedom = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, degFreedom, cumulative); + expect(getObjectValue(result)).toBe(0.7886751345947991); + }); + + it('DegFreedom value test', () => { + const x = NumberValueObject.create(1); + const degFreedom = NumberValueObject.create(0); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, degFreedom, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const degFreedom2 = NumberValueObject.create(10 ** 10 + 1); + const result2 = testFunction.calculate(x, degFreedom2, cumulative); + expect(getObjectValue(result2)).toBe(0.8413445661820564); + }); + + it('Cumulative value test', () => { + const x = NumberValueObject.create(1); + const degFreedom = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(false); + const result = testFunction.calculate(x, degFreedom, cumulative); + expect(getObjectValue(result)).toBe(0.19245008972987523); + }); + + it('Value is normal string', () => { + const x = StringValueObject.create('test'); + const degFreedom = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, degFreedom, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const x = BooleanValueObject.create(true); + const degFreedom = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, degFreedom, cumulative); + expect(getObjectValue(result)).toBe(0.7886751345947991); + }); + + it('Value is null', () => { + const x = NullValueObject.create(); + const degFreedom = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, degFreedom, cumulative); + expect(getObjectValue(result)).toBe(0.5); + }); + + it('Value is error', () => { + const x = ErrorValueObject.create(ErrorType.NAME); + const degFreedom = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, degFreedom, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(1); + const degFreedom2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, degFreedom2, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const cumulative2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(x2, degFreedom, cumulative2); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const x = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const degFreedom = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, degFreedom, cumulative); + expect(getObjectValue(result)).toStrictEqual([ + [0.7886751345947991, ErrorType.VALUE, 0.8281271922251572, 0.7886751345947991, 0.5, 0.5], + [0.5, 0.9999500074987502, 0.9279202455248455, ErrorType.VALUE, 0.04773298313135456, ErrorType.NAME], + ]); + }); + + it('More test', () => { + const x = NumberValueObject.create(0.1); + const degFreedom = NumberValueObject.create(900000000); + const cumulative = NumberValueObject.create(1); + const result = testFunction.calculate(x, degFreedom, cumulative); + expect(getObjectValue(result)).toBe(0.5398278542610474); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/t-dist/index.ts b/packages/engine-formula/src/functions/statistical/t-dist/index.ts new file mode 100644 index 000000000000..a358aae9f07a --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/t-dist/index.ts @@ -0,0 +1,113 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { studentTCDF, studentTPDF } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class TDist extends BaseFunction { + override minParams = 3; + + override maxParams = 3; + + override calculate( + x: BaseValueObject, + degFreedom: BaseValueObject, + cumulative: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getRowCount() : 1, + degFreedom.isArray() ? (degFreedom as ArrayValueObject).getRowCount() : 1, + cumulative.isArray() ? (cumulative as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getColumnCount() : 1, + degFreedom.isArray() ? (degFreedom as ArrayValueObject).getColumnCount() : 1, + cumulative.isArray() ? (cumulative as ArrayValueObject).getColumnCount() : 1 + ); + + const xArray = expandArrayValueObject(maxRowLength, maxColumnLength, x, ErrorValueObject.create(ErrorType.NA)); + const degFreedomArray = expandArrayValueObject(maxRowLength, maxColumnLength, degFreedom, ErrorValueObject.create(ErrorType.NA)); + const cumulativeArray = expandArrayValueObject(maxRowLength, maxColumnLength, cumulative, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = xArray.mapValue((xObject, rowIndex, columnIndex) => { + const degFreedomObject = degFreedomArray.get(rowIndex, columnIndex) as BaseValueObject; + const cumulativeObject = cumulativeArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (xObject.isError()) { + return xObject; + } + + if (degFreedomObject.isError()) { + return degFreedomObject; + } + + if (cumulativeObject.isError()) { + return cumulativeObject; + } + + return this._handleSignleObject(xObject, degFreedomObject, cumulativeObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + xObject: BaseValueObject, + degFreedomObject: BaseValueObject, + cumulativeObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(xObject, degFreedomObject, cumulativeObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_xObject, _degFreedomObject, _cumulativeObject] = variants as BaseValueObject[]; + + const xValue = +_xObject.getValue(); + const degFreedomValue = Math.floor(+_degFreedomObject.getValue()); + const cumulativeValue = +_cumulativeObject.getValue(); + + if (degFreedomValue < 1) { + return ErrorValueObject.create(ErrorType.NUM); + } + + let result; + + if (cumulativeValue) { + result = studentTCDF(xValue, degFreedomValue); + } else { + result = studentTPDF(xValue, degFreedomValue); + } + + if (Number.isNaN(result) || !Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/t-inv-2t/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/t-inv-2t/__tests__/index.spec.ts new file mode 100644 index 000000000000..e89ba25e3835 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/t-inv-2t/__tests__/index.spec.ts @@ -0,0 +1,103 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { TInv2t } from '../index'; + +describe('Test tInv2t function', () => { + const testFunction = new TInv2t(FUNCTION_NAMES_STATISTICAL.T_INV_2T); + + describe('TInv2t', () => { + it('Value is normal', () => { + const probability = NumberValueObject.create(0.75); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(probability, degFreedom); + expect(getObjectValue(result)).toBe(0.36514837167012903); + }); + + it('DegFreedom value test', () => { + const probability = NumberValueObject.create(0.75); + const degFreedom = NumberValueObject.create(0); + const result = testFunction.calculate(probability, degFreedom); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const degFreedom2 = NumberValueObject.create(10 ** 10 + 1); + const result2 = testFunction.calculate(probability, degFreedom2); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + }); + + it('Value is normal string', () => { + const probability = StringValueObject.create('test'); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(probability, degFreedom); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const probability = BooleanValueObject.create(true); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(probability, degFreedom); + expect(getObjectValue(result)).toBe(0); + }); + + it('Value is null', () => { + const probability = NullValueObject.create(); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(probability, degFreedom); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Value is error', () => { + const probability = ErrorValueObject.create(ErrorType.NAME); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(probability, degFreedom); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const probability2 = NumberValueObject.create(0.75); + const degFreedom2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(probability2, degFreedom2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const probability = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(probability, degFreedom); + expect(getObjectValue(result)).toStrictEqual([ + [0, ErrorType.VALUE, ErrorType.NUM, 0, ErrorType.NUM, ErrorType.NUM], + [ErrorType.NUM, ErrorType.NUM, ErrorType.NUM, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/t-inv-2t/index.ts b/packages/engine-formula/src/functions/statistical/t-inv-2t/index.ts new file mode 100644 index 000000000000..b6f5a41c71e4 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/t-inv-2t/index.ts @@ -0,0 +1,96 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ErrorType } from '../../../basics/error-type'; +import { studentTINV } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; + +export class TInv2t extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate( + probability: BaseValueObject, + degFreedom: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + probability.isArray() ? (probability as ArrayValueObject).getRowCount() : 1, + degFreedom.isArray() ? (degFreedom as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + probability.isArray() ? (probability as ArrayValueObject).getColumnCount() : 1, + degFreedom.isArray() ? (degFreedom as ArrayValueObject).getColumnCount() : 1 + ); + + const probabilityArray = expandArrayValueObject(maxRowLength, maxColumnLength, probability, ErrorValueObject.create(ErrorType.NA)); + const degFreedomArray = expandArrayValueObject(maxRowLength, maxColumnLength, degFreedom, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = probabilityArray.mapValue((probabilityObject, rowIndex, columnIndex) => { + const degFreedomObject = degFreedomArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (probabilityObject.isError()) { + return probabilityObject; + } + + if (degFreedomObject.isError()) { + return degFreedomObject; + } + + return this._handleSignleObject(probabilityObject, degFreedomObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + probabilityObject: BaseValueObject, + degFreedomObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(probabilityObject, degFreedomObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_probabilityObject, _degFreedomObject] = variants as BaseValueObject[]; + + const probabilityValue = +_probabilityObject.getValue(); + const degFreedomValue = Math.floor(+_degFreedomObject.getValue()); + + if (probabilityValue <= 0 || probabilityValue > 1 || degFreedomValue < 1 || degFreedomValue > 10 ** 10) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const result = Math.abs(studentTINV(probabilityValue / 2, degFreedomValue)); + + if (Number.isNaN(result) || !Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/t-inv/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/t-inv/__tests__/index.spec.ts new file mode 100644 index 000000000000..07a335e0b872 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/t-inv/__tests__/index.spec.ts @@ -0,0 +1,103 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { TInv } from '../index'; + +describe('Test tInv function', () => { + const testFunction = new TInv(FUNCTION_NAMES_STATISTICAL.T_INV); + + describe('TInv', () => { + it('Value is normal', () => { + const probability = NumberValueObject.create(0.75); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(probability, degFreedom); + expect(getObjectValue(result)).toBe(0.8164965809277775); + }); + + it('DegFreedom value test', () => { + const probability = NumberValueObject.create(0.75); + const degFreedom = NumberValueObject.create(0); + const result = testFunction.calculate(probability, degFreedom); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const degFreedom2 = NumberValueObject.create(10 ** 10 + 1); + const result2 = testFunction.calculate(probability, degFreedom2); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + }); + + it('Value is normal string', () => { + const probability = StringValueObject.create('test'); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(probability, degFreedom); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const probability = BooleanValueObject.create(true); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(probability, degFreedom); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Value is null', () => { + const probability = NullValueObject.create(); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(probability, degFreedom); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + }); + + it('Value is error', () => { + const probability = ErrorValueObject.create(ErrorType.NAME); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(probability, degFreedom); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const probability2 = NumberValueObject.create(0.75); + const degFreedom2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(probability2, degFreedom2); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const probability = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const degFreedom = NumberValueObject.create(2); + const result = testFunction.calculate(probability, degFreedom); + expect(getObjectValue(result)).toStrictEqual([ + [ErrorType.NUM, ErrorType.VALUE, ErrorType.NUM, ErrorType.NUM, ErrorType.NUM, ErrorType.NUM], + [ErrorType.NUM, ErrorType.NUM, ErrorType.NUM, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/t-inv/index.ts b/packages/engine-formula/src/functions/statistical/t-inv/index.ts new file mode 100644 index 000000000000..2005115eceef --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/t-inv/index.ts @@ -0,0 +1,96 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ErrorType } from '../../../basics/error-type'; +import { studentTINV } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; + +export class TInv extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate( + probability: BaseValueObject, + degFreedom: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + probability.isArray() ? (probability as ArrayValueObject).getRowCount() : 1, + degFreedom.isArray() ? (degFreedom as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + probability.isArray() ? (probability as ArrayValueObject).getColumnCount() : 1, + degFreedom.isArray() ? (degFreedom as ArrayValueObject).getColumnCount() : 1 + ); + + const probabilityArray = expandArrayValueObject(maxRowLength, maxColumnLength, probability, ErrorValueObject.create(ErrorType.NA)); + const degFreedomArray = expandArrayValueObject(maxRowLength, maxColumnLength, degFreedom, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = probabilityArray.mapValue((probabilityObject, rowIndex, columnIndex) => { + const degFreedomObject = degFreedomArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (probabilityObject.isError()) { + return probabilityObject; + } + + if (degFreedomObject.isError()) { + return degFreedomObject; + } + + return this._handleSignleObject(probabilityObject, degFreedomObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + probabilityObject: BaseValueObject, + degFreedomObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(probabilityObject, degFreedomObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_probabilityObject, _degFreedomObject] = variants as BaseValueObject[]; + + const probabilityValue = +_probabilityObject.getValue(); + const degFreedomValue = Math.floor(+_degFreedomObject.getValue()); + + if (probabilityValue <= 0 || probabilityValue > 1 || degFreedomValue < 1 || degFreedomValue > 10 ** 10) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const result = studentTINV(probabilityValue, degFreedomValue); + + if (Number.isNaN(result) || !Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/t-test/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/t-test/__tests__/index.spec.ts new file mode 100644 index 000000000000..8091aa8a6f11 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/t-test/__tests__/index.spec.ts @@ -0,0 +1,303 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { TTest } from '../index'; + +describe('Test tTest function', () => { + const testFunction = new TTest(FUNCTION_NAMES_STATISTICAL.T_TEST); + + describe('TTest', () => { + it('Value is normal', () => { + const array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [3, 4, 5, 8, 9, 1, 2, 4, 5], + ]), + rowCount: 1, + columnCount: 9, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [6, 19, 3, 2, 14, 4, 5, 17, 1], + ]), + rowCount: 1, + columnCount: 9, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const tails = NumberValueObject.create(2); + const type = NumberValueObject.create(1); + const result = testFunction.calculate(array1, array2, tails, type); + expect(getObjectValue(result)).toBe(0.19601578492531546); + }); + + it('Array1 and array2 value test', () => { + let array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0, 1, 2, 3, null], + ]), + rowCount: 1, + columnCount: 5, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + let array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0.2, 0.3, 0.1, 0.4], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const tails = NumberValueObject.create(2); + const type = NumberValueObject.create(1); + let result = testFunction.calculate(array1, array2, tails, type); + expect(getObjectValue(result)).toBe(ErrorType.NA); + + array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + result = testFunction.calculate(array1, array2, tails, type); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + + array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null, true, false, 'test'], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0.2, 0.3, 0.1, 0.4], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + result = testFunction.calculate(array1, array2, tails, type); + expect(getObjectValue(result)).toBe(ErrorType.DIV_BY_ZERO); + + array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [ErrorType.NAME, 1, 2, 3], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + result = testFunction.calculate(array1, array2, tails, type); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const array3 = ErrorValueObject.create(ErrorType.NAME); + const array4 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0.2, 0.3, 0.1, 0.4], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(array3, array4, tails, type); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const array5 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [0, 1, 2, 3], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array6 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(array5, array6, tails, type); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + }); + + it('Tails value test', () => { + const array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [3, 4, 5, 8, 9, 1, 2, 4, 5], + ]), + rowCount: 1, + columnCount: 9, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [6, 19, 3, 2, 14, 4, 5, 17, 1], + ]), + rowCount: 1, + columnCount: 9, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const tails = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [-1, 0, 1, 2, 3, true, false, null, 'test', ErrorType.NAME], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const type = NumberValueObject.create(1); + const result = testFunction.calculate(array1, array2, tails, type); + expect(getObjectValue(result)).toStrictEqual([ + [ErrorType.NUM, ErrorType.NUM, 0.09800789246265773, 0.19601578492531546, ErrorType.NUM, 0.09800789246265773, ErrorType.NUM, ErrorType.NUM, ErrorType.VALUE, ErrorType.NAME], + ]); + }); + + it('Type Value is normal', () => { + const array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [3, 4, 5, 8, 9, 1, 2, 4, 5], + ]), + rowCount: 1, + columnCount: 9, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [6, 19, 3, 2, 14, 4, 5, 17, 1], + ]), + rowCount: 1, + columnCount: 9, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const tails = NumberValueObject.create(2); + const type = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [-1, 0, 1, 2, 3, true, false, null, 'test', ErrorType.NAME], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array1, array2, tails, type); + expect(getObjectValue(result)).toStrictEqual([ + [ErrorType.NUM, ErrorType.NUM, 0.19601578492531546, 0.1919958867250542, 0.20229392336804775, 0.19601578492531546, ErrorType.NUM, ErrorType.NUM, ErrorType.VALUE, ErrorType.NAME], + ]); + }); + + it('More test', () => { + const array1 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [-10, 1], + [-8, 3], + ]), + rowCount: 2, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const array2 = NumberValueObject.create(0); + const tails = NumberValueObject.create(2); + const type = NumberValueObject.create(2); + const result = testFunction.calculate(array1, array2, tails, type); + expect(getObjectValue(result)).toBe(ErrorType.DIV_BY_ZERO); + + const array3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, 2], + ]), + rowCount: 1, + columnCount: 2, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(array1, array3, tails, type); + expect(getObjectValue(result2)).toBe(0.3609071062401591); + + const type2 = NumberValueObject.create(3); + const result3 = testFunction.calculate(array1, array3, tails, type2); + expect(getObjectValue(result3)).toBe(0.21930610212734247); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/t-test/index.ts b/packages/engine-formula/src/functions/statistical/t-test/index.ts new file mode 100644 index 000000000000..f6207f5b43da --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/t-test/index.ts @@ -0,0 +1,409 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { getTwoArrayNumberValues, studentTCDF } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class TTest extends BaseFunction { + override minParams = 4; + + override maxParams = 4; + + // eslint-disable-next-line + override calculate(array1: BaseValueObject, array2: BaseValueObject, tails: BaseValueObject, type: BaseValueObject): BaseValueObject { + // Calculate first array1 and array2 + // type === 1 + const { isError: isError_sp, errorObject: errorObject_sp, array1Values: array1Values_sp, array2Values: array2Values_sp } = this._handleArray1AndArray2(array1, array2); + // type !== 1 + const array1Values = this._getArrayValues(array1); + const array2Values = this._getArrayValues(array2); + + const maxRowLength = Math.max( + tails.isArray() ? (tails as ArrayValueObject).getRowCount() : 1, + type.isArray() ? (type as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + tails.isArray() ? (tails as ArrayValueObject).getColumnCount() : 1, + type.isArray() ? (type as ArrayValueObject).getColumnCount() : 1 + ); + + const tailsArray = expandArrayValueObject(maxRowLength, maxColumnLength, tails, ErrorValueObject.create(ErrorType.NA)); + const typeArray = expandArrayValueObject(maxRowLength, maxColumnLength, type, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = tailsArray.mapValue((tailsObject, rowIndex, columnIndex) => { + const typeObject = typeArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (array1.isError()) { + return array1; + } + + if (array2.isError()) { + return array2; + } + + if (tailsObject.isError()) { + return tailsObject; + } + + if (typeObject.isError()) { + return typeObject; + } + + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(tailsObject, typeObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_tailsObject, _typeObject] = variants as BaseValueObject[]; + + const tailsValue = Math.floor(+_tailsObject.getValue()); + const typeValue = Math.floor(+_typeObject.getValue()); + + if (![1, 2].includes(tailsValue) || ![1, 2, 3].includes(typeValue)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + if (typeValue === 1 && isError_sp) { + return errorObject_sp as ErrorValueObject; + } + + if (typeValue !== 1 && array1Values instanceof ErrorValueObject) { + return array1Values as ErrorValueObject; + } + + if (typeValue !== 1 && array2Values instanceof ErrorValueObject) { + return array2Values as ErrorValueObject; + } + + return this._handleSignleObject( + (typeValue === 1 ? array1Values_sp : array1Values) as number[], + (typeValue === 1 ? array2Values_sp : array2Values) as number[], + tailsValue, + typeValue + ); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + array1Values: number[], + array2Values: number[], + tails: number, + type: number + ): BaseValueObject { + if (array1Values.length < 2 || array2Values.length < 2) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + const { isError, errorObject, x, degFreedom } = this._getTDistParamByArrayValues(array1Values, array2Values, type); + + if (isError) { + return errorObject as ErrorValueObject; + } + + let result = studentTCDF(-x, degFreedom); + + if (tails === 2) { + result *= 2; + } + + if (Number.isNaN(result) || !Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return NumberValueObject.create(result); + } + + private _getArrayValues(array: BaseValueObject): number[] | ErrorValueObject { + const rowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; + const columnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; + + const arrayValues: number[] = []; + + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const valueObject = array.isArray() ? (array as ArrayValueObject).get(r, c) as BaseValueObject : array; + + if (valueObject.isError()) { + return valueObject as ErrorValueObject; + } + + if (valueObject.isNull()) { + if (rowCount * columnCount === 1) { + return ErrorValueObject.create(ErrorType.VALUE); + } + + continue; + } + + if (valueObject.isBoolean() || valueObject.isString()) { + continue; + } + + arrayValues.push(+valueObject.getValue()); + } + } + + return arrayValues; + } + + // eslint-disable-next-line + private _handleArray1AndArray2(array1: BaseValueObject, array2: BaseValueObject) { + const array1RowCount = array1.isArray() ? (array1 as ArrayValueObject).getRowCount() : 1; + const array1ColumnCount = array1.isArray() ? (array1 as ArrayValueObject).getColumnCount() : 1; + + const array2RowCount = array2.isArray() ? (array2 as ArrayValueObject).getRowCount() : 1; + const array2ColumnCount = array2.isArray() ? (array2 as ArrayValueObject).getColumnCount() : 1; + + let _array1 = array1; + + if (array1.isArray() && array1RowCount === 1 && array1ColumnCount === 1) { + _array1 = (array1 as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_array1.isError()) { + return { + isError: true, + errorObject: _array1 as ErrorValueObject, + array1Values: [], + array2Values: [], + }; + } + + let _array2 = array2; + + if (array2.isArray() && array2RowCount === 1 && array2ColumnCount === 1) { + _array2 = (array2 as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + if (_array2.isError()) { + return { + isError: true, + errorObject: _array2 as ErrorValueObject, + array1Values: [], + array2Values: [], + }; + } + + if (array1RowCount * array1ColumnCount === 1 || array2RowCount * array2ColumnCount === 1) { + if (_array1.isNull() || _array2.isNull()) { + return { + isError: true, + errorObject: ErrorValueObject.create(ErrorType.VALUE), + array1Values: [], + array2Values: [], + }; + } + } + + if (array1RowCount * array1ColumnCount !== array2RowCount * array2ColumnCount) { + return { + isError: true, + errorObject: ErrorValueObject.create(ErrorType.NA), + array1Values: [], + array2Values: [], + }; + } + + const { + isError, + errorObject, + array1Values, + array2Values, + noCalculate, + } = getTwoArrayNumberValues( + array1, + array2, + array1RowCount * array1ColumnCount, + array1ColumnCount, + array2ColumnCount + ); + + if (isError) { + return { + isError: true, + errorObject, + array1Values: [], + array2Values: [], + }; + } + + if (noCalculate || array1Values.length < 2) { + return { + isError: true, + errorObject: ErrorValueObject.create(ErrorType.DIV_BY_ZERO), + array1Values: [], + array2Values: [], + }; + } + + return { + isError: false, + errorObject: null, + array1Values, + array2Values, + }; + } + + private _getTDistParamByArrayValues(array1Values: number[], array2Values: number[], type: number) { + if (type === 1) { + return this._getTDistParamByType1(array1Values, array2Values); + } else if (type === 2) { + return this._getTDistParamByType2(array1Values, array2Values); + } else { + return this._getTDistParamByType3(array1Values, array2Values); + } + }; + + private _getTDistParamByType1(array1Values: number[], array2Values: number[]) { + const n = array1Values.length; + + let sum1 = 0; + let sum2 = 0; + let sumSquareDiff = 0; + + for (let i = 0; i < n; i++) { + sum1 += array1Values[i]; + sum2 += array2Values[i]; + sumSquareDiff += (array1Values[i] - array2Values[i]) ** 2; + } + + const sumDiff = sum1 - sum2; + const den = n * sumSquareDiff - sumDiff ** 2; + const degFreedom = n - 1; + + if (den === 0) { + return { + isError: true, + errorObject: ErrorValueObject.create(ErrorType.DIV_BY_ZERO), + x: 0, + degFreedom, + }; + } + + const x = Math.abs(sumDiff) * Math.sqrt(degFreedom / den); + + return { + isError: false, + errorObject: null, + x, + degFreedom, + }; + } + + private _getTDistParamByType2(array1Values: number[], array2Values: number[]) { + const array1Length = array1Values.length; + const array2Length = array2Values.length; + + let sum1 = 0; + let sumSquare1 = 0; + + for (let i = 0; i < array1Length; i++) { + sum1 += array1Values[i]; + sumSquare1 += array1Values[i] ** 2; + } + + let sum2 = 0; + let sumSquare2 = 0; + + for (let i = 0; i < array2Length; i++) { + sum2 += array2Values[i]; + sumSquare2 += array2Values[i] ** 2; + } + + const temp1 = sumSquare1 - sum1 ** 2 / array1Length; + const temp2 = sumSquare2 - sum2 ** 2 / array2Length; + const den = Math.sqrt(temp1 + temp2); + + if (den === 0) { + return { + isError: true, + errorObject: ErrorValueObject.create(ErrorType.DIV_BY_ZERO), + x: 0, + degFreedom: 0, + }; + } + + const degFreedom = array1Length - 1 + array2Length - 1; + const temp3 = Math.sqrt(array1Length * array2Length * degFreedom / (array1Length + array2Length)); + const x = Math.abs(sum1 / array1Length - sum2 / array2Length) / den * temp3; + + return { + isError: false, + errorObject: null, + x, + degFreedom, + }; + } + + private _getTDistParamByType3(array1Values: number[], array2Values: number[]) { + const array1Length = array1Values.length; + const array2Length = array2Values.length; + + let sum1 = 0; + let sumSquare1 = 0; + + for (let i = 0; i < array1Length; i++) { + sum1 += array1Values[i]; + sumSquare1 += array1Values[i] ** 2; + } + + let sum2 = 0; + let sumSquare2 = 0; + + for (let i = 0; i < array2Length; i++) { + sum2 += array2Values[i]; + sumSquare2 += array2Values[i] ** 2; + } + + const temp1 = (sumSquare1 - sum1 ** 2 / array1Length) / (array1Length * (array1Length - 1)); + const temp2 = (sumSquare2 - sum2 ** 2 / array2Length) / (array2Length * (array2Length - 1)); + + if (temp1 + temp2 === 0) { + return { + isError: true, + errorObject: ErrorValueObject.create(ErrorType.DIV_BY_ZERO), + x: 0, + degFreedom: 0, + }; + } + + const temp3 = temp1 / (temp1 + temp2); + + const x = Math.abs(sum1 / array1Length - sum2 / array2Length) / Math.sqrt(temp1 + temp2); + const degFreedom = 1 / (temp3 ** 2 / (array1Length - 1) + ((1 - temp3) ** 2) / (array2Length - 1)); + + return { + isError: false, + errorObject: null, + x, + degFreedom, + }; + } +} diff --git a/packages/engine-formula/src/functions/statistical/trimmean/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/trimmean/__tests__/index.spec.ts new file mode 100644 index 000000000000..1675d2b58fa4 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/trimmean/__tests__/index.spec.ts @@ -0,0 +1,126 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { Trimmean } from '../index'; + +describe('Test trimmean function', () => { + const testFunction = new Trimmean(FUNCTION_NAMES_STATISTICAL.TRIMMEAN); + + describe('Trimmean', () => { + it('Value is normal', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [11, 2, 3, 4, 5, 6, 7, 8, 9], + ]), + rowCount: 1, + columnCount: 9, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const percent = NumberValueObject.create(0.3); + const result = testFunction.calculate(array, percent); + expect(getObjectValue(result)).toStrictEqual(6); + }); + + it('Array value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, null, true, false, 'test', 6, 7, 8, ErrorType.NAME], + ]), + rowCount: 1, + columnCount: 9, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const percent = NumberValueObject.create(0.3); + const result = testFunction.calculate(array, percent); + expect(getObjectValue(result)).toStrictEqual(ErrorType.NAME); + + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null, true, false, 'test'], + ]), + rowCount: 1, + columnCount: 4, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(array2, percent); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NUM); + }); + + it('Percent value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [11, 2, 3, 4, 5, 6, 7, 8, 9], + ]), + rowCount: 1, + columnCount: 9, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const percent = NumberValueObject.create(0.1); + const result = testFunction.calculate(array, percent); + expect(getObjectValue(result)).toStrictEqual(6.111111111111111); + + const percent2 = NumberValueObject.create(11); + const result2 = testFunction.calculate(array, percent2); + expect(getObjectValue(result2)).toStrictEqual(ErrorType.NUM); + + const percent3 = BooleanValueObject.create(true); + const result3 = testFunction.calculate(array, percent3); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.NUM); + + const percent4 = NullValueObject.create(); + const result4 = testFunction.calculate(array, percent4); + expect(getObjectValue(result4)).toStrictEqual(6.111111111111111); + + const percent5 = StringValueObject.create('test'); + const result5 = testFunction.calculate(array, percent5); + expect(getObjectValue(result5)).toStrictEqual(ErrorType.VALUE); + + const percent6 = ErrorValueObject.create(ErrorType.NAME); + const result6 = testFunction.calculate(array, percent6); + expect(getObjectValue(result6)).toStrictEqual(ErrorType.NAME); + + const percent7 = ArrayValueObject.create('{0.1,0.2,0.3}'); + const result7 = testFunction.calculate(array, percent7); + expect(getObjectValue(result7)).toStrictEqual([ + [6.111111111111111, 6.111111111111111, 6], + ]); + + const percent8 = ArrayValueObject.create('{0.9}'); + const result8 = testFunction.calculate(array, percent8); + expect(getObjectValue(result8)).toStrictEqual(6); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/trimmean/index.ts b/packages/engine-formula/src/functions/statistical/trimmean/index.ts new file mode 100644 index 000000000000..d1239988b5ca --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/trimmean/index.ts @@ -0,0 +1,110 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { floor } from '../../../engine/utils/math-kit'; +import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; + +export class Trimmean extends BaseFunction { + override minParams = 2; + + override maxParams = 2; + + override calculate(array: BaseValueObject, percent: BaseValueObject): BaseValueObject { + const arrayValues = this._getValues(array); + + if (percent.isArray()) { + const resultArray = (percent as ArrayValueObject).mapValue((percentObject) => this._handleSingleObject(arrayValues, percentObject)); + + if ((resultArray as ArrayValueObject).getRowCount() === 1 && (resultArray as ArrayValueObject).getColumnCount() === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + return this._handleSingleObject(arrayValues, percent); + } + + private _handleSingleObject(array: number[] | ErrorValueObject, percent: BaseValueObject): BaseValueObject { + if (array instanceof ErrorValueObject) { + return array; + } + + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(percent); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [percentObject] = variants as BaseValueObject[]; + + const percentValue = +percentObject.getValue(); + + if (percentValue < 0 || percentValue >= 1) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const count = floor(array.length * percentValue / 2, 0) * 2; + + const newArray = array.slice(count / 2, array.length - count / 2); + + const result = newArray.reduce((acc, cur) => acc + cur, 0) / newArray.length; + + return NumberValueObject.create(result); + } + + private _getValues(array: BaseValueObject): number[] | ErrorValueObject { + const rowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; + const columnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; + + const values: number[] = []; + + for (let r = 0; r < rowCount; r++) { + for (let c = 0; c < columnCount; c++) { + const valueObject = array.isArray() ? (array as ArrayValueObject).get(r, c) as BaseValueObject : array; + + if (valueObject.isError()) { + return valueObject as ErrorValueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + values.push(+value); + } + } + + if (values.length === 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return values.sort((a, b) => a - b); + } +} diff --git a/packages/engine-formula/src/functions/statistical/weibull-dist/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/weibull-dist/__tests__/index.spec.ts new file mode 100644 index 000000000000..c246e83e8e43 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/weibull-dist/__tests__/index.spec.ts @@ -0,0 +1,181 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; +import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { WeibullDist } from '../index'; + +describe('Test weibullDist function', () => { + const testFunction = new WeibullDist(FUNCTION_NAMES_STATISTICAL.WEIBULL_DIST); + + describe('WeibullDist', () => { + it('Value is normal', () => { + const x = NumberValueObject.create(10); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(1); + }); + + it('Alpha and beta value test', () => { + const x = NumberValueObject.create(10); + const alpha = NumberValueObject.create(0); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NUM); + + const alpha2 = NumberValueObject.create(8); + const beta2 = NumberValueObject.create(0); + const result2 = testFunction.calculate(x, alpha2, beta2, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + + const alpha3 = NumberValueObject.create(1); + const beta3 = NumberValueObject.create(1); + const result3 = testFunction.calculate(x, alpha3, beta3, cumulative); + expect(getObjectValue(result3)).toBe(0.9999546000702375); + + const alpha4 = NumberValueObject.create(5); + const result4 = testFunction.calculate(x, alpha4, beta, cumulative); + expect(getObjectValue(result4)).toBe(1); + }); + + it('X value test', () => { + const x = NumberValueObject.create(0); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(0); + + const x2 = NumberValueObject.create(-1); + const result2 = testFunction.calculate(x2, alpha, beta, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NUM); + }); + + it('Cumulative value is normal', () => { + const x = NumberValueObject.create(10); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(false); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(0); + + const alpha2 = NumberValueObject.create(1); + const beta2 = NumberValueObject.create(1); + const result2 = testFunction.calculate(x, alpha2, beta2, cumulative); + expect(getObjectValue(result2)).toBe(0.00004539992976248485); + + const x2 = NumberValueObject.create(3); + const result3 = testFunction.calculate(x2, alpha2, beta2, cumulative); + expect(getObjectValue(result3)).toBe(0.049787068367863944); + + const alpha3 = NumberValueObject.create(520); + const beta3 = NumberValueObject.create(520); + const result4 = testFunction.calculate(x, alpha3, beta3, cumulative); + expect(getObjectValue(result4)).toBe(ErrorType.NUM); + + const alpha4 = NumberValueObject.create(350); + const beta4 = NumberValueObject.create(350); + const result5 = testFunction.calculate(x, alpha4, beta4, cumulative); + expect(getObjectValue(result5)).toBe(ErrorType.NUM); + + const alpha5 = NumberValueObject.create(0.1); + const beta5 = NumberValueObject.create(0.1); + const result6 = testFunction.calculate(x, alpha5, beta5, cumulative); + expect(getObjectValue(result6)).toBe(0.003248550572370161); + }); + + it('Value is normal string', () => { + const x = StringValueObject.create('test'); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.VALUE); + }); + + it('Value is boolean', () => { + const x = BooleanValueObject.create(true); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(0.0038986305298824853); + }); + + it('Value is null', () => { + const x = NullValueObject.create(); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(0); + }); + + it('Value is error', () => { + const x = ErrorValueObject.create(ErrorType.NAME); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const x2 = NumberValueObject.create(10); + const alpha2 = ErrorValueObject.create(ErrorType.NAME); + const result2 = testFunction.calculate(x2, alpha2, beta, cumulative); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + + const beta2 = ErrorValueObject.create(ErrorType.NAME); + const result3 = testFunction.calculate(x2, alpha, beta2, cumulative); + expect(getObjectValue(result3)).toBe(ErrorType.NAME); + + const cumulative2 = ErrorValueObject.create(ErrorType.NAME); + const result4 = testFunction.calculate(x2, alpha, beta, cumulative2); + expect(getObjectValue(result4)).toBe(ErrorType.NAME); + }); + + it('Value is array', () => { + const x = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [1, ' ', 1.23, true, false, null], + [0, '100', '2.34', 'test', -3, ErrorType.NAME], + ]), + rowCount: 2, + columnCount: 6, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const alpha = NumberValueObject.create(8); + const beta = NumberValueObject.create(2); + const cumulative = BooleanValueObject.create(true); + const result = testFunction.calculate(x, alpha, beta, cumulative); + expect(getObjectValue(result)).toStrictEqual([ + [0.0038986305298824853, ErrorType.VALUE, 0.02025651346279278, 0.0038986305298824853, 0, 0], + [0, 1, 0.9701465024693557, ErrorType.VALUE, ErrorType.NUM, ErrorType.NAME], + ]); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/weibull-dist/index.ts b/packages/engine-formula/src/functions/statistical/weibull-dist/index.ts new file mode 100644 index 000000000000..5618ff0e9f74 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/weibull-dist/index.ts @@ -0,0 +1,125 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { ErrorType } from '../../../basics/error-type'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class WeibullDist extends BaseFunction { + override minParams = 4; + + override maxParams = 4; + + override calculate( + x: BaseValueObject, + alpha: BaseValueObject, + beta: BaseValueObject, + cumulative: BaseValueObject + ): BaseValueObject { + const maxRowLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getRowCount() : 1, + alpha.isArray() ? (alpha as ArrayValueObject).getRowCount() : 1, + beta.isArray() ? (beta as ArrayValueObject).getRowCount() : 1, + cumulative.isArray() ? (cumulative as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getColumnCount() : 1, + alpha.isArray() ? (alpha as ArrayValueObject).getColumnCount() : 1, + beta.isArray() ? (beta as ArrayValueObject).getColumnCount() : 1, + cumulative.isArray() ? (cumulative as ArrayValueObject).getColumnCount() : 1 + ); + + const xArray = expandArrayValueObject(maxRowLength, maxColumnLength, x, ErrorValueObject.create(ErrorType.NA)); + const alphaArray = expandArrayValueObject(maxRowLength, maxColumnLength, alpha, ErrorValueObject.create(ErrorType.NA)); + const betaArray = expandArrayValueObject(maxRowLength, maxColumnLength, beta, ErrorValueObject.create(ErrorType.NA)); + const cumulativeArray = expandArrayValueObject(maxRowLength, maxColumnLength, cumulative, ErrorValueObject.create(ErrorType.NA)); + + const resultArray = xArray.mapValue((xObject, rowIndex, columnIndex) => { + const alphaObject = alphaArray.get(rowIndex, columnIndex) as BaseValueObject; + const betaObject = betaArray.get(rowIndex, columnIndex) as BaseValueObject; + const cumulativeObject = cumulativeArray.get(rowIndex, columnIndex) as BaseValueObject; + + if (xObject.isError()) { + return xObject; + } + + if (alphaObject.isError()) { + return alphaObject; + } + + if (betaObject.isError()) { + return betaObject; + } + + if (cumulativeObject.isError()) { + return cumulativeObject; + } + + return this._handleSignleObject(xObject, alphaObject, betaObject, cumulativeObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + xObject: BaseValueObject, + alphaObject: BaseValueObject, + betaObject: BaseValueObject, + cumulativeObject: BaseValueObject + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(xObject, alphaObject, betaObject, cumulativeObject); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [_xObject, _alphaObject, _betaObject, _cumulativeObject] = variants as BaseValueObject[]; + + const xValue = +_xObject.getValue(); + const alphaValue = +_alphaObject.getValue(); + const betaValue = +_betaObject.getValue(); + const cumulativeValue = +_cumulativeObject.getValue(); + + if (xValue < 0 || alphaValue <= 0 || betaValue <= 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const exp = Math.exp(-((xValue / betaValue) ** alphaValue)); + + let result; + + if (cumulativeValue) { + result = 1 - exp; + } else { + result = alphaValue / (betaValue ** alphaValue) * (xValue ** (alphaValue - 1)) * exp; + } + + if (Number.isNaN(result) || !Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return NumberValueObject.create(result); + } +} diff --git a/packages/engine-formula/src/functions/statistical/z-test/__tests__/index.spec.ts b/packages/engine-formula/src/functions/statistical/z-test/__tests__/index.spec.ts new file mode 100644 index 000000000000..4e2f3cf313cc --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/z-test/__tests__/index.spec.ts @@ -0,0 +1,168 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it } from 'vitest'; + +import { ErrorType } from '../../../../basics/error-type'; +import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object'; +import { NumberValueObject } from '../../../../engine/value-object/primitive-object'; +import { getObjectValue } from '../../../__tests__/create-function-test-bed'; +import { FUNCTION_NAMES_STATISTICAL } from '../../function-names'; +import { ZTest } from '../index'; + +describe('Test zTest function', () => { + const testFunction = new ZTest(FUNCTION_NAMES_STATISTICAL.Z_TEST); + + describe('ZTest', () => { + it('Value is normal', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [3, 6, 7, 8, 6, 5, 4, 2, 1, 9], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = NumberValueObject.create(4); + const result = testFunction.calculate(array, x); + expect(getObjectValue(result)).toBe(0.09057419685136392); + }); + + it('Value is number string', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + ['\'3', '\'6', '\'7', '\'8', '\'6', '\'5', '\'4', '\'2', '\'1', '\'9'], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = NumberValueObject.create(4); + const result = testFunction.calculate(array, x); + expect(getObjectValue(result)).toBe(ErrorType.NA); + }); + + it('Array value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [null], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = NumberValueObject.create(4); + const result = testFunction.calculate(array, x); + expect(getObjectValue(result)).toBe(ErrorType.NA); + + const array2 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [3], + ]), + rowCount: 1, + columnCount: 1, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result2 = testFunction.calculate(array2, x); + expect(getObjectValue(result2)).toBe(ErrorType.DIV_BY_ZERO); + + const array3 = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [3, true, false, null, 'test', 5, 4, 2, 1, ErrorType.NAME], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result3 = testFunction.calculate(array3, x); + expect(getObjectValue(result3)).toStrictEqual(ErrorType.NAME); + }); + + it('X value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [3, 6, 7, 8, 6, 5, 4, 2, 1, 9], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [-4, 100, 2.34, true, false, null, 'test', ErrorType.NAME], + ]), + rowCount: 1, + columnCount: 8, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array, x); + expect(getObjectValue(result)).toStrictEqual([ + [0, 1, 0.00039650182754802366, 3.1107494757876e-7, 2.8254398820592996e-10, 2.8254398820592996e-10, ErrorType.VALUE, ErrorType.NAME], + ]); + }); + + it('Sigma value test', () => { + const array = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [3, 6, 7, 8, 6, 5, 4, 2, 1, 9], + ]), + rowCount: 1, + columnCount: 10, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const x = NumberValueObject.create(4); + const sigma = ArrayValueObject.create({ + calculateValueList: transformToValueObject([ + [-4, 100, 2.34, true, false, null, 'test', ErrorType.NAME], + ]), + rowCount: 1, + columnCount: 8, + unitId: '', + sheetId: '', + row: 0, + column: 0, + }); + const result = testFunction.calculate(array, x, sigma); + expect(getObjectValue(result)).toStrictEqual([ + [ErrorType.NUM, 0.48612556919551, 0.06856806925633085, 0.00025210911472450803, ErrorType.NUM, ErrorType.NUM, ErrorType.VALUE, ErrorType.NAME], + ]); + }); + }); +}); diff --git a/packages/engine-formula/src/functions/statistical/z-test/index.ts b/packages/engine-formula/src/functions/statistical/z-test/index.ts new file mode 100644 index 000000000000..c345864e7b43 --- /dev/null +++ b/packages/engine-formula/src/functions/statistical/z-test/index.ts @@ -0,0 +1,169 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ArrayValueObject } from '../../../engine/value-object/array-value-object'; +import { isRealNum } from '@univerjs/core'; +import { ErrorType } from '../../../basics/error-type'; +import { normalCDF } from '../../../basics/statistical'; +import { expandArrayValueObject } from '../../../engine/utils/array-object'; +import { checkVariantsErrorIsStringToNumber } from '../../../engine/utils/check-variant-error'; +import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object'; +import { NumberValueObject } from '../../../engine/value-object/primitive-object'; +import { BaseFunction } from '../../base-function'; + +export class ZTest extends BaseFunction { + override minParams = 2; + + override maxParams = 3; + + override calculate(array: BaseValueObject, x: BaseValueObject, sigma?: BaseValueObject): BaseValueObject { + const arrayValues = this._getArrayValues(array); + + const maxRowLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getRowCount() : 1, + sigma?.isArray() ? (sigma as ArrayValueObject).getRowCount() : 1 + ); + + const maxColumnLength = Math.max( + x.isArray() ? (x as ArrayValueObject).getColumnCount() : 1, + sigma?.isArray() ? (sigma as ArrayValueObject).getColumnCount() : 1 + ); + + const xArray = expandArrayValueObject(maxRowLength, maxColumnLength, x, ErrorValueObject.create(ErrorType.NA)); + const sigmaArray = sigma ? expandArrayValueObject(maxRowLength, maxColumnLength, sigma, ErrorValueObject.create(ErrorType.NA)) : undefined; + + const resultArray = xArray.mapValue((xObject, rowIndex, columnIndex) => { + if (arrayValues instanceof ErrorValueObject) { + return arrayValues; + } + + if (xObject.isError()) { + return xObject; + } + + const sigmaObject = sigma ? (sigmaArray as ArrayValueObject).get(rowIndex, columnIndex) as BaseValueObject : undefined; + + if (sigmaObject?.isError()) { + return sigmaObject; + } + + if (arrayValues.length === 0) { + return ErrorValueObject.create(ErrorType.NA); + } + + if (arrayValues.length === 1) { + return ErrorValueObject.create(ErrorType.DIV_BY_ZERO); + } + + return this._handleSignleObject(arrayValues as number[], xObject, sigmaObject); + }); + + if (maxRowLength === 1 && maxColumnLength === 1) { + return (resultArray as ArrayValueObject).get(0, 0) as BaseValueObject; + } + + return resultArray; + } + + private _handleSignleObject( + arrayValues: number[], + x: BaseValueObject, + sigma: BaseValueObject | undefined + ): BaseValueObject { + const { isError, errorObject, variants } = checkVariantsErrorIsStringToNumber(x); + + if (isError) { + return errorObject as ErrorValueObject; + } + + const [xObject] = variants as BaseValueObject[]; + + const xValue = +xObject.getValue(); + + const n = arrayValues.length; + + let sum = 0; + let sumSquare = 0; + + for (let i = 0; i < n; i++) { + sum += arrayValues[i]; + sumSquare += arrayValues[i] ** 2; + } + + let sigmaValue = 0; + + if (sigma !== undefined) { + const { isError: _isError, errorObject: _errorObject, variants: _variants } = checkVariantsErrorIsStringToNumber(sigma); + + if (_isError) { + return _errorObject as ErrorValueObject; + } + + const [sigmaObject] = _variants as BaseValueObject[]; + + sigmaValue = +sigmaObject.getValue(); + } else { + const mean = sum / n; + + sigmaValue = Math.sqrt((sumSquare - 2 * mean * sum + n * mean ** 2) / (n - 1)); + } + + if (sigmaValue <= 0) { + return ErrorValueObject.create(ErrorType.NUM); + } + + const z = (sum / n - xValue) / (sigmaValue / Math.sqrt(n)); + + const result = 1 - normalCDF(z, 0, 1); + + if (Number.isNaN(result) || !Number.isFinite(result)) { + return ErrorValueObject.create(ErrorType.NUM); + } + + return NumberValueObject.create(result); + } + + private _getArrayValues(array: BaseValueObject): number[] | ErrorValueObject { + const values: number[] = []; + + const arrayRowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; + const arrayColumnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; + + for (let r = 0; r < arrayRowCount; r++) { + for (let c = 0; c < arrayColumnCount; c++) { + const valueObject = array.isArray() ? (array as ArrayValueObject).get(r, c) as BaseValueObject : array; + + if (valueObject.isError()) { + return valueObject as ErrorValueObject; + } + + if (valueObject.isNull() || valueObject.isBoolean() || valueObject.isString()) { + continue; + } + + const value = valueObject.getValue(); + + if (!isRealNum(value)) { + continue; + } + + values.push(+value); + } + } + + return values; + } +} diff --git a/packages/sheets-formula-ui/src/locale/function-list/compatibility/en-US.ts b/packages/sheets-formula-ui/src/locale/function-list/compatibility/en-US.ts index 36cd6a2509ad..923af1e0be1a 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/compatibility/en-US.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/compatibility/en-US.ts @@ -220,8 +220,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'The value for which you want the distribution.' }, + alpha: { name: 'alpha', detail: 'A parameter of the distribution.' }, + beta: { name: 'beta', detail: 'A parameter of the distribution.' }, + cumulative: { name: 'cumulative', detail: 'A logical value that determines the form of the function. If cumulative is TRUE, GAMMADIST returns the cumulative distribution function; if FALSE, it returns the probability density function.' }, }, }, GAMMAINV: { @@ -234,8 +236,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: 'probability', detail: 'A probability associated with the gamma distribution.' }, + alpha: { name: 'alpha', detail: 'A parameter of the distribution.' }, + beta: { name: 'beta', detail: 'A parameter of the distribution.' }, }, }, HYPGEOMDIST: { @@ -248,8 +251,11 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + sampleS: { name: 'sample_s', detail: 'The number of successes in the sample.' }, + numberSample: { name: 'number_sample', detail: 'The size of the sample.' }, + populationS: { name: 'population_s', detail: 'The number of successes in the population.' }, + numberPop: { name: 'number_pop', detail: 'The population size.' }, + cumulative: { name: 'cumulative', detail: 'A logical value that determines the form of the function. If cumulative is TRUE, HYPGEOMDIST returns the cumulative distribution function; if FALSE, it returns the probability density function.' }, }, }, LOGINV: { @@ -262,8 +268,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: 'probability', detail: 'A probability corresponding to the lognormal distribution.' }, + mean: { name: 'mean', detail: 'The arithmetic mean of the distribution.' }, + standardDev: { name: 'standard_dev', detail: 'The standard deviation of the distribution.' }, }, }, LOGNORMDIST: { @@ -276,8 +283,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'The value for which you want the distribution.' }, + mean: { name: 'mean', detail: 'The arithmetic mean of the distribution.' }, + standardDev: { name: 'standard_dev', detail: 'The standard deviation of the distribution.' }, + cumulative: { name: 'cumulative', detail: 'A logical value that determines the form of the function. If cumulative is TRUE, LOGNORM.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.' }, }, }, MODE: { @@ -290,8 +299,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: 'number1', detail: 'The first number, cell reference, or range for which you want calculate the mode.' }, + number2: { name: 'number2', detail: 'Additional numbers, cell references or ranges for which you want calculate the mode, up to a maximum of 255.' }, }, }, NEGBINOMDIST: { @@ -304,8 +313,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + numberF: { name: 'number_f', detail: 'The number of failures.' }, + numberS: { name: 'number_s', detail: 'The threshold number of successes.' }, + probabilityS: { name: 'probability_s', detail: 'The probability of a success.' }, + cumulative: { name: 'cumulative', detail: 'A logical value that determines the form of the function. If cumulative is TRUE, NEGBINOMDIST returns the cumulative distribution function; if FALSE, it returns the probability density function.' }, }, }, NORMDIST: { @@ -366,8 +377,8 @@ export default { }, }, PERCENTILE: { - description: 'Returns the k-th percentile of values in a range', - abstract: 'Returns the k-th percentile of values in a range', + description: 'Returns the k-th percentile of values in a data set (Includes 0 and 1)', + abstract: 'Returns the k-th percentile of values in a data set (Includes 0 and 1)', links: [ { title: 'Instruction', @@ -375,13 +386,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: 'array', detail: 'The array or range of data that defines relative standing.' }, + k: { name: 'k', detail: 'The percentile value in the range 0 and 1 (Includes 0 and 1).' }, }, }, PERCENTRANK: { - description: 'Returns the percentage rank of a value in a data set', - abstract: 'Returns the percentage rank of a value in a data set', + description: 'Returns the percentage rank of a value in a data set (Includes 0 and 1)', + abstract: 'Returns the percentage rank of a value in a data set (Includes 0 and 1)', links: [ { title: 'Instruction', @@ -389,8 +400,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: 'array', detail: 'The array or range of data that defines relative standing.' }, + x: { name: 'x', detail: 'The value for which you want to know the rank.' }, + significance: { name: 'significance', detail: 'A value that identifies the number of significant digits for the returned percentage value. If omitted, PERCENTRANK.INC uses three digits (0.xxx).' }, }, }, POISSON: { @@ -403,13 +415,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'The value for which you want the distribution.' }, + mean: { name: 'mean', detail: 'The arithmetic mean of the distribution.' }, + cumulative: { name: 'cumulative', detail: 'A logical value that determines the form of the function. If cumulative is TRUE, POISSON returns the cumulative distribution function; if FALSE, it returns the probability density function.' }, }, }, QUARTILE: { - description: 'Returns the quartile of a data set', - abstract: 'Returns the quartile of a data set', + description: 'Returns the quartile of a data set (Includes 0 and 1)', + abstract: 'Returns the quartile of a data set (Includes 0 and 1)', links: [ { title: 'Instruction', @@ -417,8 +430,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: 'array', detail: 'The array or range of data for which you want quartile values.' }, + quart: { name: 'quart', detail: 'The quartile value to return.' }, }, }, RANK: { @@ -465,8 +478,8 @@ export default { }, }, TDIST: { - description: 'Returns the Student\'s t-distribution', - abstract: 'Returns the Student\'s t-distribution', + description: 'Returns the probability for the Student t-distribution', + abstract: 'Returns the probability for the Student t-distribution', links: [ { title: 'Instruction', @@ -474,13 +487,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'The numeric value at which to evaluate the distribution' }, + degFreedom: { name: 'degFreedom', detail: 'An integer indicating the number of degrees of freedom.' }, + tails: { name: 'tails', detail: 'Specifies the number of distribution tails to return. If Tails = 1, TDIST returns the one-tailed distribution. If Tails = 2, TDIST returns the two-tailed distribution.' }, }, }, TINV: { - description: 'Returns the inverse of the Student\'s t-distribution', - abstract: 'Returns the inverse of the Student\'s t-distribution', + description: 'Returns the inverse of the probability for the Student t-distribution (two-tailed)', + abstract: 'Returns the inverse of the probability for the Student t-distribution (two-tailed)', links: [ { title: 'Instruction', @@ -488,8 +502,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: 'probability', detail: 'The probability associated with the Student\'s t-distribution.' }, + degFreedom: { name: 'degFreedom', detail: 'An integer indicating the number of degrees of freedom.' }, }, }, TTEST: { @@ -502,8 +516,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: 'array1', detail: 'The first array or range of data.' }, + array2: { name: 'array2', detail: 'The second array or range of data.' }, + tails: { name: 'tails', detail: 'Specifies the number of distribution tails. If tails = 1, TTEST uses the one-tailed distribution. If tails = 2, TTEST uses the two-tailed distribution.' }, + type: { name: 'type', detail: 'The kind of t-Test to perform.' }, }, }, VAR: { @@ -544,8 +560,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'The value for which you want the distribution.' }, + alpha: { name: 'alpha', detail: 'A parameter of the distribution.' }, + beta: { name: 'beta', detail: 'A parameter of the distribution.' }, + cumulative: { name: 'cumulative', detail: 'A logical value that determines the form of the function. If cumulative is TRUE, WEIBULL returns the cumulative distribution function; if FALSE, it returns the probability density function.' }, }, }, ZTEST: { @@ -558,8 +576,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: 'array', detail: 'The array or range of data against which to test x.' }, + x: { name: 'x', detail: 'The value to test.' }, + sigma: { name: 'sigma', detail: 'The population (known) standard deviation. If omitted, the sample standard deviation is used.' }, }, }, }; diff --git a/packages/sheets-formula-ui/src/locale/function-list/compatibility/ja-JP.ts b/packages/sheets-formula-ui/src/locale/function-list/compatibility/ja-JP.ts index 302fe267b777..51cdeefb54d0 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/compatibility/ja-JP.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/compatibility/ja-JP.ts @@ -220,8 +220,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '関数に代入する値を指定します。' }, + alpha: { name: 'alpha', detail: '分布の最初のパラメータ。' }, + beta: { name: 'beta', detail: '分布の 2 番目のパラメーター。' }, + cumulative: { name: '累積', detail: '計算に使用する関数の形式を論理値で指定します。 関数形式に TRUE を指定すると累積分布関数の値が計算され、FALSE を指定すると確率密度関数の値が計算されます。' }, }, }, GAMMAINV: { @@ -234,8 +236,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '確率', detail: 'ガンマ分布における確率を指定します。' }, + alpha: { name: 'alpha', detail: '分布の最初のパラメータ。' }, + beta: { name: 'beta', detail: '分布の 2 番目のパラメーター。' }, }, }, HYPGEOMDIST: { @@ -248,13 +251,16 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + sampleS: { name: '標本の成功数', detail: '標本内で成功する数を指定します。' }, + numberSample: { name: '標本数', detail: '標本数を指定します。' }, + populationS: { name: '母集団の成功数', detail: '母集団内で成功する数を指定します。' }, + numberPop: { name: '母集団の大きさ', detail: '母集団全体の数を指定します。' }, + cumulative: { name: '累積', detail: '計算に使用する関数の形式を論理値で指定します。 関数形式に TRUE を指定すると累積分布関数の値が計算され、FALSE を指定すると確率密度関数の値が計算されます。' }, }, }, LOGINV: { - description: '対数正規型の累積分布関数の逆関数の値を返します。', - abstract: '対数正規型の累積分布関数の逆関数の値を返します。', + description: '対数正規分布の累積分布関数の逆関数の値を返します。', + abstract: '対数正規分布の累積分布関数の逆関数の値を返します。', links: [ { title: '指導', @@ -262,8 +268,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '確率', detail: '対数正規分布における確率を指定します。' }, + mean: { name: '平均', detail: '対象となる分布の算術平均 (相加平均) を指定します。' }, + standardDev: { name: '標準偏差', detail: '対象となる分布の標準偏差を指定します。' }, }, }, LOGNORMDIST: { @@ -276,8 +283,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '関数に代入する値を指定します。' }, + mean: { name: '平均', detail: '対象となる分布の算術平均 (相加平均) を指定します。' }, + standardDev: { name: '標準偏差', detail: '対象となる分布の標準偏差を指定します。' }, + cumulative: { name: '累積', detail: '計算に使用する関数の形式を論理値で指定します。 関数形式に TRUE を指定すると累積分布関数の値が計算され、FALSE を指定すると確率密度関数の値が計算されます。' }, }, }, MODE: { @@ -290,8 +299,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数値 1', detail: '最頻値を求める 1 つ目の数値、セル参照、またはセル範囲を指定します。' }, + number2: { name: '数値 2', detail: '最頻値を求める追加の数値、セル参照、または範囲 (最大 255)。' }, }, }, NEGBINOMDIST: { @@ -304,8 +313,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + numberF: { name: '失敗数', detail: '試行が失敗する回数を指定します。' }, + numberS: { name: '成功数', detail: '分析のしきい値となる、試行が成功する回数を指定します。' }, + probabilityS: { name: '成功率', detail: '試行が成功する確率を指定します。' }, + cumulative: { name: '累積', detail: '計算に使用する関数の形式を論理値で指定します。 関数形式に TRUE を指定すると累積分布関数の値が計算され、FALSE を指定すると確率密度関数の値が計算されます。' }, }, }, NORMDIST: { @@ -366,8 +377,8 @@ export default { }, }, PERCENTILE: { - description: '特定の範囲に含まれるデータの第 k 百分位数に当たる値を返します。', - abstract: '特定の範囲に含まれるデータの第 k 百分位数に当たる値を返します。', + description: '配列内での第 k 百分位数に当たる値を返します (0と1が含まれています)。', + abstract: '配列内での第 k 百分位数に当たる値を返します (0と1が含まれています)。', links: [ { title: '指導', @@ -375,13 +386,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '配列', detail: '相対的な位置を決定するデータの配列またはセル範囲を指定します。' }, + k: { name: 'k', detail: '0 から 1 (0と1が含まれています)までのパーセント値。' }, }, }, PERCENTRANK: { - description: '配列内での値の順位を百分率で表した値を返します。', - abstract: '配列内での値の順位を百分率で表した値を返します。', + description: '配列内での値の順位を百分率で表した値を返します (0と1が含まれています)。', + abstract: '配列内での値の順位を百分率で表した値を返します (0と1が含まれています)。', links: [ { title: '指導', @@ -389,8 +400,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '配列', detail: '相対的な位置を決定するデータの配列またはセル範囲を指定します。' }, + x: { name: 'x', detail: 'ランクを調べる値を指定します。' }, + significance: { name: '有効桁数', detail: '計算結果として返される百分率の有効桁数を指定します。 有効桁数を省略すると、小数点以下第 3 位 (0.xxx) まで計算されます。' }, }, }, POISSON: { @@ -403,13 +415,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '関数に代入する値を指定します。' }, + mean: { name: '平均', detail: '対象となる分布の算術平均 (相加平均) を指定します。' }, + cumulative: { name: '累積', detail: '計算に使用する関数の形式を論理値で指定します。 関数形式に TRUE を指定すると累積分布関数の値が計算され、FALSE を指定すると確率密度関数の値が計算されます。' }, }, }, QUARTILE: { - description: '配列に含まれるデータから四分位数を抽出します。', - abstract: '配列に含まれるデータから四分位数を抽出します。', + description: 'データセットの四分位数を返します (0と1が含まれています)。', + abstract: 'データセットの四分位数を返します (0と1が含まれています)。', links: [ { title: '指導', @@ -417,8 +430,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '配列', detail: '四分位値を必要とする配列またはデータ範囲。' }, + quart: { name: '四分位値', detail: '返す四分位値。' }, }, }, RANK: { @@ -465,8 +478,8 @@ export default { }, }, TDIST: { - description: 'スチューデントの t 分布の値を返します。', - abstract: 'スチューデントの t 分布の値を返します。', + description: 'スチューデントの t 確率分布を返します。', + abstract: 'スチューデントの t 確率分布を返します。', links: [ { title: '指導', @@ -474,13 +487,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '分布の数値を計算する必要があります。' }, + degFreedom: { name: '自由度', detail: '自由度の数を表す整数。' }, + tails: { name: '尾部の特性', detail: '片側分布を計算するか、両側分布を計算するかを、数値で指定します。 尾部に 1 を指定すると片側分布の値が計算されます。 尾部に 2 を指定すると両側分布の値が計算されます。' }, }, }, TINV: { - description: 'スチューデントの t 分布の逆関数値を返します。', - abstract: 'スチューデントの t 分布の逆関数値を返します。', + description: 'スチューデントの t 確率分布 (両側) の逆関数値を返します。', + abstract: 'スチューデントの t 確率分布 (両側) の逆関数値を返します。', links: [ { title: '指導', @@ -488,8 +502,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '確率', detail: 'スチューデントの t 分布に従う確率を指定します。' }, + degFreedom: { name: '自由度', detail: '自由度の数を表す整数。' }, }, }, TTEST: { @@ -502,8 +516,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: '配列1', detail: '比較対象となる一方のデータを含む配列またはセル範囲を指定します。' }, + array2: { name: '配列2', detail: '比較対象となるもう一方のデータを含む配列またはセル範囲を指定します。' }, + tails: { name: '尾部の特性', detail: '片側分布を計算するか、両側分布を計算するかを、数値で指定します。 尾部に 1 を指定すると片側分布の値が計算されます。 尾部に 2 を指定すると両側分布の値が計算されます。' }, + type: { name: '検定の種類', detail: '実行する t 検定の種類を数値で指定します。' }, }, }, VAR: { @@ -544,8 +560,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '関数に代入する値を指定します。' }, + alpha: { name: 'alpha', detail: '分布の最初のパラメータ。' }, + beta: { name: 'beta', detail: '分布の 2 番目のパラメーター。' }, + cumulative: { name: '累積', detail: '計算に使用する関数の形式を論理値で指定します。 関数形式に TRUE を指定すると累積分布関数の値が計算され、FALSE を指定すると確率密度関数の値が計算されます。' }, }, }, ZTEST: { @@ -558,8 +576,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '配列', detail: 'x の検定対象となるデータを含む数値配列またはセル範囲を指定します。' }, + x: { name: 'x', detail: '検定する値を指定します。' }, + sigma: { name: '標準偏差', detail: '母集団全体に基づく標準偏差を指定します。 省略すると、標本に基づく標準偏差が使用されます。' }, }, }, }; diff --git a/packages/sheets-formula-ui/src/locale/function-list/compatibility/vi-VN.ts b/packages/sheets-formula-ui/src/locale/function-list/compatibility/vi-VN.ts index 5e87cc7033a1..e495dce1a5e9 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/compatibility/vi-VN.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/compatibility/vi-VN.ts @@ -210,7 +210,6 @@ export default { array2: { name: 'mảng 2', detail: 'Mảng thứ hai của phạm vi dữ liệu.' }, }, }, - GAMMADIST: { description: 'Trả về phân phối γ', abstract: 'Trả về phân phối γ', @@ -221,8 +220,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'thứ nhất' }, - number2: { name: 'number2', detail: 'thứ hai' }, + x: { name: 'x', detail: 'Giá trị mà bạn muốn có phân bố của nó.' }, + alpha: { name: 'alpha', detail: 'Tham số đầu tiên của phân phối.' }, + beta: { name: 'beta', detail: 'Tham số thứ hai của phân phối.' }, + cumulative: { name: 'tích lũy', detail: 'Một giá trị lô-gic quyết định dạng thức của hàm. Nếu tích lũy là TRUE, hàm GAMMADIST trả về hàm phân bố tích lũy; nếu FALSE, nó trả về hàm mật độ xác suất.' }, }, }, GAMMAINV: { @@ -235,13 +236,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'thứ nhất' }, - number2: { name: 'number2', detail: 'thứ hai' }, + probability: { name: 'xác suất', detail: 'Xác suất gắn với phân bố gamma.' }, + alpha: { name: 'alpha', detail: 'Tham số đầu tiên của phân phối.' }, + beta: { name: 'beta', detail: 'Tham số thứ hai của phân phối.' }, }, }, HYPGEOMDIST: { - description: 'Trả về phân phối siêu bội', - abstract: 'Trả về phân phối siêu bội', + description: 'Trả về phân bố siêu bội.', + abstract: 'Trả về phân bố siêu bội.', links: [ { title: 'Giảng dạy', @@ -249,13 +251,16 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'thứ nhất' }, - number2: { name: 'number2', detail: 'thứ hai' }, + sampleS: { name: 'Số lần thành công mẫu', detail: 'Số lần thành công trong mẫu.' }, + numberSample: { name: 'Kích thước mẫu', detail: 'Kích thước mẫu.' }, + populationS: { name: 'Tổng số thành công', detail: 'Số lượng thành công trong dân số.' }, + numberPop: { name: 'Kích thước tổng thể', detail: 'Kích thước tổng thể.' }, + cumulative: { name: 'tích lũy', detail: 'Một giá trị lô-gic quyết định dạng thức của hàm. Nếu tích lũy là TRUE, hàm HYPGEOMDIST trả về hàm phân bố tích lũy; nếu FALSE, nó trả về hàm mật độ xác suất.' }, }, }, LOGINV: { - description: 'Trả về hàm nghịch đảo của hàm phân phối tích lũy lô-ga', - abstract: 'Trả về hàm nghịch đảo của hàm phân phối tích lũy lô-ga', + description: 'Trả về nghịch đảo của hàm phân bố lô-ga-rit chuẩn lũy tích của', + abstract: 'Trả về nghịch đảo của hàm phân bố lô-ga-rit chuẩn lũy tích của', links: [ { title: 'Giảng dạy', @@ -263,13 +268,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'thứ nhất' }, - number2: { name: 'number2', detail: 'thứ hai' }, + probability: { name: 'xác suất', detail: 'Một xác suất tương ứng với phân bố lô-ga-rit chuẩn.' }, + mean: { name: 'trung độ số', detail: 'Trung độ số học của phân phối.' }, + standardDev: { name: 'Độ lệch chuẩn', detail: 'Độ lệch chuẩn của phân phối.' }, }, }, LOGNORMDIST: { - description: 'Trả về hàm phân phối tích lũy lô-ga', - abstract: 'Trả về hàm phân phối tích lũy lô-ga', + description: 'Trả về phân bố chuẩn lô-ga-rít của', + abstract: 'Trả về phân bố chuẩn lô-ga-rít của', links: [ { title: 'Giảng dạy', @@ -277,13 +283,15 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'thứ nhất' }, - number2: { name: 'number2', detail: 'thứ hai' }, + x: { name: 'x', detail: 'Giá trị mà bạn muốn có phân bố của nó.' }, + mean: { name: 'trung độ số', detail: 'Trung độ số học của phân phối.' }, + standardDev: { name: 'Độ lệch chuẩn', detail: 'Độ lệch chuẩn của phân phối.' }, + cumulative: { name: 'tích lũy', detail: 'Một giá trị lô-gic quyết định dạng thức của hàm. Nếu lũy tích là ĐÚNG thì LOGNORMDIST trả về hàm phân bố lũy tích; nếu SAI, nó trả về hàm mật độ xác suất.' }, }, }, MODE: { - description: 'Trả về giá trị xuất hiện nhiều nhất trong tập dữ liệu', - abstract: 'Trả về giá trị xuất hiện nhiều nhất trong tập dữ liệu', + description: 'Trả về giá trị xuất hiện nhiều nhất trong tập dữ liệu.', + abstract: 'Trả về giá trị xuất hiện nhiều nhất trong tập dữ liệu.', links: [ { title: 'Giảng dạy', @@ -291,13 +299,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'thứ nhất' }, - number2: { name: 'number2', detail: 'thứ hai' }, + number1: { name: 'số 1', detail: 'Số đầu tiên, tham chiếu ô hoặc phạm vi ô mà chế độ sẽ được tính toán.' }, + number2: { name: 'số 2', detail: 'Tối đa 255 số bổ sung, tham chiếu ô hoặc phạm vi ô để tính chế độ.' }, }, }, NEGBINOMDIST: { - description: 'Trả về phân phối nhị thức âm', - abstract: 'Trả về phân phối nhị thức âm', + description: 'Trả về phân bố nhị thức âm', + abstract: 'Trả về phân bố nhị thức âm', links: [ { title: 'Giảng dạy', @@ -305,8 +313,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'thứ nhất' }, - number2: { name: 'number2', detail: 'thứ hai' }, + numberF: { name: 'số lần thất bại.', detail: 'Số lần thất bại.' }, + numberS: { name: 'số lần thành công', detail: 'Số ngưỡng thành công.' }, + probabilityS: { name: 'xác suất thành công', detail: 'Xác suất thành công của mỗi phép thử.' }, + cumulative: { name: 'tích lũy', detail: 'Một giá trị lô-gic quyết định dạng thức của hàm. Nếu tích lũy là TRUE, hàm NEGBINOMDIST trả về hàm phân bố tích lũy; nếu FALSE, nó trả về hàm mật độ xác suất.' }, }, }, NORMDIST: { @@ -368,8 +378,8 @@ export default { }, }, PERCENTILE: { - description: 'Trả về giá trị phân vị thứ k trong một phạm vi dữ liệu', - abstract: 'Trả về giá trị phân vị thứ k trong một phạm vi dữ liệu', + description: 'Trả về giá trị phân vị thứ k trong tập dữ liệu (bao gồm 0 và 1)', + abstract: 'Trả về giá trị phân vị thứ k trong tập dữ liệu (bao gồm 0 và 1)', links: [ { title: 'Hướng dẫn', @@ -377,13 +387,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'tham số thứ nhất' }, - number2: { name: 'number2', detail: 'tham số thứ hai' }, + array: { name: 'mảng', detail: 'Mảng hoặc phạm vi dữ liệu xác định vị trí tương đối.' }, + k: { name: 'k', detail: 'Giá trị phần trăm từ 0 đến 1 (bao gồm 0 và 1).' }, }, }, PERCENTRANK: { - description: 'Trả về vị trí phần trăm của giá trị trong tập dữ liệu', - abstract: 'Trả về vị trí phần trăm của giá trị trong tập dữ liệu', + description: 'Trả về thứ hạng phần trăm của các giá trị trong tập dữ liệu (bao gồm 0 và 1)', + abstract: 'Trả về thứ hạng phần trăm của các giá trị trong tập dữ liệu (bao gồm 0 và 1)', links: [ { title: 'Hướng dẫn', @@ -391,13 +401,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'tham số thứ nhất' }, - number2: { name: 'number2', detail: 'tham số thứ hai' }, + array: { name: 'mảng', detail: 'Mảng hoặc phạm vi dữ liệu xác định vị trí tương đối.' }, + x: { name: 'x', detail: 'Giá trị mà bạn muốn biết thứ hạng của nó.' }, + significance: { name: 'chữ số có nghĩa', detail: 'Giá trị xác định số chữ số có nghĩa của giá trị phần trăm trả về. Nếu bỏ qua, hàm PERCENTRANK dùng ba chữ số (0.xxx).' }, }, }, POISSON: { - description: 'Trả về phân phối Poisson', - abstract: 'Trả về phân phối Poisson', + description: 'Trả về phân bố Poisson.', + abstract: 'Trả về phân bố Poisson.', links: [ { title: 'Hướng dẫn', @@ -405,13 +416,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'tham số thứ nhất' }, - number2: { name: 'number2', detail: 'tham số thứ hai' }, + x: { name: 'x', detail: 'Giá trị mà bạn muốn có phân bố của nó.' }, + mean: { name: 'trung độ số', detail: 'Trung độ số học của phân phối.' }, + cumulative: { name: 'tích lũy', detail: 'Một giá trị lô-gic quyết định dạng thức của hàm. Nếu lũy tích là ĐÚNG thì POISSON trả về hàm phân bố lũy tích; nếu SAI, nó trả về hàm mật độ xác suất.' }, }, }, QUARTILE: { - description: 'Trả về điểm phân vị của một tập dữ liệu', - abstract: 'Trả về điểm phân vị của một tập dữ liệu', + description: 'Trả về các phần tư của tập dữ liệu (bao gồm 0 và 1)', + abstract: 'Trả về các phần tư của tập dữ liệu (bao gồm 0 và 1)', links: [ { title: 'Hướng dẫn', @@ -419,8 +431,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'tham số thứ nhất' }, - number2: { name: 'number2', detail: 'tham số thứ hai' }, + array: { name: 'mảng', detail: 'Một mảng hoặc phạm vi dữ liệu yêu cầu giá trị tứ phân vị.' }, + quart: { name: 'giá trị tứ phân', detail: 'Giá trị tứ phân vị cần trả về.' }, }, }, RANK: { @@ -467,8 +479,8 @@ export default { }, }, TDIST: { - description: 'Trả về phân phối t-Student', - abstract: 'Trả về phân phối t-Student', + description: 'Trả về phân phối xác suất t-Student của Học sinh', + abstract: 'Trả về phân phối xác suất t-Student của Học sinh', links: [ { title: 'Hướng dẫn', @@ -476,13 +488,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'tham số thứ nhất' }, - number2: { name: 'number2', detail: 'tham số thứ hai' }, + x: { name: 'x', detail: 'Cần tính giá trị số của phân bố.' }, + degFreedom: { name: 'bậc tự do', detail: 'Một số nguyên biểu thị số bậc tự do.' }, + tails: { name: 'đặc điểm đuôi', detail: 'Xác định số phần dư của phân bố được trả về. Nếu Tails = 1, hàm TDIST sẽ trả về phân bố một phía. Nếu Tails = 2, hàm TDIST sẽ trả về phân bố hai phía.' }, }, }, TINV: { - description: 'Trả về hàm nghịch đảo phân phối t-Student', - abstract: 'Trả về hàm nghịch đảo phân phối t-Student', + description: 'Trả về hàm nghịch đảo của phân bố xác suất t-Student của Học sinh (hai đuôi)', + abstract: 'Trả về hàm nghịch đảo của phân bố xác suất t-Student của Học sinh (hai đuôi)', links: [ { title: 'Hướng dẫn', @@ -490,13 +503,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'tham số thứ nhất' }, - number2: { name: 'number2', detail: 'tham số thứ hai' }, + probability: { name: 'xác suất', detail: 'Xác suất liên quan đến phân phối t-Student của Sinh viên.' }, + degFreedom: { name: 'bậc tự do', detail: 'Một số nguyên biểu thị số bậc tự do.' }, }, }, TTEST: { - description: 'Trả về xác suất liên quan đến kiểm định t-Student', - abstract: 'Trả về xác suất liên quan đến kiểm định t-Student', + description: 'Trả về xác suất kết hợp với Phép thử t-Student.', + abstract: 'Trả về xác suất kết hợp với Phép thử t-Student.', links: [ { title: 'Hướng dẫn', @@ -504,8 +517,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'tham số thứ nhất' }, - number2: { name: 'number2', detail: 'tham số thứ hai' }, + array1: { name: 'mảng 1', detail: 'Mảng thứ nhất của phạm vi dữ liệu.' }, + array2: { name: 'mảng 2', detail: 'Mảng thứ hai của phạm vi dữ liệu.' }, + tails: { name: 'đặc điểm đuôi', detail: 'Xác định số đuôi của phân phối. Nếu đuôi = 1, TTEST sử dụng phân phối một phía. Nếu đuôi = 2, TTEST sử dụng phân phối hai phía.' }, + type: { name: 'loại Phép thử', detail: 'Loại Phép thử t cần thực hiện.' }, }, }, VAR: { @@ -537,8 +552,8 @@ export default { }, }, WEIBULL: { - description: 'Trả về phân phối Weibull', - abstract: 'Trả về phân phối Weibull', + description: 'Trả về phân bố Weibull.', + abstract: 'Trả về phân bố Weibull.', links: [ { title: 'Hướng dẫn', @@ -546,13 +561,15 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'tham số thứ nhất' }, - number2: { name: 'number2', detail: 'tham số thứ hai' }, + x: { name: 'x', detail: 'Giá trị mà bạn muốn có phân bố của nó.' }, + alpha: { name: 'alpha', detail: 'Tham số đầu tiên của phân phối.' }, + beta: { name: 'beta', detail: 'Tham số thứ hai của phân phối.' }, + cumulative: { name: 'tích lũy', detail: 'Một giá trị lô-gic quyết định dạng thức của hàm. Nếu tích lũy là TRUE, hàm WEIBULL trả về hàm phân bố tích lũy; nếu FALSE, nó trả về hàm mật độ xác suất.' }, }, }, ZTEST: { - description: 'Trả về giá trị xác suất đuôi đơn của kiểm định z', - abstract: 'Trả về giá trị xác suất đuôi đơn của kiểm định z', + description: 'Trả về giá trị xác suất một phía của kiểm tra z.', + abstract: 'Trả về giá trị xác suất một phía của kiểm tra z.', links: [ { title: 'Hướng dẫn', @@ -560,8 +577,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'tham số thứ nhất' }, - number2: { name: 'number2', detail: 'tham số thứ hai' }, + array: { name: 'mảng', detail: 'Mảng hay khoảng dữ liệu để kiểm tra x.' }, + x: { name: 'x', detail: 'Giá trị cần kiểm tra.' }, + sigma: { name: 'Độ lệch chuẩn', detail: 'Độ lệch chuẩn tổng thể (đã biết). Nếu bỏ qua, độ lệch chuẩn mẫu sẽ được dùng.' }, }, }, diff --git a/packages/sheets-formula-ui/src/locale/function-list/compatibility/zh-CN.ts b/packages/sheets-formula-ui/src/locale/function-list/compatibility/zh-CN.ts index a3269bdf4b83..35788c44cb32 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/compatibility/zh-CN.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/compatibility/zh-CN.ts @@ -220,8 +220,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要计算其分布的数值。' }, + alpha: { name: 'alpha', detail: '分布的第一个参数。' }, + beta: { name: 'beta', detail: '分布的第二个参数。' }, + cumulative: { name: '累积', detail: '决定函数形式的逻辑值。如果为TRUE,则 GAMMADIST 返回累积分布函数;如果为 FALSE,则返回概率密度函数。' }, }, }, GAMMAINV: { @@ -234,8 +236,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '概率', detail: '与伽玛分布相关的概率。' }, + alpha: { name: 'alpha', detail: '分布的第一个参数。' }, + beta: { name: 'beta', detail: '分布的第二个参数。' }, }, }, HYPGEOMDIST: { @@ -248,13 +251,16 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + sampleS: { name: '样本成功次数', detail: '样本中成功的次数。' }, + numberSample: { name: '样本大小', detail: '样本大小。' }, + populationS: { name: '总体成功次数', detail: '总体中成功的次数。' }, + numberPop: { name: '总体大小', detail: '总体大小。' }, + cumulative: { name: '累积', detail: '决定函数形式的逻辑值。如果为TRUE,则 HYPGEOMDIST 返回累积分布函数;如果为 FALSE,则返回概率密度函数。' }, }, }, LOGINV: { - description: '返回对数累积分布函数的反函数', - abstract: '返回对数累积分布函数的反函数', + description: '返回对数正态累积分布的反函数', + abstract: '返回对数正态累积分布的反函数', links: [ { title: '教学', @@ -262,13 +268,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '概率', detail: '对应于对数正态分布的概率。' }, + mean: { name: '平均值', detail: '分布的算术平均值。' }, + standardDev: { name: '标准偏差', detail: '分布的标准偏差。' }, }, }, LOGNORMDIST: { - description: '返回对数累积分布函数', - abstract: '返回对数累积分布函数', + description: '返回对数正态累积分布', + abstract: '返回对数正态累积分布', links: [ { title: '教学', @@ -276,8 +283,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要计算其分布的数值。' }, + mean: { name: '平均值', detail: '分布的算术平均值。' }, + standardDev: { name: '标准偏差', detail: '分布的标准偏差。' }, + cumulative: { name: '累积', detail: '决定函数形式的逻辑值。 如果为 TRUE,则 LOGNORMDIST 返回累积分布函数;如果为 FALSE,则返回概率密度函数。' }, }, }, MODE: { @@ -290,8 +299,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数值 1', detail: '要计算众数的第一个数字、单元格引用或单元格区域。' }, + number2: { name: '数值 2', detail: '要计算众数的其他数字、单元格引用或单元格区域,最多可包含 255 个。' }, }, }, NEGBINOMDIST: { @@ -304,8 +313,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + numberF: { name: '失败次数', detail: '失败的次数。' }, + numberS: { name: '成功次数', detail: '成功次数的阈值。' }, + probabilityS: { name: '成功概率', detail: '成功的概率。' }, + cumulative: { name: '累积', detail: '决定函数形式的逻辑值。 如果为 TRUE,则 NEGBINOMDIST 返回累积分布函数;如果为 FALSE,则返回概率密度函数。' }, }, }, NORMDIST: { @@ -366,8 +377,8 @@ export default { }, }, PERCENTILE: { - description: '返回区域中数值的第 k 个百分点的值', - abstract: '返回区域中数值的第 k 个百分点的值', + description: '返回数据集中第 k 个百分点的值 (包含 0 和 1)', + abstract: '返回数据集中第 k 个百分点的值 (包含 0 和 1)', links: [ { title: '教学', @@ -375,13 +386,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '数组', detail: '定义相对位置的数组或数据区域。' }, + k: { name: 'k', detail: '0 到 1 之间的百分点值 (包含 0 和 1)。' }, }, }, PERCENTRANK: { - description: '返回数据集中值的百分比排位', - abstract: '返回数据集中值的百分比排位', + description: '返回数据集中值的百分比排位 (包含 0 和 1)', + abstract: '返回数据集中值的百分比排位 (包含 0 和 1)', links: [ { title: '教学', @@ -389,8 +400,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '数组', detail: '定义相对位置的数组或数据区域。' }, + x: { name: 'x', detail: '需要得到其排位的值。' }, + significance: { name: '有效位数', detail: '用于标识返回的百分比值的有效位数的值。 如果省略,则 PERCENTRANK 使用 3 位小数 (0.xxx)。' }, }, }, POISSON: { @@ -403,13 +415,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要计算其分布的数值。' }, + mean: { name: '平均值', detail: '分布的算术平均值。' }, + cumulative: { name: '累积', detail: '决定函数形式的逻辑值。 如果为 TRUE,则 POISSON 返回累积分布函数;如果为 FALSE,则返回概率密度函数。' }, }, }, QUARTILE: { - description: '返回一组数据的四分位点', - abstract: '返回一组数据的四分位点', + description: '返回数据集的四分位数 (包含 0 和 1)', + abstract: '返回数据集的四分位数 (包含 0 和 1)', links: [ { title: '教学', @@ -417,8 +430,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '数组', detail: '要求得四分位数值的数组或数据区域。' }, + quart: { name: '四分位值', detail: '要返回的四分位数值。' }, }, }, RANK: { @@ -465,8 +478,8 @@ export default { }, }, TDIST: { - description: '返回学生 t-分布', - abstract: '返回学生 t-分布', + description: '返回学生的 t 概率分布', + abstract: '返回学生的 t 概率分布', links: [ { title: '教学', @@ -474,13 +487,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要计算分布的数值。' }, + degFreedom: { name: '自由度', detail: '一个表示自由度数的整数。' }, + tails: { name: '尾部特性', detail: '指定返回的分布函数是单尾分布还是双尾分布。 如果 Tails = 1,则 TDIST 返回单尾分布。 如果Tails = 2,则 TDIST 返回双尾分布。' }, }, }, TINV: { - description: '返回学生 t-分布的反函数', - abstract: '返回学生 t-分布的反函数', + description: '返回学生的 t 概率分布的反函数 (双尾)', + abstract: '返回学生的 t 概率分布的反函数 (双尾)', links: [ { title: '教学', @@ -488,8 +502,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '概率', detail: '与学生的 t 分布相关的概率。' }, + degFreedom: { name: '自由度', detail: '一个表示自由度数的整数。' }, }, }, TTEST: { @@ -502,8 +516,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: '数组1', detail: '第一个数据数组或数据范围。' }, + array2: { name: '数组2', detail: '第二个数据数组或数据范围。' }, + tails: { name: '尾部特性', detail: '指定分布尾数。 如果 tails = 1,则 TTEST 使用单尾分布。 如果 tails = 2,则 TTEST 使用双尾分布。' }, + type: { name: '检验类型', detail: '要执行的 t 检验的类型。' }, }, }, VAR: { @@ -544,8 +560,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要计算其分布的数值。' }, + alpha: { name: 'alpha', detail: '分布的第一个参数。' }, + beta: { name: 'beta', detail: '分布的第二个参数。' }, + cumulative: { name: '累积', detail: '决定函数形式的逻辑值。如果为TRUE,则 WEIBULL 返回累积分布函数;如果为 FALSE,则返回概率密度函数。' }, }, }, ZTEST: { @@ -558,8 +576,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '数组', detail: '用来检验 x 的数组或数据区域。' }, + x: { name: 'x', detail: '要测试的值。' }, + sigma: { name: '标准偏差', detail: '总体(已知)标准偏差。 如果省略,则使用样本标准偏差。' }, }, }, }; diff --git a/packages/sheets-formula-ui/src/locale/function-list/compatibility/zh-TW.ts b/packages/sheets-formula-ui/src/locale/function-list/compatibility/zh-TW.ts index e7ae26123694..7e9ed04ace45 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/compatibility/zh-TW.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/compatibility/zh-TW.ts @@ -42,7 +42,7 @@ export default { }, ], functionParameter: { - probability: { name: '機率', detail: '這是 beta 分佈的相關機率。' }, + probability: { name: '機率', detail: 'beta 分佈的相關機率。' }, alpha: { name: 'alpha', detail: '分佈的第一個參數。' }, beta: { name: 'beta', detail: '分佈的第二個參數。' }, A: { name: '下限', detail: '函數的下限,預設值為 0。' }, @@ -75,8 +75,8 @@ export default { }, ], functionParameter: { - x: { name: '值', detail: '這是用來評估分佈的值。' }, - degFreedom: { name: '自由度', detail: '這是自由度。' }, + x: { name: '值', detail: '用來評估分佈的值。' }, + degFreedom: { name: '自由度', detail: '自由度。' }, }, }, CHIINV: { @@ -89,8 +89,8 @@ export default { }, ], functionParameter: { - probability: { name: '機率', detail: '這是與 χ2 分佈相關聯的機率。' }, - degFreedom: { name: '自由度', detail: '這是自由度。' }, + probability: { name: '機率', detail: '與 χ2 分佈相關聯的機率。' }, + degFreedom: { name: '自由度', detail: '自由度。' }, }, }, CHITEST: { @@ -103,8 +103,8 @@ export default { }, ], functionParameter: { - actualRange: { name: '觀察範圍', detail: '這是觀察值範圍,用來檢定預期值。' }, - expectedRange: { name: '預期範圍', detail: '這是資料範圍,其內容為各欄總和乘各列總和後的值,再除以全部值總和的比率。' }, + actualRange: { name: '觀察範圍', detail: '觀察值範圍,用來檢定預期值。' }, + expectedRange: { name: '預期範圍', detail: '資料範圍,其內容為各欄總和乘各列總和後的值,再除以全部值總和的比率。' }, }, }, CONFIDENCE: { @@ -119,7 +119,7 @@ export default { functionParameter: { alpha: { name: 'alpha', detail: '用於計算置信水準的顯著水準。置信水準等於 100*(1 - alpha)%,換句話說,alpha 0.05 表示信賴水準為 95%。' }, standardDev: { name: '總體標準差', detail: '假設資料範圍的總體標準差已知。' }, - size: { name: '樣本大小', detail: '這是樣本大小。' }, + size: { name: '樣本大小', detail: '樣本大小。' }, }, }, COVAR: { @@ -148,7 +148,7 @@ export default { functionParameter: { trials: { name: '實驗次數', detail: '伯努利實驗的次數。' }, probabilityS: { name: '成功機率', detail: '每一次實驗的成功機率。' }, - alpha: { name: '目標機率', detail: '這是臨界值。' }, + alpha: { name: '目標機率', detail: '臨界值。' }, }, }, EXPONDIST: { @@ -161,14 +161,14 @@ export default { }, ], functionParameter: { - x: { name: '值', detail: '這是用來評估分佈的值。' }, - lambda: { name: 'lambda', detail: '這是參數值。' }, - cumulative: { name: '累積', detail: ' 這是決定函數形式的邏輯值。 如果為 TRUE,EXPONDIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, + x: { name: '值', detail: '用來評估分佈的值。' }, + lambda: { name: 'lambda', detail: '參數值。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。 如果為 TRUE,EXPONDIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, }, }, FDIST: { - description: '返回 F 機率分佈(右尾)', - abstract: '返回 F 機率分佈(右尾)', + description: '傳回 F 機率分佈(右尾)', + abstract: '傳回 F 機率分佈(右尾)', links: [ { title: '教導', @@ -176,9 +176,9 @@ export default { }, ], functionParameter: { - x: { name: '值', detail: '這是用於評估函數的值。' }, - degFreedom1: { name: '分子自由度', detail: '這是分子的自由度。' }, - degFreedom2: { name: '分母自由度', detail: '這是分母的自由度。' }, + x: { name: '值', detail: '用於評估函數的值。' }, + degFreedom1: { name: '分子自由度', detail: '分子的自由度。' }, + degFreedom2: { name: '分母自由度', detail: '分母的自由度。' }, }, }, FINV: { @@ -192,8 +192,8 @@ export default { ], functionParameter: { probability: { name: '機率', detail: 'F 累積分佈相關的機率' }, - degFreedom1: { name: '分子自由度', detail: '這是分子的自由度。' }, - degFreedom2: { name: '分母自由度', detail: '這是分母的自由度。' }, + degFreedom1: { name: '分子自由度', detail: '分子的自由度。' }, + degFreedom2: { name: '分母自由度', detail: '分母的自由度。' }, }, }, FTEST: { @@ -206,13 +206,13 @@ export default { }, ], functionParameter: { - array1: { name: '陣列1', detail: '這是第一個陣列或資料範圍。' }, - array2: { name: '陣列2', detail: '這是第一個陣列或資料範圍。' }, + array1: { name: '陣列1', detail: '第一個陣列或資料範圍。' }, + array2: { name: '陣列2', detail: '第二個陣列或資料範圍。' }, }, }, GAMMADIST: { - description: '返回 γ 分佈', - abstract: '返回 γ 分佈', + description: '傳回 γ 分佈', + abstract: '傳回 γ 分佈', links: [ { title: '教導', @@ -220,8 +220,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '要找出分佈的數值。' }, + alpha: { name: 'alpha', detail: '分佈的第一個參數。' }, + beta: { name: 'beta', detail: '分佈的第二個參數。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。如果為 TRUE,則 GAMMADIST 傳回累積分佈函數;如果為 FALSE,則傳回機率密度函數。' }, }, }, GAMMAINV: { @@ -234,8 +236,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '機率', detail: '與伽瑪分佈的相關機率。' }, + alpha: { name: 'alpha', detail: '分佈的第一個參數。' }, + beta: { name: 'beta', detail: '分佈的第二個參數。' }, }, }, HYPGEOMDIST: { @@ -248,13 +251,16 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + sampleS: { name: '樣本成功次數', detail: '樣本中成功的次數。' }, + numberSample: { name: '樣本大小', detail: '樣本大小。' }, + populationS: { name: '總體成功次數', detail: '總體中成功的次數。' }, + numberPop: { name: '總體大小', detail: '總體大小。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。如果為 TRUE,則 HYPGEOMDIST 傳回累積分佈函數;如果為 FALSE,則傳回機率密度函數。' }, }, }, LOGINV: { - description: '傳回對數累積分佈函數的反函數', - abstract: '傳回對數累積分佈函數的反函數', + description: '傳回對數常態累積分佈的反函數', + abstract: '傳回對數常態累積分佈的反函數', links: [ { title: '教導', @@ -262,13 +268,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '機率', detail: '對應到對數常態分佈的機率。' }, + mean: { name: '平均值', detail: '分佈的算術平均值。' }, + standardDev: { name: '標準差', detail: '分佈的標準差。' }, }, }, LOGNORMDIST: { - description: '傳回對數累積分佈函數', - abstract: '傳回對數累積分佈函數', + description: '傳回對數常態累積分佈', + abstract: '傳回對數常態累積分佈', links: [ { title: '教導', @@ -276,8 +283,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '要找出分佈的數值。' }, + mean: { name: '平均值', detail: '分佈的算術平均值。' }, + standardDev: { name: '標準差', detail: '分佈的標準差。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。 如果為 TRUE,LOGNORMDIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, }, }, MODE: { @@ -290,8 +299,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '數值 1', detail: '要計算眾數的第一個數字、儲存格參考或儲存格區域。 ' }, + number2: { name: '數值 2', detail: '要計算眾數的其他數字、儲存格參考或儲存格區域,最多可包含 255 個。 ' }, }, }, NEGBINOMDIST: { @@ -304,8 +313,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + numberF: { name: '失敗次數', detail: '失敗的次數。' }, + numberS: { name: '成功次數', detail: '成功的閥值數目。' }, + probabilityS: { name: '成功機率', detail: '成功的機率。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。 如果為 TRUE,NEGBINOMDIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, }, }, NORMDIST: { @@ -318,10 +329,10 @@ export default { }, ], functionParameter: { - x: { name: 'x', detail: '這是您要找出分佈的數值。' }, - mean: { name: '平均值', detail: '這是分佈的算術平均值。' }, - standardDev: { name: '標準差', detail: '這是分佈的標準差。' }, - cumulative: { name: '累積', detail: ' 這是決定函數形式的邏輯值。 如果為 TRUE,NORMDIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, + x: { name: 'x', detail: '要找出分佈的數值。' }, + mean: { name: '平均值', detail: '分佈的算術平均值。' }, + standardDev: { name: '標準差', detail: '分佈的標準差。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。 如果為 TRUE,NORMDIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, }, }, NORMINV: { @@ -333,9 +344,9 @@ export default { }, ], functionParameter: { - probability: { name: '機率', detail: '這是對應到常態分佈的機率。' }, - mean: { name: '平均值', detail: '這是分佈的算術平均值。' }, - standardDev: { name: '標準差', detail: '這是分佈的標準差。' }, + probability: { name: '機率', detail: '對應到常態分佈的機率。' }, + mean: { name: '平均值', detail: '分佈的算術平均值。' }, + standardDev: { name: '標準差', detail: '分佈的標準差。' }, }, }, NORMSDIST: { @@ -348,7 +359,7 @@ export default { }, ], functionParameter: { - z: { name: 'z', detail: '這是您要找出分佈的數值。' }, + z: { name: 'z', detail: '要找出分佈的數值。' }, }, }, NORMSINV: { @@ -361,12 +372,12 @@ export default { }, ], functionParameter: { - probability: { name: '機率', detail: '這是對應到常態分佈的機率。' }, + probability: { name: '機率', detail: '對應到常態分佈的機率。' }, }, }, PERCENTILE: { - description: '傳回區域中數值的第 k 個百分點的值', - abstract: '傳回區域中數值的第 k 個百分點的值', + description: '傳回資料集中第 k 個百分點的值 (包括 0 與 1)', + abstract: '傳回資料集中第 k 個百分點的值 (包括 0 與 1)', links: [ { title: '教導', @@ -374,13 +385,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '陣列', detail: '用以定義相對位置的陣列或資料範圍。' }, + k: { name: 'k', detail: '在 0 到 1 範圍內 (包括 0 與 1) 的百分位數。' }, }, }, PERCENTRANK: { - description: '傳回資料集中值的百分比排位', - abstract: '傳回資料集中值的百分比排位', + description: '傳回資料集中值的百分比排位 (包括 0 與 1)', + abstract: '傳回資料集中值的百分比排位 (包括 0 與 1)', links: [ { title: '教導', @@ -388,8 +399,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '陣列', detail: '用以定義相對位置的陣列或資料範圍。' }, + x: { name: 'x', detail: '想要知道排名的數值。' }, + significance: { name: '有效位數', detail: '用以識別傳回百分比值的最高有效位數之數值。 如果省略,PERCENTRANK 會使用三位小數 (0.xxx)。' }, }, }, POISSON: { @@ -402,13 +414,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '要找出分佈的數值。' }, + mean: { name: '平均值', detail: '分佈的算術平均值。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。 如果為 TRUE,POISSON 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, }, }, QUARTILE: { - description: '傳回一組資料的四分位點', - abstract: '傳回一組資料的四分位點', + description: '傳回資料集的四分位數 (包括 0 與 1)', + abstract: '傳回資料集的四分位數 (包括 0 與 1)', links: [ { title: '教導', @@ -416,8 +429,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '陣列', detail: '要求得四分位數值的陣列或資料範圍。' }, + quart: { name: '四分位值', detail: '要傳回的四分位數值。' }, }, }, RANK: { @@ -430,9 +443,9 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要找出其排名的數字。' }, + number: { name: '數值', detail: '要找出其排名的數字。' }, ref: { name: '數位清單', detail: '數位清單的參照。會忽略 ref 中的非數值。' }, - order: { name: '排列方式', detail: '這是指定排列數值方式的數字。0 或省略為遞減順序排序,非 0 為遞增順序排序。' }, + order: { name: '排列方式', detail: '指定排列數值方式的數字。0 或省略為遞減順序排序,非 0 為遞增順序排序。' }, }, }, STDEV: { @@ -464,7 +477,7 @@ export default { }, }, TDIST: { - description: '返回學生 t-分佈', + description: '傳回學生的 t 機率分佈', abstract: '返回學生 t-分佈', links: [ { @@ -473,13 +486,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要計算分佈的數值。' }, + degFreedom: { name: '自由度', detail: '一個表示自由度數的整數。' }, + tails: { name: '尾部特性', detail: '指定要傳回之分佈尾數。 如果 Tails = 1,TDIST 會傳回單尾分佈。 如果 Tails = 2,TDIST 會傳回雙尾分佈。' }, }, }, TINV: { - description: '傳回學生 t-分佈的反函數', - abstract: '傳回學生 t-分佈的反函數', + description: '傳回學生的 t 機率分佈的反函數 (雙尾)', + abstract: '傳回學生的 t 機率分佈的反函數 (雙尾)', links: [ { title: '教導', @@ -487,8 +501,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '機率', detail: '與學生的 t 分佈相關的機率。' }, + dedegFreedom: { name: '自由度', detail: '一個表示自由度數的整數。' }, }, }, TTEST: { @@ -501,8 +515,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: '陣列1', detail: '第一個陣列或資料範圍。' }, + array2: { name: '陣列2', detail: '第二個陣列或資料範圍。' }, + tails: { name: '尾部特性', detail: '指定分佈的尾數。 如果 tails = 1,TTEST 會使用單尾分佈。 如果 tails = 2,TTEST 會使用雙尾分佈。' }, + type: { name: '檢定類型', detail: '要執行的 t 檢定類型。' }, }, }, VAR: { @@ -534,8 +550,8 @@ export default { }, }, WEIBULL: { - description: '返回 Weibull 分佈', - abstract: '返回 Weibull 分佈', + description: '傳回 Weibull 分佈', + abstract: '傳回 Weibull 分佈', links: [ { title: '教導', @@ -543,8 +559,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '要找出分佈的數值。' }, + alpha: { name: 'alpha', detail: '分佈的第一個參數。' }, + beta: { name: 'beta', detail: '分佈的第二個參數。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。如果為 TRUE,則 WEIBULL 傳回累積分佈函數;如果為 FALSE,則傳回機率密度函數。' }, }, }, ZTEST: { @@ -557,8 +575,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '陣列', detail: '用來檢定 x 的陣列或資料範圍。' }, + x: { name: 'x', detail: '要檢定的值。' }, + sigma: { name: '標準差', detail: '總體(已知)標準差。如果省略,則使用樣本標準差。' }, }, }, }; diff --git a/packages/sheets-formula-ui/src/locale/function-list/date/zh-TW.ts b/packages/sheets-formula-ui/src/locale/function-list/date/zh-TW.ts index d3f3d322311a..ed209cef3899 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/date/zh-TW.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/date/zh-TW.ts @@ -42,7 +42,7 @@ export default { functionParameter: { startDate: { name: '開始日期', detail: '代表指定期間的第一個或開始日期的日期。' }, endDate: { name: '結束日期', detail: '代表期間最後一個或結束日期的日期。' }, - method: { name: '資訊類型', detail: '您要傳回的資訊類型' }, + method: { name: '資訊類型', detail: '要傳回的資訊類型' }, }, }, DATEVALUE: { @@ -190,9 +190,9 @@ export default { }, ], functionParameter: { - startDate: { name: '開始日期', detail: '這是代表開始日期的日期。' }, - endDate: { name: '結束日期', detail: '這是代表結束日期的日期。' }, - holidays: { name: '假日', detail: '這是要從工作行事曆中排除之一個或多個日期的選擇性範圍。' }, + startDate: { name: '開始日期', detail: '代表開始日期的日期。' }, + endDate: { name: '結束日期', detail: '代表結束日期的日期。' }, + holidays: { name: '假日', detail: '要從工作行事曆中排除之一個或多個日期的選擇性範圍。' }, }, }, NETWORKDAYS_INTL: { @@ -205,10 +205,10 @@ export default { }, ], functionParameter: { - startDate: { name: '開始日期', detail: '這是代表開始日期的日期。' }, - endDate: { name: '結束日期', detail: '這是代表結束日期的日期。' }, + startDate: { name: '開始日期', detail: '代表開始日期的日期。' }, + endDate: { name: '結束日期', detail: '代表結束日期的日期。' }, weekend: { name: '週末', detail: '是指定何時是週末的數字或字串。' }, - holidays: { name: '假日', detail: '這是要從工作行事曆中排除之一個或多個日期的選擇性範圍。' }, + holidays: { name: '假日', detail: '要從工作行事曆中排除之一個或多個日期的選擇性範圍。' }, }, }, NOW: { @@ -261,7 +261,7 @@ export default { }, ], functionParameter: { - timeText: { name: '時間文字', detail: '這是以任何一種時間格式表示的文字字串;例如,"6:45 PM" 和 "18:45",引號中的文字字串表示時間。' }, + timeText: { name: '時間文字', detail: '以任何一種時間格式表示的文字字串;例如,"6:45 PM" 和 "18:45",引號中的文字字串表示時間。' }, }, }, TODAY: { @@ -285,8 +285,8 @@ export default { }, ], functionParameter: { - serialNumber: { name: '日期序列值', detail: '這是代表要尋找之該天日期的序列值。' }, - returnType: { name: '傳回值類型', detail: '這是決定傳回值類型的數字。' }, + serialNumber: { name: '日期序列值', detail: '代表要尋找之該天日期的序列值。' }, + returnType: { name: '傳回值類型', detail: '決定傳回值類型的數字。' }, }, }, WEEKNUM: { @@ -299,8 +299,8 @@ export default { }, ], functionParameter: { - serialNumber: { name: '日期序列值', detail: '這是一週中的日期。' }, - returnType: { name: '傳回值類型', detail: '這是決定一週從星期幾開始的數字。 預設值為 1。' }, + serialNumber: { name: '日期序列值', detail: '一週中的日期。' }, + returnType: { name: '傳回值類型', detail: '決定一週從星期幾開始的數字。 預設值為 1。' }, }, }, WORKDAY: { @@ -313,9 +313,9 @@ export default { }, ], functionParameter: { - startDate: { name: '開始日期', detail: '這是代表開始日期的日期。' }, - days: { name: '天數', detail: '這是開始日期之前或之後的非週末和非假日的天數。正值代表未來的日期;負值代表過去的日期。' }, - holidays: { name: '假日', detail: '這是要從工作行事曆中排除之一個或多個日期的選擇性範圍。' }, + startDate: { name: '開始日期', detail: '代表開始日期的日期。' }, + days: { name: '天數', detail: '開始日期之前或之後的非週末和非假日的天數。正值代表未來的日期;負值代表過去的日期。' }, + holidays: { name: '假日', detail: '要從工作行事曆中排除之一個或多個日期的選擇性範圍。' }, }, }, WORKDAY_INTL: { @@ -328,10 +328,10 @@ export default { }, ], functionParameter: { - startDate: { name: '開始日期', detail: '這是代表開始日期的日期。' }, - days: { name: '天數', detail: '這是開始日期之前或之後的非週末和非假日的天數。正值代表未來的日期;負值代表過去的日期。' }, + startDate: { name: '開始日期', detail: '代表開始日期的日期。' }, + days: { name: '天數', detail: '開始日期之前或之後的非週末和非假日的天數。正值代表未來的日期;負值代表過去的日期。' }, weekend: { name: '週末', detail: '是指定何時是週末的數字或字串。' }, - holidays: { name: '假日', detail: '這是要從工作行事曆中排除之一個或多個日期的選擇性範圍。' }, + holidays: { name: '假日', detail: '要從工作行事曆中排除之一個或多個日期的選擇性範圍。' }, }, }, YEAR: { @@ -357,9 +357,9 @@ export default { }, ], functionParameter: { - startDate: { name: '开始日期', detail: '這是代表開始日期的日期。' }, - endDate: { name: '结束日期', detail: '這是代表結束日期的日期。' }, - basis: { name: '基礎類型', detail: '這是要使用的日計數基礎類型。' }, + startDate: { name: '开始日期', detail: '代表開始日期的日期。' }, + endDate: { name: '结束日期', detail: '代表結束日期的日期。' }, + basis: { name: '基礎類型', detail: '要使用的日計數基礎類型。' }, }, }, }; diff --git a/packages/sheets-formula-ui/src/locale/function-list/engineering/zh-TW.ts b/packages/sheets-formula-ui/src/locale/function-list/engineering/zh-TW.ts index e3702ef82e4e..a51c965a35c2 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/engineering/zh-TW.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/engineering/zh-TW.ts @@ -25,8 +25,8 @@ export default { }, ], functionParameter: { - x: { name: 'X', detail: '這是用於評估函數的值。' }, - n: { name: 'N', detail: '這是Bessel函數的順序。如果n不是整數,則會取至整數。' }, + x: { name: 'X', detail: '用於評估函數的值。' }, + n: { name: 'N', detail: 'Bessel函數的順序。如果n不是整數,則會取至整數。' }, }, }, BESSELJ: { @@ -39,8 +39,8 @@ export default { }, ], functionParameter: { - x: { name: 'X', detail: '這是用於評估函數的值。' }, - n: { name: 'N', detail: '這是Bessel函數的順序。如果n不是整數,則會取至整數。' }, + x: { name: 'X', detail: '用於評估函數的值。' }, + n: { name: 'N', detail: 'Bessel函數的順序。如果n不是整數,則會取至整數。' }, }, }, BESSELK: { @@ -53,8 +53,8 @@ export default { }, ], functionParameter: { - x: { name: 'X', detail: '這是用於評估函數的值。' }, - n: { name: 'N', detail: '這是Bessel函數的順序。如果n不是整數,則會取至整數。' }, + x: { name: 'X', detail: '用於評估函數的值。' }, + n: { name: 'N', detail: 'Bessel函數的順序。如果n不是整數,則會取至整數。' }, }, }, BESSELY: { @@ -67,8 +67,8 @@ export default { }, ], functionParameter: { - x: { name: 'X', detail: '這是用於評估函數的值。' }, - n: { name: 'N', detail: '這是Bessel函數的順序。如果n不是整數,則會取至整數。' }, + x: { name: 'X', detail: '用於評估函數的值。' }, + n: { name: 'N', detail: 'Bessel函數的順序。如果n不是整數,則會取至整數。' }, }, }, BIN2DEC: { @@ -81,7 +81,7 @@ export default { }, ], functionParameter: { - number: { name: '二進制數', detail: '您要轉換的二進制數。' }, + number: { name: '二進制數', detail: '要轉換的二進制數。' }, }, }, BIN2HEX: { @@ -94,8 +94,8 @@ export default { }, ], functionParameter: { - number: { name: '二進制數', detail: '您要轉換的二進制數。' }, - places: { name: '字元數', detail: '這是要使用的字元數。' }, + number: { name: '二進制數', detail: '要轉換的二進制數。' }, + places: { name: '字元數', detail: '要使用的字元數。' }, }, }, BIN2OCT: { @@ -108,8 +108,8 @@ export default { }, ], functionParameter: { - number: { name: '二進制數', detail: '您要轉換的二進制數。' }, - places: { name: '字元數', detail: '這是要使用的字元數。' }, + number: { name: '二進制數', detail: '要轉換的二進制數。' }, + places: { name: '字元數', detail: '要使用的字元數。' }, }, }, BITAND: { @@ -192,9 +192,9 @@ export default { }, ], functionParameter: { - realNum: { name: '實係數', detail: '這是複數的實係數。' }, - iNum: { name: '虛係數', detail: '這是複數的虛係數。' }, - suffix: { name: '字尾', detail: '這是複數虛數元件的字尾。如果省略,會將字尾假設為 "i"。' }, + realNum: { name: '實係數', detail: '複數的實係數。' }, + iNum: { name: '虛係數', detail: '複數的虛係數。' }, + suffix: { name: '字尾', detail: '複數虛數元件的字尾。如果省略,會將字尾假設為 "i"。' }, }, }, CONVERT: { @@ -208,8 +208,8 @@ export default { ], functionParameter: { number: { name: '數值', detail: '要轉換的值。' }, - fromUnit: { name: '轉換前單位', detail: '這是數值的單位。' }, - toUnit: { name: '轉換后單位', detail: '這是結果的單位。' }, + fromUnit: { name: '轉換前單位', detail: '數值的單位。' }, + toUnit: { name: '轉換后單位', detail: '結果的單位。' }, }, }, DEC2BIN: { @@ -222,8 +222,8 @@ export default { }, ], functionParameter: { - number: { name: '十進制數', detail: '您要轉換的十進制數。' }, - places: { name: '字元數', detail: '這是要使用的字元數。' }, + number: { name: '十進制數', detail: '要轉換的十進制數。' }, + places: { name: '字元數', detail: '要使用的字元數。' }, }, }, DEC2HEX: { @@ -236,8 +236,8 @@ export default { }, ], functionParameter: { - number: { name: '十進制數', detail: '您要轉換的十進制數。' }, - places: { name: '字元數', detail: '這是要使用的字元數。' }, + number: { name: '十進制數', detail: '要轉換的十進制數。' }, + places: { name: '字元數', detail: '要使用的字元數。' }, }, }, DEC2OCT: { @@ -250,8 +250,8 @@ export default { }, ], functionParameter: { - number: { name: '十進制數', detail: '您要轉換的十進制數。' }, - places: { name: '字元數', detail: '這是要使用的字元數。' }, + number: { name: '十進制數', detail: '要轉換的十進制數。' }, + places: { name: '字元數', detail: '要使用的字元數。' }, }, }, DELTA: { @@ -264,8 +264,8 @@ export default { }, ], functionParameter: { - number1: { name: '數值1', detail: '這是第一個數值。' }, - number2: { name: '數值2', detail: '這是第二個數值。如果省略,會將數值2假設為零。' }, + number1: { name: '數值1', detail: '第一個數值。' }, + number2: { name: '數值2', detail: '第二個數值。如果省略,會將數值2假設為零。' }, }, }, ERF: { @@ -278,8 +278,8 @@ export default { }, ], functionParameter: { - lowerLimit: { name: '下限', detail: '這是整合ERF的下限。' }, - upperLimit: { name: '上限', detail: '這是整合ERF的上限。如果省略,ERF會在零和下限之間整合。' }, + lowerLimit: { name: '下限', detail: '整合ERF的下限。' }, + upperLimit: { name: '上限', detail: '整合ERF的上限。如果省略,ERF會在零和下限之間整合。' }, }, }, ERF_PRECISE: { @@ -292,7 +292,7 @@ export default { }, ], functionParameter: { - x: { name: '下限', detail: '這是整合ERF.PRECISE的下限。' }, + x: { name: '下限', detail: '整合ERF.PRECISE的下限。' }, }, }, ERFC: { @@ -305,7 +305,7 @@ export default { }, ], functionParameter: { - x: { name: '下限', detail: '這是整合ERFC的下限。' }, + x: { name: '下限', detail: '整合ERFC的下限。' }, }, }, ERFC_PRECISE: { @@ -318,7 +318,7 @@ export default { }, ], functionParameter: { - x: { name: '下限', detail: '這是整合ERFC.PRECISE的下限。' }, + x: { name: '下限', detail: '整合ERFC.PRECISE的下限。' }, }, }, GESTEP: { @@ -331,8 +331,8 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要檢定閾值的值。' }, - step: { name: '閾值', detail: '這是閾值。如果您省略閾值的值,GESTEP 會使用零。' }, + number: { name: '數值', detail: '要檢定閾值的值。' }, + step: { name: '閾值', detail: '閾值。如果省略閾值的值,GESTEP 會使用零。' }, }, }, HEX2BIN: { @@ -345,8 +345,8 @@ export default { }, ], functionParameter: { - number: { name: '十六進制數', detail: '您要轉換的十六進制數。' }, - places: { name: '字元數', detail: '這是要使用的字元數。' }, + number: { name: '十六進制數', detail: '要轉換的十六進制數。' }, + places: { name: '字元數', detail: '要使用的字元數。' }, }, }, HEX2DEC: { @@ -359,7 +359,7 @@ export default { }, ], functionParameter: { - number: { name: '十六進制數', detail: '您要轉換的十六進制數。' }, + number: { name: '十六進制數', detail: '要轉換的十六進制數。' }, }, }, HEX2OCT: { @@ -372,8 +372,8 @@ export default { }, ], functionParameter: { - number: { name: '十六進制數', detail: '您要轉換的十六進制數。' }, - places: { name: '字元數', detail: '這是要使用的字元數。' }, + number: { name: '十六進制數', detail: '要轉換的十六進制數。' }, + places: { name: '字元數', detail: '要使用的字元數。' }, }, }, IMABS: { @@ -386,7 +386,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得絕對值的複數。' }, + inumber: { name: '複數', detail: '要求得絕對值的複數。' }, }, }, IMAGINARY: { @@ -399,7 +399,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得虛係數的複數。' }, + inumber: { name: '複數', detail: '要求得虛係數的複數。' }, }, }, IMARGUMENT: { @@ -412,7 +412,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求自變數 theta 的複數。' }, + inumber: { name: '複數', detail: '要求自變數 theta 的複數。' }, }, }, IMCONJUGATE: { @@ -425,7 +425,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得共軛的複數。' }, + inumber: { name: '複數', detail: '要求得共軛的複數。' }, }, }, IMCOS: { @@ -438,7 +438,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得餘弦值的複數。' }, + inumber: { name: '複數', detail: '要求得餘弦值的複數。' }, }, }, IMCOSH: { @@ -451,7 +451,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得雙曲餘弦值的複數。' }, + inumber: { name: '複數', detail: '要求得雙曲餘弦值的複數。' }, }, }, IMCOT: { @@ -464,7 +464,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得餘切值的複數。' }, + inumber: { name: '複數', detail: '要求得餘切值的複數。' }, }, }, IMCSC: { @@ -477,7 +477,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得餘割值的複數。' }, + inumber: { name: '複數', detail: '要求得餘割值的複數。' }, }, }, IMCSCH: { @@ -490,7 +490,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得雙曲餘割值的複數。' }, + inumber: { name: '複數', detail: '要求得雙曲餘割值的複數。' }, }, }, IMDIV: { @@ -503,8 +503,8 @@ export default { }, ], functionParameter: { - inumber1: { name: '複數分子', detail: '這是複數分子或被除數。' }, - inumber2: { name: '複數分母', detail: '這是複數分母或除數。' }, + inumber1: { name: '複數分子', detail: '複數分子或被除數。' }, + inumber2: { name: '複數分母', detail: '複數分母或除數。' }, }, }, IMEXP: { @@ -517,7 +517,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得指數的複數。' }, + inumber: { name: '複數', detail: '要求得指數的複數。' }, }, }, IMLN: { @@ -530,7 +530,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得自然對數的複數。' }, + inumber: { name: '複數', detail: '要求得自然對數的複數。' }, }, }, IMLOG10: { @@ -543,7 +543,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得常用對數的複數。' }, + inumber: { name: '複數', detail: '要求得常用對數的複數。' }, }, }, IMLOG2: { @@ -556,7 +556,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得底數為 2 之對數的複數。' }, + inumber: { name: '複數', detail: '要求得底數為 2 之對數的複數。' }, }, }, IMPOWER: { @@ -569,8 +569,8 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要遞增至乘冪的複數。' }, - number: { name: '數值', detail: '這是要遞增至複數的乘冪。' }, + inumber: { name: '複數', detail: '要遞增至乘冪的複數。' }, + number: { name: '數值', detail: '要遞增至複數的乘冪。' }, }, }, IMPRODUCT: { @@ -583,8 +583,8 @@ export default { }, ], functionParameter: { - inumber1: { name: '複數1', detail: '這是 1 到 255 個要乘以的複數。' }, - inumber2: { name: '複數2', detail: '這是 1 到 255 個要乘以的複數。' }, + inumber1: { name: '複數1', detail: '1 到 255 個要乘以的複數。' }, + inumber2: { name: '複數2', detail: '1 到 255 個要乘以的複數。' }, }, }, IMREAL: { @@ -597,7 +597,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得實係數的複數。' }, + inumber: { name: '複數', detail: '要求得實係數的複數。' }, }, }, IMSEC: { @@ -610,7 +610,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得正割值的複數。' }, + inumber: { name: '複數', detail: '要求得正割值的複數。' }, }, }, IMSECH: { @@ -623,7 +623,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得雙曲正割值的複數。' }, + inumber: { name: '複數', detail: '要求得雙曲正割值的複數。' }, }, }, IMSIN: { @@ -636,7 +636,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得正弦值的複數。' }, + inumber: { name: '複數', detail: '要求得正弦值的複數。' }, }, }, IMSINH: { @@ -649,7 +649,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得雙曲正弦值的複數。' }, + inumber: { name: '複數', detail: '要求得雙曲正弦值的複數。' }, }, }, IMSQRT: { @@ -662,7 +662,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得平方根的複數。' }, + inumber: { name: '複數', detail: '要求得平方根的複數。' }, }, }, IMSUB: { @@ -689,8 +689,8 @@ export default { }, ], functionParameter: { - inumber1: { name: '複數1', detail: '這是 1 到 255 個要相加的複數。' }, - inumber2: { name: '複數2', detail: '這是 1 到 255 個要相加的複數。' }, + inumber1: { name: '複數1', detail: '1 到 255 個要相加的複數。' }, + inumber2: { name: '複數2', detail: '1 到 255 個要相加的複數。' }, }, }, IMTAN: { @@ -703,7 +703,7 @@ export default { }, ], functionParameter: { - inumber: { name: '複數', detail: '這是要求得正切值的複數。' }, + inumber: { name: '複數', detail: '要求得正切值的複數。' }, }, }, OCT2BIN: { @@ -716,8 +716,8 @@ export default { }, ], functionParameter: { - number: { name: '八進制數', detail: '您要轉換的八進制數。' }, - places: { name: '字元數', detail: '這是要使用的字元數。' }, + number: { name: '八進制數', detail: '要轉換的八進制數。' }, + places: { name: '字元數', detail: '要使用的字元數。' }, }, }, OCT2DEC: { @@ -730,7 +730,7 @@ export default { }, ], functionParameter: { - number: { name: '八進制數', detail: '您要轉換的八進制數。' }, + number: { name: '八進制數', detail: '要轉換的八進制數。' }, }, }, OCT2HEX: { @@ -743,8 +743,8 @@ export default { }, ], functionParameter: { - number: { name: '八進制數', detail: '您要轉換的八進制數。' }, - places: { name: '字元數', detail: '這是要使用的字元數。' }, + number: { name: '八進制數', detail: '要轉換的八進制數。' }, + places: { name: '字元數', detail: '要使用的字元數。' }, }, }, }; diff --git a/packages/sheets-formula-ui/src/locale/function-list/financial/zh-CN.ts b/packages/sheets-formula-ui/src/locale/function-list/financial/zh-CN.ts index 520d833cb4e1..48ef75352593 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/financial/zh-CN.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/financial/zh-CN.ts @@ -230,7 +230,7 @@ export default { cost: { name: '成本', detail: '资产原值。' }, salvage: { name: '残值', detail: '折旧末尾时的值(有时也称为资产残值)。' }, life: { name: '使用寿命', detail: '资产的折旧期数(有时也称作资产的使用寿命)。' }, - period: { name: '期间', detail: '您要计算折旧的时期。' }, + period: { name: '期间', detail: '要计算折旧的时期。' }, month: { name: '月份', detail: '第一年的月份数。如果省略月份,则假定其值为12。' }, }, }, @@ -247,7 +247,7 @@ export default { cost: { name: '成本', detail: '资产原值。' }, salvage: { name: '残值', detail: '折旧末尾时的值(有时也称为资产残值)。' }, life: { name: '使用寿命', detail: '资产的折旧期数(有时也称作资产的使用寿命)。' }, - period: { name: '期间', detail: '您要计算折旧的时期。' }, + period: { name: '期间', detail: '要计算折旧的时期。' }, factor: { name: '速率', detail: '余额递减速率。如果省略影响因素,则假定为2(双倍余额递减法)。' }, }, }, @@ -404,7 +404,7 @@ export default { }, ], functionParameter: { - values: { name: '现金流', detail: '数组或单元格的引用,这些单元格包含用来计算内部收益率的数字。\n1.Values 必须包含至少一个正值和一个负值,以计算返回的内部收益率。\n2.IRR 使用值的顺序来说明现金流的顺序。 一定要按您需要的顺序输入支出值和收益值。\n3.如果数组或引用包含文本、逻辑值或空白单元格,这些数值将被忽略。' }, + values: { name: '现金流', detail: '数组或单元格的引用,这些单元格包含用来计算内部收益率的数字。\n1.Values 必须包含至少一个正值和一个负值,以计算返回的内部收益率。\n2.IRR 使用值的顺序来说明现金流的顺序。 一定要按需要的顺序输入支出值和收益值。\n3.如果数组或引用包含文本、逻辑值或空白单元格,这些数值将被忽略。' }, guess: { name: '估计值', detail: '对函数 IRR 计算结果的估计值。' }, }, }, @@ -845,8 +845,8 @@ export default { cost: { name: '成本', detail: '资产原值。' }, salvage: { name: '残值', detail: '折旧末尾时的值(有时也称为资产残值)。' }, life: { name: '使用寿命', detail: '资产的折旧期数(有时也称作资产的使用寿命)。' }, - startPeriod: { name: '起始时期', detail: '您要计算折旧的起始时期。' }, - endPeriod: { name: '终止时期', detail: '您要计算折旧的终止时期。' }, + startPeriod: { name: '起始时期', detail: '要计算折旧的起始时期。' }, + endPeriod: { name: '终止时期', detail: '要计算折旧的终止时期。' }, factor: { name: '速率', detail: '余额递减速率。如果省略影响因素,则假定为2(双倍余额递减法)。' }, noSwitch: { name: '不切换', detail: '逻辑值,指定当折旧值大于余额递减计算值时,是否转用直线折旧法。' }, }, diff --git a/packages/sheets-formula-ui/src/locale/function-list/financial/zh-TW.ts b/packages/sheets-formula-ui/src/locale/function-list/financial/zh-TW.ts index d8c74b6873ae..f8922466e65d 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/financial/zh-TW.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/financial/zh-TW.ts @@ -25,13 +25,13 @@ export default { }, ], functionParameter: { - issue: { name: '發行日', detail: '這是證券的發行日期。' }, - firstInterest: { name: '首次計息日', detail: '這是證券的第一個利率日期。' }, - settlement: { name: '到期日', detail: '這是證券的到期日期。' }, - rate: { name: '利率', detail: '這是證券的年度票息率。' }, - par: { name: '面值', detail: '這是證券的票面價值。' }, - frequency: { name: '頻次', detail: '這是每年票息付款的次數。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + issue: { name: '發行日', detail: '證券的發行日期。' }, + firstInterest: { name: '首次計息日', detail: '證券的第一個利率日期。' }, + settlement: { name: '到期日', detail: '證券的到期日期。' }, + rate: { name: '利率', detail: '證券的年度票息率。' }, + par: { name: '面值', detail: '證券的票面價值。' }, + frequency: { name: '頻次', detail: '每年票息付款的次數。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, calcMethod: { name: '計算方法', detail: '是一個邏輯值:從發行日期開始的應計利息 = TRUE 或忽略;從最後票據支付日期開始計算 = FALSE。' }, }, }, @@ -45,11 +45,11 @@ export default { }, ], functionParameter: { - issue: { name: '發行日', detail: '這是證券的發行日期。' }, - settlement: { name: '到期日', detail: '這是證券的到期日期。' }, - rate: { name: '利率', detail: '這是證券的年度票息率。' }, - par: { name: '面值', detail: '這是證券的票面價值。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + issue: { name: '發行日', detail: '證券的發行日期。' }, + settlement: { name: '到期日', detail: '證券的到期日期。' }, + rate: { name: '利率', detail: '證券的年度票息率。' }, + par: { name: '面值', detail: '證券的票面價值。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, AMORDEGRC: { @@ -76,13 +76,13 @@ export default { }, ], functionParameter: { - cost: { name: '成本', detail: '這是資產的成本。' }, - datePurchased: { name: '購買日期', detail: '這是資產的購買日期。' }, - firstPeriod: { name: '首個週期', detail: '這是第一個週期結束的日期。' }, + cost: { name: '成本', detail: '資產的成本。' }, + datePurchased: { name: '購買日期', detail: '資產的購買日期。' }, + firstPeriod: { name: '首個週期', detail: '第一個週期結束的日期。' }, salvage: { name: '殘值', detail: '資產耐用年限終了時的殘餘價值。' }, - period: { name: '週期', detail: '這是週期。' }, - rate: { name: '折舊率', detail: '這是折舊率。' }, - basis: { name: '基礎', detail: '這是要使用的年計數基礎。' }, + period: { name: '週期', detail: '週期。' }, + rate: { name: '折舊率', detail: '折舊率。' }, + basis: { name: '基礎', detail: '要使用的年計數基礎。' }, }, }, COUPDAYBS: { @@ -95,10 +95,10 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - frequency: { name: '頻次', detail: '這是每年票息付款的次數。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + frequency: { name: '頻次', detail: '每年票息付款的次數。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, COUPDAYS: { @@ -111,10 +111,10 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - frequency: { name: '頻次', detail: '這是每年票息付款的次數。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + frequency: { name: '頻次', detail: '每年票息付款的次數。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, COUPDAYSNC: { @@ -127,10 +127,10 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - frequency: { name: '頻次', detail: '這是每年票息付款的次數。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + frequency: { name: '頻次', detail: '每年票息付款的次數。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, COUPNCD: { @@ -143,10 +143,10 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - frequency: { name: '頻次', detail: '這是每年票息付款的次數。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + frequency: { name: '頻次', detail: '每年票息付款的次數。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, COUPNUM: { @@ -159,10 +159,10 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - frequency: { name: '頻次', detail: '這是每年票息付款的次數。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + frequency: { name: '頻次', detail: '每年票息付款的次數。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, COUPPCD: { @@ -175,10 +175,10 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - frequency: { name: '頻次', detail: '這是每年票息付款的次數。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + frequency: { name: '頻次', detail: '每年票息付款的次數。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, CUMIPMT: { @@ -191,12 +191,12 @@ export default { }, ], functionParameter: { - rate: { name: '利率', detail: '這是利率。' }, - nper: { name: '總期數', detail: '這是總付款期數。' }, - pv: { name: '現值', detail: '這是現值。' }, - startPeriod: { name: '首期', detail: '這是計算中的第一個週期。付款週期的編號由1開始。' }, - endPeriod: { name: '末期', detail: '這是計算中的最後一個週期。' }, - type: { name: '類型', detail: '這是付款的時機。' }, + rate: { name: '利率', detail: '利率。' }, + nper: { name: '總期數', detail: '總付款期數。' }, + pv: { name: '現值', detail: '現值。' }, + startPeriod: { name: '首期', detail: '計算中的第一個週期。付款週期的編號由1開始。' }, + endPeriod: { name: '末期', detail: '計算中的最後一個週期。' }, + type: { name: '類型', detail: '付款的時機。' }, }, }, CUMPRINC: { @@ -209,12 +209,12 @@ export default { }, ], functionParameter: { - rate: { name: '利率', detail: '這是利率。' }, - nper: { name: '總期數', detail: '這是總付款期數。' }, - pv: { name: '現值', detail: '這是現值。' }, - startPeriod: { name: '首期', detail: '這是計算中的第一個週期。付款週期的編號由1開始。' }, - endPeriod: { name: '末期', detail: '這是計算中的最後一個週期。' }, - type: { name: '類型', detail: '這是付款的時機。' }, + rate: { name: '利率', detail: '利率。' }, + nper: { name: '總期數', detail: '總付款期數。' }, + pv: { name: '現值', detail: '現值。' }, + startPeriod: { name: '首期', detail: '計算中的第一個週期。付款週期的編號由1開始。' }, + endPeriod: { name: '末期', detail: '計算中的最後一個週期。' }, + type: { name: '類型', detail: '付款的時機。' }, }, }, DB: { @@ -227,10 +227,10 @@ export default { }, ], functionParameter: { - cost: { name: '成本', detail: '這是資產的原始成本。' }, - salvage: { name: '殘值', detail: '這是折舊最後的值 (有時稱為資產的殘餘價值)。' }, - life: { name: '使用年限', detail: '這是資產折舊的期數 (有時稱為資產的使用年限)。' }, - period: { name: '期間', detail: '這是要計算折舊的期間。' }, + cost: { name: '成本', detail: '資產的原始成本。' }, + salvage: { name: '殘值', detail: '折舊最後的值 (有時稱為資產的殘餘價值)。' }, + life: { name: '使用年限', detail: '資產折舊的期數 (有時稱為資產的使用年限)。' }, + period: { name: '期間', detail: '要計算折舊的期間。' }, month: { name: '月份', detail: '第一年的月份數。如果省略 month,則假設其值為12。' }, }, }, @@ -244,11 +244,11 @@ export default { }, ], functionParameter: { - cost: { name: '成本', detail: '這是資產的原始成本。' }, - salvage: { name: '殘值', detail: '這是折舊最後的值 (有時稱為資產的殘餘價值)。' }, - life: { name: '使用年限', detail: '這是資產折舊的期數 (有時稱為資產的使用年限)。' }, - period: { name: '期間', detail: '這是要計算折舊的期間。' }, - factor: { name: '速率', detail: '這是餘額遞減的速率。如果省略factor,將假設其值為2(倍率遞減法)。' }, + cost: { name: '成本', detail: '資產的原始成本。' }, + salvage: { name: '殘值', detail: '折舊最後的值 (有時稱為資產的殘餘價值)。' }, + life: { name: '使用年限', detail: '資產折舊的期數 (有時稱為資產的使用年限)。' }, + period: { name: '期間', detail: '要計算折舊的期間。' }, + factor: { name: '速率', detail: '餘額遞減的速率。如果省略factor,將假設其值為2(倍率遞減法)。' }, }, }, DISC: { @@ -261,11 +261,11 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - pr: { name: '價格', detail: '這是證券每$100面額的價格。' }, - redemption: { name: '贖回價', detail: '這是證券每$100面額的贖回價值。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + pr: { name: '價格', detail: '證券每$100面額的價格。' }, + redemption: { name: '贖回價', detail: '證券每$100面額的贖回價值。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, DOLLARDE: { @@ -278,8 +278,8 @@ export default { }, ], functionParameter: { - fractionalDollar: { name: '分數', detail: '這是以整數部分和分數部分表示,並以小數點符號分隔的數字。' }, - fraction: { name: '分母', detail: '這是用於分數之分母的整數。' }, + fractionalDollar: { name: '分數', detail: '以整數部分和分數部分表示,並以小數點符號分隔的數字。' }, + fraction: { name: '分母', detail: '用於分數之分母的整數。' }, }, }, DOLLARFR: { @@ -292,8 +292,8 @@ export default { }, ], functionParameter: { - decimalDollar: { name: '小數', detail: '這是小數。' }, - fraction: { name: '分母', detail: '這是用於分數之分母的整數。' }, + decimalDollar: { name: '小數', detail: '小數。' }, + fraction: { name: '分母', detail: '用於分數之分母的整數。' }, }, }, DURATION: { @@ -306,12 +306,12 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - coupon: { name: '年度票息率', detail: '這是證券的年度票息率。' }, - yld: { name: '年收益率', detail: '這是證券的年收益。' }, - frequency: { name: '頻次', detail: '這是每年票息付款的次數。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + coupon: { name: '年度票息率', detail: '證券的年度票息率。' }, + yld: { name: '年收益率', detail: '證券的年收益。' }, + frequency: { name: '頻次', detail: '每年票息付款的次數。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, EFFECT: { @@ -324,7 +324,7 @@ export default { }, ], functionParameter: { - nominalRate: { name: '名義利率', detail: '這是名義利率。' }, + nominalRate: { name: '名義利率', detail: '名義利率。' }, npery: { name: '期數', detail: '每年以複利計算之期數。' }, }, }, @@ -338,9 +338,9 @@ export default { }, ], functionParameter: { - rate: { name: '利率', detail: '這是各期的利率。' }, - nper: { name: '總期數', detail: '這是年金的總付款期數。' }, - pmt: { name: '金額', detail: '這是各期給付的金額;不得在年金期限內變更。' }, + rate: { name: '利率', detail: '各期的利率。' }, + nper: { name: '總期數', detail: '年金的總付款期數。' }, + pmt: { name: '金額', detail: '各期給付的金額;不得在年金期限內變更。' }, pv: { name: '現值', detail: '一系列未來付款的現值或目前總額。' }, type: { name: '類型', detail: '數字0或1,指出付款期限。' }, }, @@ -355,8 +355,8 @@ export default { }, ], functionParameter: { - principal: { name: '初始資金', detail: '這是現值。' }, - schedule: { name: '利率陣列', detail: '這是要套用的利率陣列。' }, + principal: { name: '初始資金', detail: '現值。' }, + schedule: { name: '利率陣列', detail: '要套用的利率陣列。' }, }, }, INTRATE: { @@ -369,11 +369,11 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - investment: { name: '投資額', detail: '這是證券的投資額。' }, - redemption: { name: '贖回價', detail: '這是證券到期時的贖回價值。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + investment: { name: '投資額', detail: '證券的投資額。' }, + redemption: { name: '贖回價', detail: '證券到期時的贖回價值。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, IPMT: { @@ -386,11 +386,11 @@ export default { }, ], functionParameter: { - rate: { name: '利率', detail: '這是各期的利率。' }, - per: { name: '期數', detail: '這是求算利息的期次,其值必須介於1到nper之間。' }, - nper: { name: '總期數', detail: '這是年金的總付款期數。' }, + rate: { name: '利率', detail: '各期的利率。' }, + per: { name: '期數', detail: '求算利息的期次,其值必須介於1到nper之間。' }, + nper: { name: '總期數', detail: '年金的總付款期數。' }, pv: { name: '現值', detail: '一系列未來付款的現值或目前總額。' }, - fv: { name: '餘額', detail: '這是最後一次付款完成後,所能獲得的未來值或現金餘額。' }, + fv: { name: '餘額', detail: '最後一次付款完成後,所能獲得的未來值或現金餘額。' }, type: { name: '類型', detail: '數字0或1,指出付款期限。' }, }, }, @@ -404,8 +404,8 @@ export default { }, ], functionParameter: { - values: { name: '現金流', detail: '這是陣列或儲存格參照,其中包含要計算內部報酬率的數字。\n1.Values 必須至少包含一個正數和一個負數,以計算內部報酬率。\n2.IRR 使用 values 的順序來表示現金流量的順序。 請務必依所要的順序輸入支出及收入的值。\n3.如果陣列或參照引數中包含文字、邏輯值或空白儲存格,則這些值將會略過。' }, - guess: { name: '猜測值', detail: '這是您猜測接近 IRR 結果的數字。' }, + values: { name: '現金流', detail: '陣列或儲存格參照,其中包含要計算內部報酬率的數字。\n1.Values 必須至少包含一個正數和一個負數,以計算內部報酬率。\n2.IRR 使用 values 的順序來表示現金流量的順序。 請務必依所要的順序輸入支出及收入的值。\n3.如果陣列或參照引數中包含文字、邏輯值或空白儲存格,則這些值將會略過。' }, + guess: { name: '猜測值', detail: '猜測接近 IRR 結果的數字。' }, }, }, ISPMT: { @@ -418,10 +418,10 @@ export default { }, ], functionParameter: { - rate: { name: '利率', detail: '這是投資的利率。' }, - per: { name: '期數', detail: '這是要尋找利息的期間,其值必須介於1到Nper之間。' }, - nper: { name: '總期數', detail: '這是投資的總付款期數。' }, - pv: { name: '現值', detail: '這是投資的現值。若為貸款,Pv為貸款金額。' }, + rate: { name: '利率', detail: '投資的利率。' }, + per: { name: '期數', detail: '要尋找利息的期間,其值必須介於1到Nper之間。' }, + nper: { name: '總期數', detail: '投資的總付款期數。' }, + pv: { name: '現值', detail: '投資的現值。若為貸款,Pv為貸款金額。' }, }, }, MDURATION: { @@ -434,12 +434,12 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - coupon: { name: '年度票息率', detail: '這是證券的年度票息率。' }, - yld: { name: '年收益率', detail: '這是證券的年收益。' }, - frequency: { name: '頻次', detail: '這是每年票息付款的次數。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + coupon: { name: '年度票息率', detail: '證券的年度票息率。' }, + yld: { name: '年收益率', detail: '證券的年收益。' }, + frequency: { name: '頻次', detail: '每年票息付款的次數。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, MIRR: { @@ -452,9 +452,9 @@ export default { }, ], functionParameter: { - values: { name: '現金流', detail: '這是陣列或儲存格參照,其中包含數字。 這些數字代表定期發生的一系列支出 (負值) 和收入 (正值)。\n1.Values 必須至少包含一個正值和一個負值,以計算經修改的內部報酬率。 否則,MIRR 會傳回 #DIV/0! 的錯誤值。\n2.如果陣列或參照引數包含文字、邏輯值或空白儲存格,則忽略這些數值;但包含零值儲存格。' }, - financeRate: { name: '融資利率', detail: '這是投入資金的融資利率。' }, - reinvestRate: { name: '轉投資報酬率', detail: '這是各期收入淨額的轉投資報酬率。' }, + values: { name: '現金流', detail: '陣列或儲存格參照,其中包含數字。 這些數字代表定期發生的一系列支出 (負值) 和收入 (正值)。\n1.Values 必須至少包含一個正值和一個負值,以計算經修改的內部報酬率。 否則,MIRR 會傳回 #DIV/0! 的錯誤值。\n2.如果陣列或參照引數包含文字、邏輯值或空白儲存格,則忽略這些數值;但包含零值儲存格。' }, + financeRate: { name: '融資利率', detail: '投入資金的融資利率。' }, + reinvestRate: { name: '轉投資報酬率', detail: '各期收入淨額的轉投資報酬率。' }, }, }, NOMINAL: { @@ -467,7 +467,7 @@ export default { }, ], functionParameter: { - effectRate: { name: '實質利率', detail: '這是實質利率。' }, + effectRate: { name: '實質利率', detail: '實質利率。' }, npery: { name: '期數', detail: '每年以複利計算之期數。' }, }, }, @@ -481,10 +481,10 @@ export default { }, ], functionParameter: { - rate: { name: '利率', detail: '這是各期的利率。' }, - pmt: { name: '金額', detail: '這是各期給付的金額;不得在年金期限內變更。' }, + rate: { name: '利率', detail: '各期的利率。' }, + pmt: { name: '金額', detail: '各期給付的金額;不得在年金期限內變更。' }, pv: { name: '現值', detail: '一系列未來付款的現值或目前總額。' }, - fv: { name: '餘額', detail: '這是最後一次付款完成後,所能獲得的未來值或現金餘額。' }, + fv: { name: '餘額', detail: '最後一次付款完成後,所能獲得的未來值或現金餘額。' }, type: { name: '類型', detail: '數字0或1,指出付款期限。' }, }, }, @@ -498,9 +498,9 @@ export default { }, ], functionParameter: { - rate: { name: '貼現率', detail: '這是一段期間內的貼現率。' }, - value1: { name: '現金流1', detail: '這是 1 到 254 個代表支出和收入的引數。' }, - value2: { name: '現金流2', detail: '這是 1 到 254 個代表支出和收入的引數。' }, + rate: { name: '貼現率', detail: '一段期間內的貼現率。' }, + value1: { name: '現金流1', detail: '1 到 254 個代表支出和收入的引數。' }, + value2: { name: '現金流2', detail: '1 到 254 個代表支出和收入的引數。' }, }, }, ODDFPRICE: { @@ -513,15 +513,15 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - issue: { name: '發行日期', detail: '這是證券的發行日期。' }, - firstCoupon: { name: '首次付息日期', detail: '這是證券的首次付息日期。' }, - rate: { name: '利率', detail: '這是證券的年度票息率。' }, - yld: { name: '年收益率', detail: '這是證券的年收益。' }, - redemption: { name: '贖回價', detail: '這是證券到期時的贖回價值。' }, - frequency: { name: '頻次', detail: '這是每年票息付款的次數。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + issue: { name: '發行日期', detail: '證券的發行日期。' }, + firstCoupon: { name: '首次付息日期', detail: '證券的首次付息日期。' }, + rate: { name: '利率', detail: '證券的年度票息率。' }, + yld: { name: '年收益率', detail: '證券的年收益。' }, + redemption: { name: '贖回價', detail: '證券到期時的贖回價值。' }, + frequency: { name: '頻次', detail: '每年票息付款的次數。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, ODDFYIELD: { @@ -534,15 +534,15 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - issue: { name: '發行日期', detail: '這是證券的發行日期。' }, - firstCoupon: { name: '首次付息日期', detail: '這是證券的首次付息日期。' }, - rate: { name: '利率', detail: '這是證券的年度票息率。' }, - pr: { name: '價格', detail: '這是證券的價格。' }, - redemption: { name: '贖回價', detail: '這是證券到期時的贖回價值。' }, - frequency: { name: '頻次', detail: '這是每年票息付款的次數。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + issue: { name: '發行日期', detail: '證券的發行日期。' }, + firstCoupon: { name: '首次付息日期', detail: '證券的首次付息日期。' }, + rate: { name: '利率', detail: '證券的年度票息率。' }, + pr: { name: '價格', detail: '證券的價格。' }, + redemption: { name: '贖回價', detail: '證券到期時的贖回價值。' }, + frequency: { name: '頻次', detail: '每年票息付款的次數。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, ODDLPRICE: { @@ -555,14 +555,14 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - lastInterest: { name: '最後票息日期', detail: '這是證券的最後票息日期。' }, - rate: { name: '利率', detail: '這是證券的年度票息率。' }, - yld: { name: '年收益率', detail: '這是證券的年收益。' }, - redemption: { name: '贖回價', detail: '這是證券到期時的贖回價值。' }, - frequency: { name: '頻次', detail: '這是每年票息付款的次數。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + lastInterest: { name: '最後票息日期', detail: '證券的最後票息日期。' }, + rate: { name: '利率', detail: '證券的年度票息率。' }, + yld: { name: '年收益率', detail: '證券的年收益。' }, + redemption: { name: '贖回價', detail: '證券到期時的贖回價值。' }, + frequency: { name: '頻次', detail: '每年票息付款的次數。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, ODDLYIELD: { @@ -575,14 +575,14 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - lastInterest: { name: '最後票息日期', detail: '這是證券的最後票息日期。' }, - rate: { name: '利率', detail: '這是證券的年度票息率。' }, - pr: { name: '價格', detail: '這是證券的價格。' }, - redemption: { name: '贖回價', detail: '這是證券到期時的贖回價值。' }, - frequency: { name: '頻次', detail: '這是每年票息付款的次數。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + lastInterest: { name: '最後票息日期', detail: '證券的最後票息日期。' }, + rate: { name: '利率', detail: '證券的年度票息率。' }, + pr: { name: '價格', detail: '證券的價格。' }, + redemption: { name: '贖回價', detail: '證券到期時的贖回價值。' }, + frequency: { name: '頻次', detail: '每年票息付款的次數。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, PDURATION: { @@ -610,10 +610,10 @@ export default { }, ], functionParameter: { - rate: { name: '利率', detail: '這是各期的利率。' }, - nper: { name: '總期數', detail: '這是年金的總付款期數。' }, + rate: { name: '利率', detail: '各期的利率。' }, + nper: { name: '總期數', detail: '年金的總付款期數。' }, pv: { name: '現值', detail: '一系列未來付款的現值或目前總額。' }, - fv: { name: '餘額', detail: '這是最後一次付款完成後,所能獲得的未來值或現金餘額。' }, + fv: { name: '餘額', detail: '最後一次付款完成後,所能獲得的未來值或現金餘額。' }, type: { name: '類型', detail: '數字0或1,指出付款期限。' }, }, }, @@ -627,11 +627,11 @@ export default { }, ], functionParameter: { - rate: { name: '利率', detail: '這是各期的利率。' }, - per: { name: '期數', detail: '這是求算利息的期次,其值必須介於1到nper之間。' }, - nper: { name: '總期數', detail: '這是年金的總付款期數。' }, + rate: { name: '利率', detail: '各期的利率。' }, + per: { name: '期數', detail: '求算利息的期次,其值必須介於1到nper之間。' }, + nper: { name: '總期數', detail: '年金的總付款期數。' }, pv: { name: '現值', detail: '一系列未來付款的現值或目前總額。' }, - fv: { name: '餘額', detail: '這是最後一次付款完成後,所能獲得的未來值或現金餘額。' }, + fv: { name: '餘額', detail: '最後一次付款完成後,所能獲得的未來值或現金餘額。' }, type: { name: '類型', detail: '數字0或1,指出付款期限。' }, }, }, @@ -645,13 +645,13 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - rate: { name: '利率', detail: '這是證券的年度票息率。' }, - yld: { name: '年收益率', detail: '這是證券的年收益。' }, - redemption: { name: '贖回價', detail: '這是證券到期時的贖回價值。' }, - frequency: { name: '頻次', detail: '這是每年票息付款的次數。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + rate: { name: '利率', detail: '證券的年度票息率。' }, + yld: { name: '年收益率', detail: '證券的年收益。' }, + redemption: { name: '贖回價', detail: '證券到期時的贖回價值。' }, + frequency: { name: '頻次', detail: '每年票息付款的次數。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, PRICEDISC: { @@ -664,11 +664,11 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - discount: { name: '貼現率', detail: '這是證券的貼現率。' }, - redemption: { name: '贖回價', detail: '這是證券到期時的贖回價值。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + discount: { name: '貼現率', detail: '證券的貼現率。' }, + redemption: { name: '贖回價', detail: '證券到期時的贖回價值。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, PRICEMAT: { @@ -681,12 +681,12 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - issue: { name: '發行日期', detail: '這是證券的發行日期。' }, - rate: { name: '利率', detail: '這是證券的年度票息率。' }, - yld: { name: '年收益率', detail: '這是證券的年收益。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + issue: { name: '發行日期', detail: '證券的發行日期。' }, + rate: { name: '利率', detail: '證券的年度票息率。' }, + yld: { name: '年收益率', detail: '證券的年收益。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, PV: { @@ -699,10 +699,10 @@ export default { }, ], functionParameter: { - rate: { name: '利率', detail: '這是各期的利率。' }, - nper: { name: '總期數', detail: '這是年金的總付款期數。' }, - pmt: { name: '金額', detail: '這是各期給付的金額;不得在年金期限內變更。' }, - fv: { name: '餘額', detail: '這是最後一次付款完成後,所能獲得的未來值或現金餘額。' }, + rate: { name: '利率', detail: '各期的利率。' }, + nper: { name: '總期數', detail: '年金的總付款期數。' }, + pmt: { name: '金額', detail: '各期給付的金額;不得在年金期限內變更。' }, + fv: { name: '餘額', detail: '最後一次付款完成後,所能獲得的未來值或現金餘額。' }, type: { name: '類型', detail: '數字0或1,指出付款期限。' }, }, }, @@ -716,12 +716,12 @@ export default { }, ], functionParameter: { - nper: { name: '總期數', detail: '這是年金的總付款期數。' }, - pmt: { name: '金額', detail: '這是各期給付的金額;不得在年金期限內變更。' }, + nper: { name: '總期數', detail: '年金的總付款期數。' }, + pmt: { name: '金額', detail: '各期給付的金額;不得在年金期限內變更。' }, pv: { name: '現值', detail: '一系列未來付款的現值或目前總額。' }, - fv: { name: '餘額', detail: '這是最後一次付款完成後,所能獲得的未來值或現金餘額。' }, + fv: { name: '餘額', detail: '最後一次付款完成後,所能獲得的未來值或現金餘額。' }, type: { name: '類型', detail: '數字0或1,指出付款期限。' }, - guess: { name: '猜測值', detail: '這是對利率的猜測值。' }, + guess: { name: '猜測值', detail: '對利率的猜測值。' }, }, }, RECEIVED: { @@ -734,11 +734,11 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - investment: { name: '投資額', detail: '這是證券的投資額。' }, - discount: { name: '貼現率', detail: '這是證券的貼現率。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + investment: { name: '投資額', detail: '證券的投資額。' }, + discount: { name: '貼現率', detail: '證券的貼現率。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, RRI: { @@ -766,9 +766,9 @@ export default { }, ], functionParameter: { - cost: { name: '資產原始成本', detail: '這是資產的原始成本。' }, - salvage: { name: '資產殘餘價值', detail: '這是折舊最後的值 (有時稱為資產的殘餘價值)。' }, - life: { name: '資產使用年限', detail: '這是固定資產折舊的期數 (有時稱為固定資產的使用年限)。' }, + cost: { name: '資產原始成本', detail: '資產的原始成本。' }, + salvage: { name: '資產殘餘價值', detail: '折舊最後的值 (有時稱為資產的殘餘價值)。' }, + life: { name: '資產使用年限', detail: '固定資產折舊的期數 (有時稱為固定資產的使用年限)。' }, }, }, SYD: { @@ -781,10 +781,10 @@ export default { }, ], functionParameter: { - cost: { name: '資產原始成本', detail: '這是資產的原始成本。' }, - salvage: { name: '資產殘餘價值', detail: '這是折舊最後的值 (有時稱為資產的殘餘價值)。' }, - life: { name: '資產使用年限', detail: '這是固定資產折舊的期數 (有時稱為固定資產的使用年限)。' }, - per: { name: '週期', detail: '這是週期。' }, + cost: { name: '資產原始成本', detail: '資產的原始成本。' }, + salvage: { name: '資產殘餘價值', detail: '折舊最後的值 (有時稱為資產的殘餘價值)。' }, + life: { name: '資產使用年限', detail: '固定資產折舊的期數 (有時稱為固定資產的使用年限)。' }, + per: { name: '週期', detail: '週期。' }, }, }, TBILLEQ: { @@ -797,9 +797,9 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是國庫券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是國庫券的到期日期。' }, - discount: { name: '貼現率', detail: '這是國庫券的貼現率。' }, + settlement: { name: '結算日期', detail: '國庫券的結算日期。' }, + maturity: { name: '到期日期', detail: '國庫券的到期日期。' }, + discount: { name: '貼現率', detail: '國庫券的貼現率。' }, }, }, TBILLPRICE: { @@ -812,9 +812,9 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是國庫券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是國庫券的到期日期。' }, - discount: { name: '貼現率', detail: '這是國庫券的貼現率。' }, + settlement: { name: '結算日期', detail: '國庫券的結算日期。' }, + maturity: { name: '到期日期', detail: '國庫券的到期日期。' }, + discount: { name: '貼現率', detail: '國庫券的貼現率。' }, }, }, TBILLYIELD: { @@ -827,9 +827,9 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是國庫券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是國庫券的到期日期。' }, - pr: { name: '價格', detail: '這是國庫債券每 $100 美元面額的價格。' }, + settlement: { name: '結算日期', detail: '國庫券的結算日期。' }, + maturity: { name: '到期日期', detail: '國庫券的到期日期。' }, + pr: { name: '價格', detail: '國庫債券每 $100 美元面額的價格。' }, }, }, VDB: { @@ -842,13 +842,13 @@ export default { }, ], functionParameter: { - cost: { name: '成本', detail: '這是資產的原始成本。' }, - salvage: { name: '殘值', detail: '這是折舊最後的值 (有時稱為資產的殘餘價值)。' }, - life: { name: '使用年限', detail: '這是資產折舊的期數 (有時稱為資產的使用年限)。' }, - startPeriod: { name: '開始期間', detail: '這是要計算折舊的開始期間。' }, - endPeriod: { name: '結束期間', detail: '這是要計算折舊的結束期間。' }, - factor: { name: '速率', detail: '這是餘額遞減的速率。如果省略factor,將假設其值為2(倍率遞減法)。' }, - noSwitch: { name: '不切換', detail: '這是用於指定當折舊大於遞減餘額計算時,是否切換到直線折舊法的邏輯值。' }, + cost: { name: '成本', detail: '資產的原始成本。' }, + salvage: { name: '殘值', detail: '折舊最後的值 (有時稱為資產的殘餘價值)。' }, + life: { name: '使用年限', detail: '資產折舊的期數 (有時稱為資產的使用年限)。' }, + startPeriod: { name: '開始期間', detail: '要計算折舊的開始期間。' }, + endPeriod: { name: '結束期間', detail: '要計算折舊的結束期間。' }, + factor: { name: '速率', detail: '餘額遞減的速率。如果省略factor,將假設其值為2(倍率遞減法)。' }, + noSwitch: { name: '不切換', detail: '用於指定當折舊大於遞減餘額計算時,是否切換到直線折舊法的邏輯值。' }, }, }, XIRR: { @@ -861,9 +861,9 @@ export default { }, ], functionParameter: { - values: { name: '現金流', detail: '這是一系列與 dates 的付款日期對應的現金流。第一次付款是選擇性的,而且與投資開始時的成本和付款對應。如果第一個值是成本或付款,則它必須是負值。而之後的付款都會以一年 365 天為基礎來折算。序列值必須至少包括一個正值和一個負值。' }, - dates: { name: '日期表', detail: '這是一系列與現金流對應的付款日期。日期可能會以任何順序發生。' }, - guess: { name: '猜測值', detail: '這是您所猜測接近 XIRR 結果的數字。' }, + values: { name: '現金流', detail: '一系列與 dates 的付款日期對應的現金流。第一次付款是選擇性的,而且與投資開始時的成本和付款對應。如果第一個值是成本或付款,則它必須是負值。而之後的付款都會以一年 365 天為基礎來折算。序列值必須至少包括一個正值和一個負值。' }, + dates: { name: '日期表', detail: '一系列與現金流對應的付款日期。日期可能會以任何順序發生。' }, + guess: { name: '猜測值', detail: '所猜測接近 XIRR 結果的數字。' }, }, }, XNPV: { @@ -876,9 +876,9 @@ export default { }, ], functionParameter: { - rate: { name: '貼現率', detail: '這是要套用到現金流的貼現率。' }, - values: { name: '現金流', detail: '這是一系列與 dates 的付款日期對應的現金流。第一次付款是選擇性的,而且與投資開始時的成本和付款對應。如果第一個值是成本或付款,則它必須是負值。而之後的付款都會以一年 365 天為基礎來折算。序列值必須至少包括一個正值和一個負值。' }, - dates: { name: '日期表', detail: '這是一系列與現金流對應的付款日期。日期可能會以任何順序發生。' }, + rate: { name: '貼現率', detail: '要套用到現金流的貼現率。' }, + values: { name: '現金流', detail: '一系列與 dates 的付款日期對應的現金流。第一次付款是選擇性的,而且與投資開始時的成本和付款對應。如果第一個值是成本或付款,則它必須是負值。而之後的付款都會以一年 365 天為基礎來折算。序列值必須至少包括一個正值和一個負值。' }, + dates: { name: '日期表', detail: '一系列與現金流對應的付款日期。日期可能會以任何順序發生。' }, }, }, YIELD: { @@ -890,13 +890,13 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - rate: { name: '利率', detail: '這是證券的年度票息率。' }, - pr: { name: '價格', detail: '這是證券每 $100 面額的價格。' }, - redemption: { name: '贖回價', detail: '這是證券到期時的贖回價值。' }, - frequency: { name: '頻次', detail: '這是每年票息付款的次數。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + rate: { name: '利率', detail: '證券的年度票息率。' }, + pr: { name: '價格', detail: '證券每 $100 面額的價格。' }, + redemption: { name: '贖回價', detail: '證券到期時的贖回價值。' }, + frequency: { name: '頻次', detail: '每年票息付款的次數。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, YIELDDISC: { @@ -909,11 +909,11 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - pr: { name: '價格', detail: '這是證券每 $100 面額的價格。' }, - redemption: { name: '贖回價', detail: '這是證券到期時的贖回價值。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + pr: { name: '價格', detail: '證券每 $100 面額的價格。' }, + redemption: { name: '贖回價', detail: '證券到期時的贖回價值。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, YIELDMAT: { @@ -926,12 +926,12 @@ export default { }, ], functionParameter: { - settlement: { name: '結算日期', detail: '這是證券的結算日期。' }, - maturity: { name: '到期日期', detail: '這是證券的到期日期。' }, - issue: { name: '發行日期', detail: '這是證券的發行日期。' }, - rate: { name: '利率', detail: '這是證券的年度票息率。' }, - pr: { name: '價格', detail: '這是證券每 $100 面額的價格。' }, - basis: { name: '基礎', detail: '這是要使用的日計數基礎類型。' }, + settlement: { name: '結算日期', detail: '證券的結算日期。' }, + maturity: { name: '到期日期', detail: '證券的到期日期。' }, + issue: { name: '發行日期', detail: '證券的發行日期。' }, + rate: { name: '利率', detail: '證券的年度票息率。' }, + pr: { name: '價格', detail: '證券每 $100 面額的價格。' }, + basis: { name: '基礎', detail: '要使用的日計數基礎類型。' }, }, }, }; diff --git a/packages/sheets-formula-ui/src/locale/function-list/information/zh-TW.ts b/packages/sheets-formula-ui/src/locale/function-list/information/zh-TW.ts index 6ed3ad335db9..f47c4e787a4b 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/information/zh-TW.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/information/zh-TW.ts @@ -25,8 +25,8 @@ export default { }, ], functionParameter: { - infoType: { name: '資訊類型', detail: '這是指定所要傳回何種儲存格資訊類型的文字值。' }, - reference: { name: '參考', detail: '這是您要取得其相關資訊的儲存格。' }, + infoType: { name: '資訊類型', detail: '指定所要傳回何種儲存格資訊類型的文字值。' }, + reference: { name: '參考', detail: '要取得其相關資訊的儲存格。' }, }, }, ERROR_TYPE: { @@ -39,7 +39,7 @@ export default { }, ], functionParameter: { - errorVal: { name: '錯誤值', detail: '這是您要尋找之識別數字的錯誤值。' }, + errorVal: { name: '錯誤值', detail: '要尋找之識別數字的錯誤值。' }, }, }, INFO: { @@ -118,7 +118,7 @@ export default { }, ], functionParameter: { - reference: { name: '參照', detail: '是您要測試之儲存格的參照。' }, + reference: { name: '參照', detail: '是要測試之儲存格的參照。' }, }, }, ISLOGICAL: { @@ -235,7 +235,7 @@ export default { }, ], functionParameter: { - value: { name: '值', detail: '這是要轉換的值。' }, + value: { name: '值', detail: '要轉換的值。' }, }, }, NA: { diff --git a/packages/sheets-formula-ui/src/locale/function-list/logical/zh-CN.ts b/packages/sheets-formula-ui/src/locale/function-list/logical/zh-CN.ts index 7ff229a45ad4..b88cfe940287 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/logical/zh-CN.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/logical/zh-CN.ts @@ -79,13 +79,13 @@ export default { ], functionParameter: { logicalTest: { name: '布尔表达式', detail: '要测试的条件。' }, - valueIfTrue: { name: '如果值为 true', detail: 'logical_test 的结果为 TRUE 时,您希望返回的值。' }, - valueIfFalse: { name: '如果值为 false', detail: 'logical_test 的结果为 FALSE 时,您希望返回的值。' }, + valueIfTrue: { name: '如果值为 true', detail: 'logical_test 的结果为 TRUE 时,希望返回的值。' }, + valueIfFalse: { name: '如果值为 false', detail: 'logical_test 的结果为 FALSE 时,希望返回的值。' }, }, }, IFERROR: { - description: '如果公式的计算结果错误,则返回您指定的值;否则返回公式的结果', - abstract: '如果公式的计算结果错误,则返回您指定的值;否则返回公式的结果', + description: '如果公式的计算结果错误,则返回指定的值;否则返回公式的结果', + abstract: '如果公式的计算结果错误,则返回指定的值;否则返回公式的结果', links: [ { title: '教学', @@ -98,8 +98,8 @@ export default { }, }, IFNA: { - description: '如果表达式的结果为 #N/A,则返回您指定的值,否则返回表达式的结果', - abstract: '如果表达式的结果为 #N/A,则返回您指定的值,否则返回表达式的结果', + description: '如果表达式的结果为 #N/A,则返回指定的值,否则返回表达式的结果', + abstract: '如果表达式的结果为 #N/A,则返回指定的值,否则返回表达式的结果', links: [ { title: '教学', @@ -208,7 +208,7 @@ export default { }, ], functionParameter: { - logical: { name: '逻辑表达式', detail: '您要反转逻辑的条件,可评估为 TRUE 或 FALSE。' }, + logical: { name: '逻辑表达式', detail: '要反转逻辑的条件,可评估为 TRUE 或 FALSE。' }, }, }, OR: { diff --git a/packages/sheets-formula-ui/src/locale/function-list/logical/zh-TW.ts b/packages/sheets-formula-ui/src/locale/function-list/logical/zh-TW.ts index f3727ff8d0fb..62a7f5720845 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/logical/zh-TW.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/logical/zh-TW.ts @@ -80,13 +80,13 @@ export default { ], functionParameter: { logicalTest: { name: '布林表達式', detail: '要測試的條件。 ' }, - valueIfTrue: { name: '如果值為 true', detail: 'logical_test 的結果為 TRUE 時,您希望傳回的值。 ' }, - valueIfFalse: { name: '如果值為 false', detail: 'logical_test 的結果為 FALSE 時,您希望傳回的值。 ' }, + valueIfTrue: { name: '如果值為 true', detail: 'logical_test 的結果為 TRUE 時,希望傳回的值。 ' }, + valueIfFalse: { name: '如果值為 false', detail: 'logical_test 的結果為 FALSE 時,希望傳回的值。 ' }, }, }, IFERROR: { - description: '如果公式的計算結果錯誤,則傳回您指定的值;否則傳回公式的結果', - abstract: '如果公式的計算結果錯誤,則傳回您指定的值;否則傳回公式的結果', + description: '如果公式的計算結果錯誤,則傳回指定的值;否則傳回公式的結果', + abstract: '如果公式的計算結果錯誤,則傳回指定的值;否則傳回公式的結果', links: [ { title: '教導', @@ -209,7 +209,7 @@ export default { }, ], functionParameter: { - logical: { name: '邏輯表達式', detail: '您要反轉邏輯的條件,可評估為 TRUE 或 FALSE。' }, + logical: { name: '邏輯表達式', detail: '要反轉邏輯的條件,可評估為 TRUE 或 FALSE。' }, }, }, OR: { diff --git a/packages/sheets-formula-ui/src/locale/function-list/lookup/zh-CN.ts b/packages/sheets-formula-ui/src/locale/function-list/lookup/zh-CN.ts index 74405e16bbf0..5572aa214620 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/lookup/zh-CN.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/lookup/zh-CN.ts @@ -298,7 +298,7 @@ export default { }, }, LOOKUP: { - description: '当您需要查询一行或一列并查找另一行或列中的相同位置的值时使用', + description: '当需要查询一行或一列并查找另一行或列中的相同位置的值时使用', abstract: '在向量或数组中查找值', links: [ { diff --git a/packages/sheets-formula-ui/src/locale/function-list/lookup/zh-TW.ts b/packages/sheets-formula-ui/src/locale/function-list/lookup/zh-TW.ts index 1b4b761a89df..87b84c262f0d 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/lookup/zh-TW.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/lookup/zh-TW.ts @@ -298,7 +298,7 @@ export default { }, }, LOOKUP: { - description: '當您需要查詢一行或一列並查找另一行或列中的相同位置的值時使用', + description: '當需要查詢一行或一列並查找另一行或列中的相同位置的值時使用', abstract: '在向量或陣列中找出值', links: [ { diff --git a/packages/sheets-formula-ui/src/locale/function-list/math/vi-VN.ts b/packages/sheets-formula-ui/src/locale/function-list/math/vi-VN.ts index 961ddbccb083..079721cb62de 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/math/vi-VN.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/math/vi-VN.ts @@ -218,8 +218,8 @@ export default { }, }, COMBIN: { - description: 'Trả về số tổ hợp cho số mục nhất định. Hãy dùng COMBIN để xác định tổng số nhóm có thể có cho số hạng mục nhất định.', - abstract: 'Trả về số tổ hợp cho số mục nhất định. Hãy dùng COMBIN để xác định tổng số nhóm có thể có cho số hạng mục nhất định.', + description: 'Trả về số tổ hợp cho số mục nhất định.', + abstract: 'Trả về số tổ hợp cho số mục nhất định.', links: [ { title: 'Hướng dẫn', diff --git a/packages/sheets-formula-ui/src/locale/function-list/math/zh-TW.ts b/packages/sheets-formula-ui/src/locale/function-list/math/zh-TW.ts index 2dc205693986..d2adb48ac228 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/math/zh-TW.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/math/zh-TW.ts @@ -119,7 +119,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是欲求角度的正弦值,其值必須介於 -1 到 1。' }, + number: { name: '數值', detail: '欲求角度的正弦值,其值必須介於 -1 到 1。' }, }, }, ASINH: { @@ -132,7 +132,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是任意實數。' }, + number: { name: '數值', detail: '任意實數。' }, }, }, ATAN: { @@ -145,7 +145,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是欲求角度的正切值。' }, + number: { name: '數值', detail: '欲求角度的正切值。' }, }, }, ATAN2: { @@ -158,8 +158,8 @@ export default { }, ], functionParameter: { - xNum: { name: 'x 座標', detail: '這是點的 X 座標。' }, - yNum: { name: 'y 座標', detail: '這是點的 Y 座標。' }, + xNum: { name: 'x 座標', detail: '點的 X 座標。' }, + yNum: { name: 'y 座標', detail: '點的 Y 座標。' }, }, }, ATANH: { @@ -172,7 +172,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是任何介於 1 和 -1 之間的實數。' }, + number: { name: '數值', detail: '任何介於 1 和 -1 之間的實數。' }, }, }, BASE: { @@ -185,8 +185,8 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要轉換的數位。必須是大於或等於 0 且小於 2^53 的整數。' }, - radix: { name: '基數', detail: '這是要將數字轉換為底數的基數。必須是大於或等於 2 且小於或等於 36 的整數。' }, + number: { name: '數值', detail: '要轉換的數位。必須是大於或等於 0 且小於 2^53 的整數。' }, + radix: { name: '基數', detail: '要將數字轉換為底數的基數。必須是大於或等於 2 且小於或等於 36 的整數。' }, minLength: { name: '最小長度', detail: '傳回之字串的最小長度。必須是大於或等於 0 的整數。' }, }, }, @@ -200,8 +200,8 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要捨位的數值。' }, - significance: { name: '倍數', detail: '這是要捨位的倍數。' }, + number: { name: '數值', detail: '要捨位的數值。' }, + significance: { name: '倍數', detail: '要捨位的倍數。' }, }, }, CEILING_MATH: { @@ -214,8 +214,8 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要捨位的數值。' }, - significance: { name: '倍數', detail: '這是要捨位的倍數。' }, + number: { name: '數值', detail: '要捨位的數值。' }, + significance: { name: '倍數', detail: '要捨位的倍數。' }, mode: { name: '眾數', detail: '對於負數,請控制數位是否趨於或背離於零。' }, }, }, @@ -229,8 +229,8 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要捨位的數值。' }, - significance: { name: '倍數', detail: '這是要捨位的倍數。' }, + number: { name: '數值', detail: '要捨位的數值。' }, + significance: { name: '倍數', detail: '要捨位的倍數。' }, }, }, COMBIN: { @@ -243,8 +243,8 @@ export default { }, ], functionParameter: { - number: { name: '總數', detail: '這是項目數。' }, - numberChosen: { name: '樣品數量', detail: '這是每個組合中的項目數。' }, + number: { name: '總數', detail: '項目數。' }, + numberChosen: { name: '樣品數量', detail: '每個組合中的項目數。' }, }, }, COMBINA: { @@ -257,8 +257,8 @@ export default { }, ], functionParameter: { - number: { name: '總數', detail: '這是項目數。' }, - numberChosen: { name: '樣品數量', detail: '這是每個組合中的項目數。' }, + number: { name: '總數', detail: '項目數。' }, + numberChosen: { name: '樣品數量', detail: '每個組合中的項目數。' }, }, }, COS: { @@ -271,7 +271,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: ' 這是欲求算其餘弦值的角度,以弧度表示。' }, + number: { name: '數值', detail: '欲求算其餘弦值的角度,以弧度表示。' }, }, }, COSH: { @@ -284,7 +284,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是欲求得其雙曲線餘弦值的任意實數。' }, + number: { name: '數值', detail: '欲求得其雙曲線餘弦值的任意實數。' }, }, }, COT: { @@ -297,7 +297,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是欲求餘切值的角度,以弧度表示。' }, + number: { name: '數值', detail: '欲求餘切值的角度,以弧度表示。' }, }, }, COTH: { @@ -350,7 +350,7 @@ export default { ], functionParameter: { text: { name: '字串', detail: '字串長度必須小於或等於 255 個字元。' }, - radix: { name: '基數', detail: '這是要將數字轉換為底數的基數。 必須是大於或等於 2 且小於或等於 36 的整數。' }, + radix: { name: '基數', detail: '要將數字轉換為底數的基數。 必須是大於或等於 2 且小於或等於 36 的整數。' }, }, }, DEGREES: { @@ -363,7 +363,7 @@ export default { }, ], functionParameter: { - angle: { name: '角度', detail: '這是要轉換的角度,以弧度表示。' }, + angle: { name: '角度', detail: '要轉換的角度,以弧度表示。' }, }, }, EVEN: { @@ -376,7 +376,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要捨入的數值。' }, + number: { name: '數值', detail: '要捨入的數值。' }, }, }, EXP: { @@ -389,7 +389,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是套用至基數 e 的指數。' }, + number: { name: '數值', detail: '套用至基數 e 的指數。' }, }, }, FACT: { @@ -402,7 +402,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是您要階乘的非負數數字。 如果數字不是整數,則只會取整數。' }, + number: { name: '數值', detail: '要階乘的非負數數字。 如果數字不是整數,則只會取整數。' }, }, }, FACTDOUBLE: { @@ -415,7 +415,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是您要雙倍階乘的非負數數字。 如果數字不是整數,則只會取整數。' }, + number: { name: '數值', detail: '要雙倍階乘的非負數數字。 如果數字不是整數,則只會取整數。' }, }, }, FLOOR: { @@ -428,8 +428,8 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要捨位的數值。' }, - significance: { name: '倍數', detail: '這是要捨位的倍數。' }, + number: { name: '數值', detail: '要捨位的數值。' }, + significance: { name: '倍數', detail: '要捨位的倍數。' }, }, }, FLOOR_MATH: { @@ -442,8 +442,8 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要捨位的數值。' }, - significance: { name: '倍數', detail: '這是要捨位的倍數。' }, + number: { name: '數值', detail: '要捨位的數值。' }, + significance: { name: '倍數', detail: '要捨位的倍數。' }, mode: { name: '眾數', detail: '對於負數,請控制數位是否趨於或背離於零。' }, }, }, @@ -457,8 +457,8 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要捨位的數值。' }, - significance: { name: '倍數', detail: '這是要捨位的倍數。' }, + number: { name: '數值', detail: '要捨位的數值。' }, + significance: { name: '倍數', detail: '要捨位的倍數。' }, }, }, GCD: { @@ -485,7 +485,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要將數字向下捨去到最接近的整數的實數。' }, + number: { name: '數值', detail: '要將數字向下捨去到最接近的整數的實數。' }, }, }, ISO_CEILING: { @@ -540,7 +540,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要求得自然對數的正實數。' }, + number: { name: '數值', detail: '要求得自然對數的正實數。' }, }, }, LOG: { @@ -553,8 +553,8 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要求得對數的正實數。' }, - base: { name: '底數', detail: '這是對數的底數。 如果省略 base,則假設其值為 10。' }, + number: { name: '數值', detail: '要求得對數的正實數。' }, + base: { name: '底數', detail: '對數的底數。 如果省略 base,則假設其值為 10。' }, }, }, LOG10: { @@ -567,7 +567,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要求得底數為 10 之對數的正實數。' }, + number: { name: '數值', detail: '要求得底數為 10 之對數的正實數。' }, }, }, MDETERM: { @@ -580,7 +580,7 @@ export default { }, ], functionParameter: { - array: { name: '陣列', detail: '這是具有相同列數與欄數的數值陣列。' }, + array: { name: '陣列', detail: '具有相同列數與欄數的數值陣列。' }, }, }, MINVERSE: { @@ -593,7 +593,7 @@ export default { }, ], functionParameter: { - array: { name: '陣列', detail: '這是具有相同列數與欄數的數值陣列。' }, + array: { name: '陣列', detail: '具有相同列數與欄數的數值陣列。' }, }, }, MMULT: { @@ -606,8 +606,8 @@ export default { }, ], functionParameter: { - array1: { name: '陣列1', detail: '這是您要相乘的陣列。' }, - array2: { name: '陣列2', detail: '這是您要相乘的陣列。' }, + array1: { name: '陣列1', detail: '要相乘的陣列。' }, + array2: { name: '陣列2', detail: '要相乘的陣列。' }, }, }, MOD: { @@ -634,8 +634,8 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要捨入的數值。' }, - multiple: { name: '倍數', detail: '這是要捨入數字的倍數。' }, + number: { name: '數值', detail: '要捨入的數值。' }, + multiple: { name: '倍數', detail: '要捨入數字的倍數。' }, }, }, MULTINOMIAL: { @@ -675,7 +675,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要捨入的數值。' }, + number: { name: '數值', detail: '要捨入的數值。' }, }, }, PI: { @@ -728,8 +728,8 @@ export default { }, ], functionParameter: { - numerator: { name: '分子', detail: '這是被除數。' }, - denominator: { name: '分母', detail: '這是除數。' }, + numerator: { name: '分子', detail: '被除數。' }, + denominator: { name: '分母', detail: '除數。' }, }, }, RADIANS: { @@ -741,7 +741,7 @@ export default { }, ], functionParameter: { - angle: { name: '角度', detail: '這是要轉換的角度 (以度數為單位)。' }, + angle: { name: '角度', detail: '要轉換的角度 (以度數為單位)。' }, }, }, RAND: { @@ -811,8 +811,8 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要四捨五入的數字。' }, - numDigits: { name: '位數', detail: '這是要對數字引數進位的位數。' }, + number: { name: '數值', detail: '要四捨五入的數字。' }, + numDigits: { name: '位數', detail: '要對數字引數進位的位數。' }, }, }, ROUNDDOWN: { @@ -825,8 +825,8 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要四捨五入的數字。' }, - numDigits: { name: '位數', detail: '這是要對數字引數進位的位數。' }, + number: { name: '數值', detail: '要四捨五入的數字。' }, + numDigits: { name: '位數', detail: '要對數字引數進位的位數。' }, }, }, ROUNDUP: { @@ -839,8 +839,8 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要四捨五入的數字。' }, - numDigits: { name: '位數', detail: '這是要對數字引數進位的位數。' }, + number: { name: '數值', detail: '要四捨五入的數字。' }, + numDigits: { name: '位數', detail: '要對數字引數進位的位數。' }, }, }, SEC: { @@ -879,10 +879,10 @@ export default { }, ], functionParameter: { - x: { name: 'x', detail: '這是冪級數的輸入值。' }, - n: { name: 'n', detail: '這是要增加 x 的初始乘冪。' }, - m: { name: 'm', detail: '這是要將級數中的每一項增加 n 所用的間距。' }, - coefficients: { name: '係數集', detail: '這是一組由 x 的每一個連續乘冪相乘的係數集。' }, + x: { name: 'x', detail: '冪級數的輸入值。' }, + n: { name: 'n', detail: '要增加 x 的初始乘冪。' }, + m: { name: 'm', detail: '要將級數中的每一項增加 n 所用的間距。' }, + coefficients: { name: '係數集', detail: '一組由 x 的每一個連續乘冪相乘的係數集。' }, }, }, SEQUENCE: { @@ -911,7 +911,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是任意實數。' }, + number: { name: '數值', detail: '任意實數。' }, }, }, SIN: { @@ -924,7 +924,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要求出正弦值的角度,以弧度表示。' }, + number: { name: '數值', detail: '要求出正弦值的角度,以弧度表示。' }, }, }, SINH: { @@ -937,7 +937,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是任意實數。' }, + number: { name: '數值', detail: '任意實數。' }, }, }, SQRT: { @@ -950,7 +950,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要求得平方根的數字。' }, + number: { name: '數值', detail: '要求得平方根的數字。' }, }, }, SQRTPI: { @@ -963,7 +963,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要乘以 pi 的數值。' }, + number: { name: '數值', detail: '要乘以 pi 的數值。' }, }, }, SUBTOTAL: { @@ -997,7 +997,7 @@ export default { }, number2: { name: '數值 2', - detail: '這是第二個要相加的數字。 可以按照這種方式指定最多 255 個數字。 ', + detail: '第二個要相加的數字。 可以按照這種方式指定最多 255 個數字。 ', }, }, }, @@ -1052,8 +1052,8 @@ export default { }, ], functionParameter: { - array1: { name: '陣列', detail: '這是您要求元素乘積和的第一個陣列引數。' }, - array2: { name: '陣列', detail: '這是您要求元素乘積和的第 2 個到第 255 個陣列引數。' }, + array1: { name: '陣列', detail: '要求元素乘積和的第一個陣列引數。' }, + array2: { name: '陣列', detail: '要求元素乘積和的第 2 個到第 255 個陣列引數。' }, }, }, SUMSQ: { @@ -1066,8 +1066,8 @@ export default { }, ], functionParameter: { - number1: { name: '數值1', detail: '這是要求出平方總和的第1個數字。您也可以使用單一陣列或陣列參照來取代以逗點分隔的引數。' }, - number2: { name: '數值2', detail: '這是要求出平方總和的第2個數字。可以按照這種方式指定最多 255 個數字。' }, + number1: { name: '數值1', detail: '要求出平方總和的第1個數字。也可以使用單一陣列或陣列參照來取代以逗點分隔的引數。' }, + number2: { name: '數值2', detail: '要求出平方總和的第2個數字。可以按照這種方式指定最多 255 個數字。' }, }, }, SUMX2MY2: { @@ -1080,8 +1080,8 @@ export default { }, ], functionParameter: { - arrayX: { name: '值陣列1', detail: '這是第一個值陣列或範圍。' }, - arrayY: { name: '值陣列2', detail: '這是第二個值陣列或範圍。' }, + arrayX: { name: '值陣列1', detail: '第一個值陣列或範圍。' }, + arrayY: { name: '值陣列2', detail: '第二個值陣列或範圍。' }, }, }, SUMX2PY2: { @@ -1094,8 +1094,8 @@ export default { }, ], functionParameter: { - arrayX: { name: '值陣列1', detail: '這是第一個值陣列或範圍。' }, - arrayY: { name: '值陣列2', detail: '這是第二個值陣列或範圍。' }, + arrayX: { name: '值陣列1', detail: '第一個值陣列或範圍。' }, + arrayY: { name: '值陣列2', detail: '第二個值陣列或範圍。' }, }, }, SUMXMY2: { @@ -1108,8 +1108,8 @@ export default { }, ], functionParameter: { - arrayX: { name: '值陣列1', detail: '這是第一個值陣列或範圍。' }, - arrayY: { name: '值陣列2', detail: '這是第二個值陣列或範圍。' }, + arrayX: { name: '值陣列1', detail: '第一個值陣列或範圍。' }, + arrayY: { name: '值陣列2', detail: '第二個值陣列或範圍。' }, }, }, TAN: { @@ -1122,7 +1122,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要求出正切值的角度,以弧度表示。' }, + number: { name: '數值', detail: '要求出正切值的角度,以弧度表示。' }, }, }, TANH: { @@ -1135,7 +1135,7 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是任意實數。' }, + number: { name: '數值', detail: '任意實數。' }, }, }, TRUNC: { @@ -1148,8 +1148,8 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要取至整數的數字。' }, - numDigits: { name: '位數', detail: '這是指定要捨去之精確位數的數字。其預設值為 0 (零)。' }, + number: { name: '數值', detail: '要取至整數的數字。' }, + numDigits: { name: '位數', detail: '指定要捨去之精確位數的數字。其預設值為 0 (零)。' }, }, }, }; diff --git a/packages/sheets-formula-ui/src/locale/function-list/statistical/en-US.ts b/packages/sheets-formula-ui/src/locale/function-list/statistical/en-US.ts index 873d874297b1..445baeb559cb 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/statistical/en-US.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/statistical/en-US.ts @@ -636,8 +636,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + dataArray: { name: 'data_array', detail: 'An array of or reference to a set of values for which you want to count frequencies. If data_array contains no values, FREQUENCY returns an array of zeros.' }, + binsArray: { name: 'bins_array', detail: 'An array of or reference to intervals into which you want to group the values in data_array. If bins_array contains no values, FREQUENCY returns the number of elements in data_array.' }, }, }, GAMMA: { @@ -650,8 +650,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number: { name: 'number', detail: 'Input value to the gamma function.' }, }, }, GAMMA_DIST: { @@ -664,8 +663,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'The value for which you want the distribution.' }, + alpha: { name: 'alpha', detail: 'A parameter of the distribution.' }, + beta: { name: 'beta', detail: 'A parameter of the distribution.' }, + cumulative: { name: 'cumulative', detail: 'A logical value that determines the form of the function. If cumulative is TRUE, GAMMA.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.' }, }, }, GAMMA_INV: { @@ -678,8 +679,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: 'probability', detail: 'A probability associated with the gamma distribution.' }, + alpha: { name: 'alpha', detail: 'A parameter of the distribution.' }, + beta: { name: 'beta', detail: 'A parameter of the distribution.' }, }, }, GAMMALN: { @@ -692,8 +694,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'The value for which you want to calculate GAMMALN.' }, }, }, GAMMALN_PRECISE: { @@ -706,8 +707,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'The value for which you want to calculate GAMMALN.PRECISE.' }, }, }, GAUSS: { @@ -720,8 +720,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + z: { name: 'z', detail: 'The value for which you want the distribution.' }, }, }, GEOMEAN: { @@ -734,8 +733,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: 'number1', detail: 'The first number, cell reference, or range for which you want the geometric mean.' }, + number2: { name: 'number2', detail: 'Additional numbers, cell references or ranges for which you want the geometric mean, up to a maximum of 255.' }, }, }, GROWTH: { @@ -748,8 +747,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + knownYs: { name: "known_y's", detail: 'The set of y-values you already know in the relationship y = b*m^x.' }, + knownXs: { name: "known_x's", detail: 'The set of x-values you already know in the relationship y = b*m^x.' }, + newXs: { name: "new_x's", detail: 'Are new x-values for which you want GROWTH to return corresponding y-values.' }, + constb: { name: 'const', detail: 'A logical value specifying whether to force the constant b to equal 1.' }, }, }, HARMEAN: { @@ -762,8 +763,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: 'number1', detail: 'The first number, cell reference, or range for which you want the harmonic mean.' }, + number2: { name: 'number2', detail: 'Additional numbers, cell references or ranges for which you want the harmonic mean, up to a maximum of 255.' }, }, }, HYPGEOM_DIST: { @@ -776,8 +777,11 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + sampleS: { name: 'sample_s', detail: 'The number of successes in the sample.' }, + numberSample: { name: 'number_sample', detail: 'The size of the sample.' }, + populationS: { name: 'population_s', detail: 'The number of successes in the population.' }, + numberPop: { name: 'number_pop', detail: 'The population size.' }, + cumulative: { name: 'cumulative', detail: 'A logical value that determines the form of the function. If cumulative is TRUE, HYPGEOM.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.' }, }, }, INTERCEPT: { @@ -804,8 +808,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: 'number1', detail: 'The first number, cell reference, or range for which you want the kurtosis.' }, + number2: { name: 'number2', detail: 'Additional numbers, cell references or ranges for which you want the kurtosis, up to a maximum of 255.' }, }, }, LARGE: { @@ -818,8 +822,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: 'array', detail: 'The array or range of data for which you want to determine the k-th largest value.' }, + k: { name: 'k', detail: 'The position (from the largest) in the array or cell range of data to return.' }, }, }, LINEST: { @@ -860,8 +864,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'The value for which you want the distribution.' }, + mean: { name: 'mean', detail: 'The arithmetic mean of the distribution.' }, + standardDev: { name: 'standard_dev', detail: 'The standard deviation of the distribution.' }, + cumulative: { name: 'cumulative', detail: 'A logical value that determines the form of the function. If cumulative is TRUE, LOGNORM.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.' }, }, }, LOGNORM_INV: { @@ -874,8 +880,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: 'probability', detail: 'A probability corresponding to the lognormal distribution.' }, + mean: { name: 'mean', detail: 'The arithmetic mean of the distribution.' }, + standardDev: { name: 'standard_dev', detail: 'The standard deviation of the distribution.' }, }, }, MAX: { @@ -939,8 +946,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: 'number1', detail: 'The first number, cell reference, or range for which you want the given numbers.' }, + number2: { name: 'number2', detail: 'Additional numbers, cell references or ranges for which you want the given numbers, up to a maximum of 255.' }, }, }, MIN: { @@ -1004,8 +1011,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: 'number1', detail: 'The first number, cell reference, or range for which you want calculate the mode.' }, + number2: { name: 'number2', detail: 'Additional numbers, cell references or ranges for which you want calculate the mode, up to a maximum of 255.' }, }, }, MODE_SNGL: { @@ -1018,8 +1025,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: 'number1', detail: 'The first number, cell reference, or range for which you want calculate the mode.' }, + number2: { name: 'number2', detail: 'Additional numbers, cell references or ranges for which you want calculate the mode, up to a maximum of 255.' }, }, }, NEGBINOM_DIST: { @@ -1032,8 +1039,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + numberF: { name: 'number_f', detail: 'The number of failures.' }, + numberS: { name: 'number_s', detail: 'The threshold number of successes.' }, + probabilityS: { name: 'probability_s', detail: 'The probability of a success.' }, + cumulative: { name: 'cumulative', detail: 'A logical value that determines the form of the function. If cumulative is TRUE, NEGBINOM.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.' }, }, }, NORM_DIST: { @@ -1104,13 +1113,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: 'array1', detail: 'The dependent array or range of data.' }, + array2: { name: 'array2', detail: 'The independent array or range of data.' }, }, }, PERCENTILE_EXC: { - description: 'Returns the k-th percentile of values in a range, where k is in the range 0..1, exclusive', - abstract: 'Returns the k-th percentile of values in a range, where k is in the range 0..1, exclusive', + description: 'Returns the k-th percentile of values in a data set (Excludes 0 and 1).', + abstract: 'Returns the k-th percentile of values in a data set (Excludes 0 and 1).', links: [ { title: 'Instruction', @@ -1118,13 +1127,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: 'array', detail: 'The array or range of data that defines relative standing.' }, + k: { name: 'k', detail: 'The percentile value in the range 0 and 1 (Excludes 0 and 1).' }, }, }, PERCENTILE_INC: { - description: 'Returns the k-th percentile of values in a range', - abstract: 'Returns the k-th percentile of values in a range', + description: 'Returns the k-th percentile of values in a data set (Includes 0 and 1)', + abstract: 'Returns the k-th percentile of values in a data set (Includes 0 and 1)', links: [ { title: 'Instruction', @@ -1132,13 +1141,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: 'array', detail: 'The array or range of data that defines relative standing.' }, + k: { name: 'k', detail: 'The percentile value in the range 0 and 1 (Includes 0 and 1).' }, }, }, PERCENTRANK_EXC: { - description: 'Returns the rank of a value in a data set as a percentage (0..1, exclusive) of the data set', - abstract: 'Returns the rank of a value in a data set as a percentage (0..1, exclusive) of the data set', + description: 'Returns the percentage rank of a value in a data set (Excludes 0 and 1)', + abstract: 'Returns the percentage rank of a value in a data set (Excludes 0 and 1)', links: [ { title: 'Instruction', @@ -1146,13 +1155,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: 'array', detail: 'The array or range of data that defines relative standing.' }, + x: { name: 'x', detail: 'The value for which you want to know the rank.' }, + significance: { name: 'significance', detail: 'A value that identifies the number of significant digits for the returned percentage value. If omitted, PERCENTRANK.EXC uses three digits (0.xxx).' }, }, }, PERCENTRANK_INC: { - description: 'Returns the percentage rank of a value in a data set', - abstract: 'Returns the percentage rank of a value in a data set', + description: 'Returns the percentage rank of a value in a data set (Includes 0 and 1)', + abstract: 'Returns the percentage rank of a value in a data set (Includes 0 and 1)', links: [ { title: 'Instruction', @@ -1160,8 +1170,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: 'array', detail: 'The array or range of data that defines relative standing.' }, + x: { name: 'x', detail: 'The value for which you want to know the rank.' }, + significance: { name: 'significance', detail: 'A value that identifies the number of significant digits for the returned percentage value. If omitted, PERCENTRANK.INC uses three digits (0.xxx).' }, }, }, PERMUT: { @@ -1174,8 +1185,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number: { name: 'number', detail: 'The number of items.' }, + numberChosen: { name: 'number_chosen', detail: 'The number of items in each permutations.' }, }, }, PERMUTATIONA: { @@ -1188,8 +1199,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number: { name: 'number', detail: 'The number of items.' }, + numberChosen: { name: 'number_chosen', detail: 'The number of items in each permutations.' }, }, }, PHI: { @@ -1202,8 +1213,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'X is the number for which you want the density of the standard normal distribution.' }, }, }, POISSON_DIST: { @@ -1216,8 +1226,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'The value for which you want the distribution.' }, + mean: { name: 'mean', detail: 'The arithmetic mean of the distribution.' }, + cumulative: { name: 'cumulative', detail: 'A logical value that determines the form of the function. If cumulative is TRUE, POISSON.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.' }, }, }, PROB: { @@ -1230,13 +1241,15 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + xRange: { name: 'x_range', detail: 'The range of numeric values of x with which there are associated probabilities.' }, + probRange: { name: 'prob_range', detail: 'A set of probabilities associated with values in x_range.' }, + lowerLimit: { name: 'lower_limit', detail: 'The lower bound on the value for which you want a probability.' }, + upperLimit: { name: 'upper_limit', detail: 'The upper bound on the value for which you want a probability.' }, }, }, QUARTILE_EXC: { - description: 'Returns the quartile of the data set, based on percentile values from 0..1, exclusive', - abstract: 'Returns the quartile of the data set, based on percentile values from 0..1, exclusive', + description: 'Returns the quartile of a data set (Excludes 0 and 1)', + abstract: 'Returns the quartile of a data set (Excludes 0 and 1)', links: [ { title: 'Instruction', @@ -1244,13 +1257,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: 'array', detail: 'The array or range of data for which you want quartile values.' }, + quart: { name: 'quart', detail: 'The quartile value to return.' }, }, }, QUARTILE_INC: { - description: 'Returns the quartile of a data set', - abstract: 'Returns the quartile of a data set', + description: 'Returns the quartile of a data set (Includes 0 and 1)', + abstract: 'Returns the quartile of a data set (Includes 0 and 1)', links: [ { title: 'Instruction', @@ -1258,8 +1271,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: 'array', detail: 'The array or range of data for which you want quartile values.' }, + quart: { name: 'quart', detail: 'The quartile value to return.' }, }, }, RANK_AVG: { @@ -1302,8 +1315,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: 'array1', detail: 'The dependent array or range of data.' }, + array2: { name: 'array2', detail: 'The independent array or range of data.' }, }, }, SKEW: { @@ -1316,13 +1329,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: 'number1', detail: 'The first number, cell reference, or range for which you want the skewness.' }, + number2: { name: 'number2', detail: 'Additional numbers, cell references or ranges for which you want the skewness, up to a maximum of 255.' }, }, }, SKEW_P: { - description: 'Returns the skewness of a distribution based on a population: a characterization of the degree of asymmetry of a distribution around its mean', - abstract: 'Returns the skewness of a distribution based on a population: a characterization of the degree of asymmetry of a distribution around its mean', + description: 'Returns the skewness of a distribution based on a population', + abstract: 'Returns the skewness of a distribution based on a population', links: [ { title: 'Instruction', @@ -1330,8 +1343,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: 'number1', detail: 'The first number, cell reference, or range for which you want the skewness.' }, + number2: { name: 'number2', detail: 'Additional numbers, cell references or ranges for which you want the skewness, up to a maximum of 255.' }, }, }, SLOPE: { @@ -1344,8 +1357,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + knownYs: { name: "known_y's", detail: 'The dependent array or range of data.' }, + knownXs: { name: "known_x's", detail: 'The independent array or range of data.' }, }, }, SMALL: { @@ -1358,8 +1371,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: 'array', detail: 'The array or range of data for which you want to determine the k-th smallest value.' }, + k: { name: 'k', detail: 'The position (from the smallest) in the array or cell range of data to return.' }, }, }, STANDARDIZE: { @@ -1372,8 +1385,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'The value you want to normalize.' }, + mean: { name: 'mean', detail: 'The arithmetic mean of the distribution.' }, + standardDev: { name: 'standard_dev', detail: 'The standard deviation of the distribution.' }, }, }, STDEV_P: { @@ -1442,13 +1456,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + knownYs: { name: "known_y's", detail: 'The dependent array or range of data.' }, + knownXs: { name: "known_x's", detail: 'The independent array or range of data.' }, }, }, T_DIST: { - description: 'Returns the Percentage Points (probability) for the Student t-distribution', - abstract: 'Returns the Percentage Points (probability) for the Student t-distribution', + description: 'Returns the probability for the Student t-distribution', + abstract: 'Returns the probability for the Student t-distribution', links: [ { title: 'Instruction', @@ -1456,13 +1470,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'The numeric value at which to evaluate the distribution' }, + degFreedom: { name: 'degFreedom', detail: 'An integer indicating the number of degrees of freedom.' }, + cumulative: { name: 'cumulative', detail: 'A logical value that determines the form of the function. If cumulative is TRUE, T.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.' }, }, }, T_DIST_2T: { - description: 'Returns the Percentage Points (probability) for the Student t-distribution', - abstract: 'Returns the Percentage Points (probability) for the Student t-distribution', + description: 'Returns the probability for the Student t-distribution (two-tailed)', + abstract: 'Returns the probability for the Student t-distribution (two-tailed)', links: [ { title: 'Instruction', @@ -1470,13 +1485,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'The numeric value at which to evaluate the distribution' }, + degFreedom: { name: 'degFreedom', detail: 'An integer indicating the number of degrees of freedom.' }, }, }, T_DIST_RT: { - description: 'Returns the Student\'s t-distribution', - abstract: 'Returns the Student\'s t-distribution', + description: 'Returns the probability for the Student t-distribution (right-tailed)', + abstract: 'Returns the probability for the Student t-distribution (right-tailed)', links: [ { title: 'Instruction', @@ -1484,13 +1499,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'The numeric value at which to evaluate the distribution' }, + degFreedom: { name: 'degFreedom', detail: 'An integer indicating the number of degrees of freedom.' }, }, }, T_INV: { - description: 'Returns the t-value of the Student\'s t-distribution as a function of the probability and the degrees of freedom', - abstract: 'Returns the t-value of the Student\'s t-distribution as a function of the probability and the degrees of freedom', + description: 'Returns the inverse of the probability for the Student t-distribution', + abstract: 'Returns the inverse of the probability for the Student t-distribution', links: [ { title: 'Instruction', @@ -1498,13 +1513,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: 'probability', detail: 'The probability associated with the Student\'s t-distribution.' }, + degFreedom: { name: 'degFreedom', detail: 'An integer indicating the number of degrees of freedom.' }, }, }, T_INV_2T: { - description: 'Returns the inverse of the Student\'s t-distribution', - abstract: 'Returns the inverse of the Student\'s t-distribution', + description: 'Returns the inverse of the probability for the Student t-distribution (two-tailed)', + abstract: 'Returns the inverse of the probability for the Student t-distribution (two-tailed)', links: [ { title: 'Instruction', @@ -1512,8 +1527,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: 'probability', detail: 'The probability associated with the Student\'s t-distribution.' }, + degFreedom: { name: 'degFreedom', detail: 'An integer indicating the number of degrees of freedom.' }, }, }, T_TEST: { @@ -1526,8 +1541,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: 'array1', detail: 'The first array or range of data.' }, + array2: { name: 'array2', detail: 'The second array or range of data.' }, + tails: { name: 'tails', detail: 'Specifies the number of distribution tails. If tails = 1, T.TEST uses the one-tailed distribution. If tails = 2, T.TEST uses the two-tailed distribution.' }, + type: { name: 'type', detail: 'The kind of t-Test to perform.' }, }, }, TREND: { @@ -1554,8 +1571,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: 'array', detail: 'The array or range of values to trim and average.' }, + percent: { name: 'percent', detail: 'The fractional number of data points to exclude from the calculation.' }, }, }, VAR_P: { @@ -1624,8 +1641,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'The value for which you want the distribution.' }, + alpha: { name: 'alpha', detail: 'A parameter of the distribution.' }, + beta: { name: 'beta', detail: 'A parameter of the distribution.' }, + cumulative: { name: 'cumulative', detail: 'A logical value that determines the form of the function. If cumulative is TRUE, WEIBULL.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.' }, }, }, Z_TEST: { @@ -1638,8 +1657,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: 'array', detail: 'The array or range of data against which to test x.' }, + x: { name: 'x', detail: 'The value to test.' }, + sigma: { name: 'sigma', detail: 'The population (known) standard deviation. If omitted, the sample standard deviation is used.' }, }, }, }; diff --git a/packages/sheets-formula-ui/src/locale/function-list/statistical/ja-JP.ts b/packages/sheets-formula-ui/src/locale/function-list/statistical/ja-JP.ts index 886b90613b0e..fa85336e8a84 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/statistical/ja-JP.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/statistical/ja-JP.ts @@ -611,8 +611,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + dataArray: { name: 'データ配列', detail: '頻度分布の計算対象となる値セットの配列、またはこのセットへの参照を指定します。 データ配列に値が含まれていない場合は、0 の配列が返されます。' }, + binsArray: { name: '区間配列', detail: '区間配列の値をグループ化する間隔の配列、またはこの間隔への参照を指定します。 区間配列に値が含まれていない場合は、データ配列に指定した要素の数が返されます。' }, }, }, GAMMA: { @@ -625,8 +625,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number: { name: '数値', detail: 'ガンマ関数の入力値。' }, }, }, GAMMA_DIST: { @@ -639,8 +638,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '関数に代入する値を指定します。' }, + alpha: { name: 'alpha', detail: '分布の最初のパラメータ。' }, + beta: { name: 'beta', detail: '分布の 2 番目のパラメーター。' }, + cumulative: { name: '累積', detail: '計算に使用する関数の形式を論理値で指定します。 関数形式に TRUE を指定すると累積分布関数の値が計算され、FALSE を指定すると確率密度関数の値が計算されます。' }, }, }, GAMMA_INV: { @@ -653,8 +654,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '確率', detail: 'ガンマ分布における確率を指定します。' }, + alpha: { name: 'alpha', detail: '分布の最初のパラメータ。' }, + beta: { name: 'beta', detail: '分布の 2 番目のパラメーター。' }, }, }, GAMMALN: { @@ -667,8 +669,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'GAMMALN 関数に代入する値を指定します。' }, }, }, GAMMALN_PRECISE: { @@ -681,8 +682,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'GAMMALN.PRECISE 関数に代入する値を指定します。' }, }, }, GAUSS: { @@ -695,8 +695,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + z: { name: 'z', detail: '関数に代入する値を指定します。' }, }, }, GEOMEAN: { @@ -709,8 +708,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数値 1', detail: '相乗平均を求める 1 つ目の数値、セル参照、またはセル範囲を指定します。' }, + number2: { name: '数値 2', detail: '相乗平均を求める追加の数値、セル参照、または範囲 (最大 255)。' }, }, }, GROWTH: { @@ -723,8 +722,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + knownYs: { name: '既知の y', detail: '既にわかっている y の値の系列であり、y = b*m^x という関係が成り立ちます。' }, + knownXs: { name: '既知の x', detail: '既にわかっている x の値の系列であり、y = b*m^x という関係が成り立ちます。' }, + newXs: { name: '新しい x', detail: 'GROWTH 関数を利用して、対応する y の値を計算する新しい x の値を指定します。' }, + constb: { name: 'b', detail: '定数 b を 1 にするかどうかを論理値で指定します。' }, }, }, HARMEAN: { @@ -737,8 +738,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数値 1', detail: '調和平均を求める 1 つ目の数値、セル参照、またはセル範囲を指定します。' }, + number2: { name: '数値 2', detail: '調和平均を求める追加の数値、セル参照、または範囲 (最大 255)。' }, }, }, HYPGEOM_DIST: { @@ -751,8 +752,11 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + sampleS: { name: '標本の成功数', detail: '標本内で成功する数を指定します。' }, + numberSample: { name: '標本数', detail: '標本数を指定します。' }, + populationS: { name: '母集団の成功数', detail: '母集団内で成功する数を指定します。' }, + numberPop: { name: '母集団の大きさ', detail: '母集団全体の数を指定します。' }, + cumulative: { name: '累積', detail: '計算に使用する関数の形式を論理値で指定します。 関数形式に TRUE を指定すると累積分布関数の値が計算され、FALSE を指定すると確率密度関数の値が計算されます。' }, }, }, INTERCEPT: { @@ -779,8 +783,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数値 1', detail: '尖度を求める 1 つ目の数値、セル参照、またはセル範囲を指定します。' }, + number2: { name: '数値 2', detail: '尖度を求める追加の数値、セル参照、または範囲 (最大 255)。' }, }, }, LARGE: { @@ -793,8 +797,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '配列', detail: '抽出の対象となるデータが入力されているセル範囲または配列を指定します。' }, + k: { name: 'k', detail: '抽出する値の、大きい方から数えた順位を数値で指定します。' }, }, }, LINEST: { @@ -835,13 +839,15 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '関数に代入する値を指定します。' }, + mean: { name: '平均', detail: '対象となる分布の算術平均 (相加平均) を指定します。' }, + standardDev: { name: '標準偏差', detail: '対象となる分布の標準偏差を指定します。' }, + cumulative: { name: '累積', detail: '計算に使用する関数の形式を論理値で指定します。 関数形式に TRUE を指定すると累積分布関数の値が計算され、FALSE を指定すると確率密度関数の値が計算されます。' }, }, }, LOGNORM_INV: { - description: '対数正規型の累積分布関数の逆関数値を返します。', - abstract: '対数正規型の累積分布関数の逆関数値を返します。', + description: '対数正規分布の累積分布関数の逆関数値を返します。', + abstract: '対数正規分布の累積分布関数の逆関数値を返します。', links: [ { title: '指導', @@ -849,8 +855,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '確率', detail: '対数正規分布における確率を指定します。' }, + mean: { name: '平均', detail: '対象となる分布の算術平均 (相加平均) を指定します。' }, + standardDev: { name: '標準偏差', detail: '対象となる分布の標準偏差を指定します。' }, }, }, MAX: { @@ -908,8 +915,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数値 1', detail: '中央値を求める 1 つ目の数値、セル参照、またはセル範囲を指定します。' }, + number2: { name: '数値 2', detail: '中央値を求める追加の数値、セル参照、または範囲 (最大 255)。' }, }, }, MIN: { @@ -967,8 +974,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数値 1', detail: '最頻値を求める 1 つ目の数値、セル参照、またはセル範囲を指定します。' }, + number2: { name: '数値 2', detail: '最頻値を求める追加の数値、セル参照、または範囲 (最大 255)。' }, }, }, MODE_SNGL: { @@ -981,8 +988,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数値 1', detail: '最頻値を求める 1 つ目の数値、セル参照、またはセル範囲を指定します。' }, + number2: { name: '数値 2', detail: '最頻値を求める追加の数値、セル参照、または範囲 (最大 255)。' }, }, }, NEGBINOM_DIST: { @@ -995,8 +1002,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + numberF: { name: '失敗数', detail: '試行が失敗する回数を指定します。' }, + numberS: { name: '成功数', detail: '分析のしきい値となる、試行が成功する回数を指定します。' }, + probabilityS: { name: '成功率', detail: '試行が成功する確率を指定します。' }, + cumulative: { name: '累積', detail: '計算に使用する関数の形式を論理値で指定します。 関数形式に TRUE を指定すると累積分布関数の値が計算され、FALSE を指定すると確率密度関数の値が計算されます。' }, }, }, NORM_DIST: { @@ -1067,13 +1076,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: '配列 1', detail: '複数の従属変数の値が入力されているセル範囲または配列を指定します。' }, + array2: { name: '配列 2', detail: '複数の独立変数の値が入力されているセル範囲または配列を指定します。' }, }, }, PERCENTILE_EXC: { - description: '特定の範囲に含まれるデータの第 k 百分位数に当たる値を返します (k は 0 より大きく 1 より小さい値)。', - abstract: '特定の範囲に含まれるデータの第 k 百分位数に当たる値を返します (k は 0 より大きく 1 より小さい値)。', + description: '配列内での第 k 百分位数に当たる値を返します (0と1は含まれません)。', + abstract: '配列内での第 k 百分位数に当たる値を返します (0と1は含まれません)。', links: [ { title: '指導', @@ -1081,13 +1090,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '配列', detail: '相対的な位置を決定するデータの配列またはセル範囲を指定します。' }, + k: { name: 'k', detail: '0 から 1 (0と1は含まれません)までのパーセント値。' }, }, }, PERCENTILE_INC: { - description: '特定の範囲に含まれるデータの第 k 百分位数に当たる値を返します。', - abstract: '特定の範囲に含まれるデータの第 k 百分位数に当たる値を返します。', + description: '配列内での第 k 百分位数に当たる値を返します (0と1が含まれています)。', + abstract: '配列内での第 k 百分位数に当たる値を返します (0と1が含まれています)。', links: [ { title: '指導', @@ -1095,13 +1104,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '配列', detail: '相対的な位置を決定するデータの配列またはセル範囲を指定します。' }, + k: { name: 'k', detail: '0 から 1 (0と1が含まれています)までのパーセント値。' }, }, }, PERCENTRANK_EXC: { - description: '配列内での値の順位を百分率 (0 より大きく 1 より小さい) で表した値を返します。', - abstract: '配列内での値の順位を百分率 (0 より大きく 1 より小さい) で表した値を返します。', + description: '配列内での値の順位を百分率で表した値を返します (0と1は含まれません)。', + abstract: '配列内での値の順位を百分率で表した値を返します (0と1は含まれません)。', links: [ { title: '指導', @@ -1109,13 +1118,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '配列', detail: '相対的な位置を決定するデータの配列またはセル範囲を指定します。' }, + x: { name: 'x', detail: 'ランクを調べる値を指定します。' }, + significance: { name: '有効桁数', detail: '計算結果として返される百分率の有効桁数を指定します。 有効桁数を省略すると、小数点以下第 3 位 (0.xxx) まで計算されます。' }, }, }, PERCENTRANK_INC: { - description: '配列内での値の順位を百分率で表した値を返します。', - abstract: '配列内での値の順位を百分率で表した値を返します。', + description: '配列内での値の順位を百分率で表した値を返します (0と1が含まれています)。', + abstract: '配列内での値の順位を百分率で表した値を返します (0と1が含まれています)。', links: [ { title: '指導', @@ -1123,8 +1133,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '配列', detail: '相対的な位置を決定するデータの配列またはセル範囲を指定します。' }, + x: { name: 'x', detail: 'ランクを調べる値を指定します。' }, + significance: { name: '有効桁数', detail: '計算結果として返される百分率の有効桁数を指定します。 有効桁数を省略すると、小数点以下第 3 位 (0.xxx) まで計算されます。' }, }, }, PERMUT: { @@ -1137,8 +1148,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number: { name: '総数', detail: '抜き取る対象の全体の数を指定します。' }, + numberChosen: { name: '抜き取り数', detail: '抜き取る順列わせ 1 組に含まれる項目の数を指定します。' }, }, }, PERMUTATIONA: { @@ -1151,8 +1162,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number: { name: '総数', detail: '抜き取る対象の全体の数を指定します。' }, + numberChosen: { name: '抜き取り数', detail: '抜き取る順列わせ 1 組に含まれる項目の数を指定します。' }, }, }, PHI: { @@ -1165,8 +1176,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '標準正規分布の密度を求める数値を指定します。' }, }, }, POISSON_DIST: { @@ -1179,8 +1189,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '関数に代入する値を指定します。' }, + mean: { name: '平均', detail: '対象となる分布の算術平均 (相加平均) を指定します。' }, + cumulative: { name: '累積', detail: '計算に使用する関数の形式を論理値で指定します。 関数形式に TRUE を指定すると累積分布関数の値が計算され、FALSE を指定すると確率密度関数の値が計算されます。' }, }, }, PROB: { @@ -1193,13 +1204,15 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + xRange: { name: '数値', detail: 'それぞれの確率値を含む数値範囲。' }, + probRange: { name: '確率', detail: '数値に関連付けられた確率値のセット。' }, + lowerLimit: { name: '下限', detail: '確率が計算される数値の下限。' }, + upperLimit: { name: '上限', detail: '確率が計算される数値の上限。' }, }, }, QUARTILE_EXC: { - description: '0 より大きく 1 より小さい百分位値に基づいて、配列に含まれるデータから四分位数を返します。', - abstract: '0 より大きく 1 より小さい百分位値に基づいて、配列に含まれるデータから四分位数を返します。', + description: 'データセットの四分位数を返します (0と1は含まれません)。', + abstract: 'データセットの四分位数を返します (0と1は含まれません)。', links: [ { title: '指導', @@ -1207,13 +1220,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '配列', detail: '四分位値を必要とする配列またはデータ範囲。' }, + quart: { name: '四分位値', detail: '返す四分位値。' }, }, }, QUARTILE_INC: { - description: '配列に含まれるデータから四分位数を抽出します。', - abstract: '配列に含まれるデータから四分位数を抽出します。', + description: 'データセットの四分位数を返します (0と1が含まれています)。', + abstract: 'データセットの四分位数を返します (0と1が含まれています)。', links: [ { title: '指導', @@ -1221,8 +1234,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '配列', detail: '四分位値を必要とする配列またはデータ範囲。' }, + quart: { name: '四分位値', detail: '返す四分位値。' }, }, }, RANK_AVG: { @@ -1265,8 +1278,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: '配列 1', detail: '複数の従属変数の値が入力されているセル範囲または配列を指定します。' }, + array2: { name: '配列 2', detail: '複数の独立変数の値が入力されているセル範囲または配列を指定します。' }, }, }, SKEW: { @@ -1279,13 +1292,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数値 1', detail: '歪度を求める 1 つ目の数値、セル参照、またはセル範囲を指定します。' }, + number2: { name: '数値 2', detail: '歪度を求める追加の数値、セル参照、または範囲 (最大 255)。' }, }, }, SKEW_P: { - description: '人口に基づく分布の歪度を返します。歪度とは、分布の平均値周辺での両側の非対称度を表す値です。', - abstract: '人口に基づく分布の歪度を返します。歪度とは、分布の平均値周辺での両側の非対称度を表す値です。', + description: 'サンプル母集団に基づいて分布の歪度を返します。', + abstract: 'サンプル母集団に基づいて分布の歪度を返します。', links: [ { title: '指導', @@ -1293,8 +1306,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数値 1', detail: '歪度を求める 1 つ目の数値、セル参照、またはセル範囲を指定します。' }, + number2: { name: '数値 2', detail: '歪度を求める追加の数値、セル参照、または範囲 (最大 255)。' }, }, }, SLOPE: { @@ -1307,8 +1320,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + knownYs: { name: '既知の y', detail: '既知の従属変数の値が入力されているセル範囲または配列を指定します。' }, + knownXs: { name: '既知の x', detail: '既知の独立変数の値が入力されているセル範囲または配列を指定します。' }, }, }, SMALL: { @@ -1321,8 +1334,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '配列', detail: '抽出の対象となるデータが入力されているセル範囲または配列を指定します。' }, + k: { name: 'k', detail: '抽出する値の小さい方から数えた順位を数値で指定します。' }, }, }, STANDARDIZE: { @@ -1335,8 +1348,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '関数に代入する値を指定します。' }, + mean: { name: '平均', detail: '対象となる分布の算術平均 (相加平均) を指定します。' }, + standardDev: { name: '標準偏差', detail: '対象となる分布の標準偏差を指定します。' }, }, }, STDEV_P: { @@ -1405,13 +1419,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + knownYs: { name: '既知の y', detail: '既知の従属変数の値が入力されているセル範囲または配列を指定します。' }, + knownXs: { name: '既知の x', detail: '既知の独立変数の値が入力されているセル範囲または配列を指定します。' }, }, }, T_DIST: { - description: 'スチューデントの t 分布のパーセンテージ (確率) を返します。', - abstract: 'スチューデントの t 分布のパーセンテージ (確率) を返します。', + description: 'スチューデントの t 確率分布を返します。', + abstract: 'スチューデントの t 確率分布を返します。', links: [ { title: '指導', @@ -1419,13 +1433,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '分布の数値を計算する必要があります。' }, + degFreedom: { name: '自由度', detail: '自由度の数を表す整数。' }, + cumulative: { name: '累積', detail: '計算に使用する関数の形式を論理値で指定します。 関数形式に TRUE を指定すると累積分布関数の値が計算され、FALSE を指定すると確率密度関数の値が計算されます。' }, }, }, T_DIST_2T: { - description: 'スチューデントの t 分布のパーセンテージ (確率) を返します。', - abstract: 'スチューデントの t 分布のパーセンテージ (確率) を返します。', + description: 'スチューデントの t 確率分布 (両側) を返します。', + abstract: 'スチューデントの t 確率分布 (両側) を返します。', links: [ { title: '指導', @@ -1433,13 +1448,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '分布の数値を計算する必要があります。' }, + degFreedom: { name: '自由度', detail: '自由度の数を表す整数。' }, }, }, T_DIST_RT: { - description: 'スチューデントの t 分布の値を返します。', - abstract: 'スチューデントの t 分布の値を返します。', + description: 'スチューデントの t 確率分布 (右側) を返します。', + abstract: 'スチューデントの t 確率分布 (右側) を返します。', links: [ { title: '指導', @@ -1447,13 +1462,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '分布の数値を計算する必要があります。' }, + degFreedom: { name: '自由度', detail: '自由度の数を表す整数。' }, }, }, T_INV: { - description: 'スチューデントの t 分布の t 値を、確率と自由度の関数として返します。', - abstract: 'スチューデントの t 分布の t 値を、確率と自由度の関数として返します。', + description: 'スチューデントの t 確率分布の逆関数値を返します。', + abstract: 'スチューデントの t 確率分布の逆関数値を返します。', links: [ { title: '指導', @@ -1461,13 +1476,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '確率', detail: 'スチューデントの t 分布に従う確率を指定します。' }, + degFreedom: { name: '自由度', detail: '自由度の数を表す整数。' }, }, }, T_INV_2T: { - description: 'スチューデントの t 分布の逆関数値を返します。', - abstract: 'スチューデントの t 分布の逆関数値を返します。', + description: 'スチューデントの t 確率分布 (両側) の逆関数値を返します。', + abstract: 'スチューデントの t 確率分布 (両側) の逆関数値を返します。', links: [ { title: '指導', @@ -1475,8 +1490,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '確率', detail: 'スチューデントの t 分布に従う確率を指定します。' }, + degFreedom: { name: '自由度', detail: '自由度の数を表す整数。' }, }, }, T_TEST: { @@ -1489,8 +1504,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: '配列1', detail: '比較対象となる一方のデータを含む配列またはセル範囲を指定します。' }, + array2: { name: '配列2', detail: '比較対象となるもう一方のデータを含む配列またはセル範囲を指定します。' }, + tails: { name: '尾部の特性', detail: '片側分布を計算するか、両側分布を計算するかを、数値で指定します。 尾部に 1 を指定すると片側分布の値が計算されます。 尾部に 2 を指定すると両側分布の値が計算されます。' }, + type: { name: '検定の種類', detail: '実行する t 検定の種類を数値で指定します。' }, }, }, TREND: { @@ -1517,8 +1534,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '配列', detail: '対象となる値の配列または範囲。' }, + percent: { name: '割合', detail: '計算から排除する端数のデータ ポイント数。' }, }, }, VAR_P: { @@ -1587,8 +1604,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '関数に代入する値を指定します。' }, + alpha: { name: 'alpha', detail: '分布の最初のパラメータ。' }, + beta: { name: 'beta', detail: '分布の 2 番目のパラメーター。' }, + cumulative: { name: '累積', detail: '計算に使用する関数の形式を論理値で指定します。 関数形式に TRUE を指定すると累積分布関数の値が計算され、FALSE を指定すると確率密度関数の値が計算されます。' }, }, }, Z_TEST: { @@ -1601,8 +1620,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '配列', detail: 'x の検定対象となるデータを含む数値配列またはセル範囲を指定します。' }, + x: { name: 'x', detail: '検定する値を指定します。' }, + sigma: { name: '標準偏差', detail: '母集団全体に基づく標準偏差を指定します。 省略すると、標本に基づく標準偏差が使用されます。' }, }, }, }; diff --git a/packages/sheets-formula-ui/src/locale/function-list/statistical/vi-VN.ts b/packages/sheets-formula-ui/src/locale/function-list/statistical/vi-VN.ts index eb46dd9026cb..2a31a872a3cd 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/statistical/vi-VN.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/statistical/vi-VN.ts @@ -558,6 +558,164 @@ export default { knownXs: { name: 'mảng _x', detail: 'Mảng độc lập của mảng hoặc phạm vi dữ liệu.' }, }, }, + FREQUENCY: { + description: '以垂直数组的形式返回频率分布', + abstract: '以垂直数组的形式返回频率分布', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/frequency-%E5%87%BD%E6%95%B0-44e3be2b-eca0-42cd-a3f7-fd9ea898fdb9', + }, + ], + functionParameter: { + dataArray: { name: 'dữ liệuMảng', detail: 'Một mảng hoặc tham chiếu tới một tập giá trị mà bạn muốn đếm tần suất của nó. Nếu data_array không chứa giá trị, thì hàm FREQUENCY trả về mảng các số không.' }, + binsArray: { name: 'mảng ngắt quãng', detail: 'Mảng hoặc tham chiếu tới các khoảng mà bạn muốn nhóm các giá trị trong data_array vào trong đó. Nếu bins_array không chứa giá trị, thì hàm FREQUENCY trả về số thành phần trong data_array.' }, + }, + }, + GAMMA: { + description: 'Trả về giá trị hàm gamma.', + abstract: 'Trả về giá trị hàm gamma.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/gamma-%E5%87%BD%E6%95%B0-ce1702b1-cf55-471d-8307-f83be0fc5297', + }, + ], + functionParameter: { + number: { name: 'số', detail: 'Giá trị đầu vào của hàm gamma.' }, + }, + }, + GAMMA_DIST: { + description: 'Trả về phân bố gamma.', + abstract: 'Trả về phân bố gamma.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/gamma-dist-%E5%87%BD%E6%95%B0-9b6f1538-d11c-4d5f-8966-21f6a2201def', + }, + ], + functionParameter: { + x: { name: 'x', detail: 'Giá trị mà bạn muốn có phân bố của nó.' }, + alpha: { name: 'alpha', detail: 'Tham số đầu tiên của phân phối.' }, + beta: { name: 'beta', detail: 'Tham số thứ hai của phân phối.' }, + cumulative: { name: 'tích lũy', detail: 'Một giá trị lô-gic quyết định dạng thức của hàm. Nếu tích lũy là TRUE, hàm GAMMA.DIST trả về hàm phân bố tích lũy; nếu FALSE, nó trả về hàm mật độ xác suất.' }, + }, + }, + GAMMA_INV: { + description: 'Trả về giá trị đảo của phân bố lũy tích gamma.', + abstract: 'Trả về giá trị đảo của phân bố lũy tích gamma.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/gamma-inv-%E5%87%BD%E6%95%B0-74991443-c2b0-4be5-aaab-1aa4d71fbb18', + }, + ], + functionParameter: { + probability: { name: 'xác suất', detail: 'Xác suất gắn với phân bố gamma.' }, + alpha: { name: 'alpha', detail: 'Tham số đầu tiên của phân phối.' }, + beta: { name: 'beta', detail: 'Tham số thứ hai của phân phối.' }, + }, + }, + GAMMALN: { + description: 'Trả về lô-ga-rít tự nhiên của hàm gamma, Γ(x).', + abstract: 'Trả về lô-ga-rít tự nhiên của hàm gamma, Γ(x).', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/gammaln-%E5%87%BD%E6%95%B0-b838c48b-c65f-484f-9e1d-141c55470eb9', + }, + ], + functionParameter: { + x: { name: 'x', detail: 'Giá trị mà bạn muốn tính toán GAMMALN.' }, + }, + }, + GAMMALN_PRECISE: { + description: 'Trả về lô-ga-rít tự nhiên của hàm gamma, Γ(x).', + abstract: 'Trả về lô-ga-rít tự nhiên của hàm gamma, Γ(x).', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/gammaln-precise-%E5%87%BD%E6%95%B0-5cdfe601-4e1e-4189-9d74-241ef1caa599', + }, + ], + functionParameter: { + x: { name: 'x', detail: 'Giá trị mà bạn muốn tính toán GAMMALN.PRECISE.' }, + }, + }, + GAUSS: { + description: 'Trả về ít hơn 0.5 so với phân phối tích lũy chuẩn', + abstract: 'Trả về ít hơn 0.5 so với phân phối tích lũy chuẩn', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/gauss-%E5%87%BD%E6%95%B0-069f1b4e-7dee-4d6a-a71f-4b69044a6b33', + }, + ], + functionParameter: { + z: { name: 'z', detail: 'Giá trị mà bạn muốn có phân bố của nó.' }, + }, + }, + GEOMEAN: { + description: 'Trả về giá trị trung bình hình học', + abstract: 'Trả về giá trị trung bình hình học', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/geomean-%E5%87%BD%E6%95%B0-db1ac48d-25a5-40a0-ab83-0b38980e40d5', + }, + ], + functionParameter: { + number1: { name: 'số 1', detail: 'Số đầu tiên, tham chiếu ô hoặc phạm vi ô để tính giá trị trung bình hình học.' }, + number2: { name: 'số 2', detail: 'Tối đa 255 số bổ sung, tham chiếu ô hoặc phạm vi ô để tính giá trị trung bình hình học.' }, + }, + }, + GROWTH: { + description: 'Trả về giá trị xu hướng hàm mũ', + abstract: 'Trả về giá trị xu hướng hàm mũ', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/growth-%E5%87%BD%E6%95%B0-541a91dc-3d5e-437d-b156-21324e68b80d', + }, + ], + functionParameter: { + knownYs: { name: 'dữ liệu đã biết_y', detail: 'Tập giá trị y mà bạn đã biết trong quan hệ y = b*m^x.' }, + knownXs: { name: 'dữ liệu đã biết_x', detail: 'Tập giá trị x mà bạn đã biết trong quan hệ y = b*m^x.' }, + newXs: { name: 'dữ liệu mới_x', detail: 'Là những giá trị x mới mà bạn muốn hàm GROWTH trả về tương ứng với các giá trị y.' }, + constb: { name: 'b', detail: 'Một giá trị lô-gic cho biết có bắt buộc hằng số b phải bằng 1 hay không.' }, + }, + }, + HARMEAN: { + description: 'Trả về giá trị trung bình điều hòa', + abstract: 'Trả về giá trị trung bình điều hòa', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/harmean-%E5%87%BD%E6%95%B0-5efd9184-fab5-42f9-b1d3-57883a1d3bc6', + }, + ], + functionParameter: { + number1: { name: 'số 1', detail: 'Số đầu tiên, tham chiếu ô hoặc phạm vi ô để tính giá trị trung bình điều hòa.' }, + number2: { name: 'số 2', detail: 'Lên đến 255 số bổ sung, tham chiếu ô hoặc phạm vi ô để tính giá trị trung bình hài hòa.' }, + }, + }, + HYPGEOM_DIST: { + description: 'Trả về phân bố siêu bội.', + abstract: 'Trả về phân bố siêu bội.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/hypgeom-dist-%E5%87%BD%E6%95%B0-6dbd547f-1d12-4b1f-8ae5-b0d9e3d22fbf', + }, + ], + functionParameter: { + sampleS: { name: 'Số lần thành công mẫu', detail: 'Số lần thành công trong mẫu.' }, + numberSample: { name: 'Kích thước mẫu', detail: 'Kích thước mẫu.' }, + populationS: { name: 'Tổng số thành công', detail: 'Số lượng thành công trong dân số.' }, + numberPop: { name: 'Kích thước tổng thể', detail: 'Kích thước tổng thể.' }, + cumulative: { name: 'tích lũy', detail: 'Một giá trị lô-gic quyết định dạng thức của hàm. Nếu tích lũy là TRUE, hàm HYPGEOM.DIST trả về hàm phân bố tích lũy; nếu FALSE, nó trả về hàm mật độ xác suất.' }, + }, + }, INTERCEPT: { description: 'Trả về điểm chặn của đường hồi quy tuyến tính', abstract: 'Trả về điểm chặn của đường hồi quy tuyến tính', @@ -572,6 +730,65 @@ export default { knownXs: { name: 'mảng _x', detail: 'Mảng độc lập của mảng hoặc phạm vi dữ liệu.' }, }, }, + KURT: { + description: 'Trả về hệ số nhọn của tập dữ liệu.', + abstract: 'Trả về hệ số nhọn của tập dữ liệu.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/kurt-%E5%87%BD%E6%95%B0-bc3a265c-5da4-4dcb-b7fd-c237789095ab', + }, + ], + functionParameter: { + number1: { name: 'số 1', detail: 'Số, tham chiếu ô hoặc phạm vi ô đầu tiên cần tính giá trị đỉnh.' }, + number2: { name: 'số 2', detail: 'Tối đa 255 số bổ sung, tham chiếu ô hoặc phạm vi ô để tính giá trị đỉnh.' }, + }, + }, + LARGE: { + description: 'Trả về giá trị lớn thứ k của tập dữ liệu.', + abstract: 'Trả về giá trị lớn thứ k của tập dữ liệu.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/large-%E5%87%BD%E6%95%B0-3af0af19-1190-42bb-bb8b-01672ec00a64', + }, + ], + functionParameter: { + array: { name: 'mảng', detail: 'Mảng hoặc phạm vi dữ liệu mà bạn muốn xác định giá trị lớn thứ k trong đó.' }, + k: { name: 'k', detail: 'Vị trí (tính từ lớn nhất) trong mảng hoặc phạm vi ô dữ liệu cần trả về.' }, + }, + }, + LOGNORM_DIST: { + description: 'Trả về phân bố chuẩn lô-ga-rít của', + abstract: 'Trả về phân bố chuẩn lô-ga-rít của', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/lognorm-dist-%E5%87%BD%E6%95%B0-eb60d00b-48a9-4217-be2b-6074aee6b070', + }, + ], + functionParameter: { + x: { name: 'x', detail: 'Giá trị mà bạn muốn có phân bố của nó.' }, + mean: { name: 'trung độ số', detail: 'Trung độ số học của phân phối.' }, + standardDev: { name: 'Độ lệch chuẩn', detail: 'Độ lệch chuẩn của phân phối.' }, + cumulative: { name: 'tích lũy', detail: 'Một giá trị lô-gic quyết định dạng thức của hàm. Nếu lũy tích là ĐÚNG thì LOGNORM.DIST trả về hàm phân bố lũy tích; nếu SAI, nó trả về hàm mật độ xác suất.' }, + }, + }, + LOGNORM_INV: { + description: 'Trả về nghịch đảo của hàm phân bố lô-ga-rit chuẩn lũy tích của', + abstract: 'Trả về nghịch đảo của hàm phân bố lô-ga-rit chuẩn lũy tích của', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/lognorm-inv-%E5%87%BD%E6%95%B0-fe79751a-f1f2-4af8-a0a1-e151b2d4f600', + }, + ], + functionParameter: { + probability: { name: 'xác suất', detail: 'Một xác suất tương ứng với phân bố lô-ga-rit chuẩn.' }, + mean: { name: 'trung độ số', detail: 'Trung độ số học của phân phối.' }, + standardDev: { name: 'Độ lệch chuẩn', detail: 'Độ lệch chuẩn của phân phối.' }, + }, + }, MAX: { description: 'Trả về giá trị lớn nhất trong tập giá trị.', abstract: 'Trả về giá trị lớn nhất trong tập giá trị.', @@ -623,6 +840,20 @@ export default { criteria2: { name: 'tiêu chí 2', detail: 'Điều kiện liên kết bổ sung. Có thể nhập tối đa 127 điều kiện.' }, }, }, + MEDIAN: { + description: 'Trả về số trung vị của các số đã cho.', + abstract: 'Trả về số trung vị của các số đã cho.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/median-%E5%87%BD%E6%95%B0-d0916313-4753-414c-8537-ce85bdd967d2', + }, + ], + functionParameter: { + number1: { name: 'số 1', detail: 'Số đầu tiên, tham chiếu ô hoặc phạm vi ô để tính trung vị.' }, + number2: { name: 'số 2', detail: 'Bạn có thể bao gồm tối đa 255 số bổ sung, tham chiếu ô hoặc phạm vi ô để tính trung vị.' }, + }, + }, MIN: { description: 'Trả về số nhỏ nhất trong tập giá trị.', abstract: 'Trả về số nhỏ nhất trong tập giá trị.', @@ -674,6 +905,50 @@ export default { criteria2: { name: 'tiêu chí 2', detail: 'Điều kiện liên kết bổ sung. Có thể nhập tối đa 127 điều kiện.' }, }, }, + MODE_MULT: { + description: 'Trả về một mảng dọc của các giá trị thường xảy ra nhất, hoặc các giá trị lặp lại trong một mảng hoặc phạm vi dữ liệu.', + abstract: 'Trả về một mảng dọc của các giá trị thường xảy ra nhất, hoặc các giá trị lặp lại trong một mảng hoặc phạm vi dữ liệu.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/mode-mult-%E5%87%BD%E6%95%B0-50fd9464-b2ba-4191-b57a-39446689ae8c', + }, + ], + functionParameter: { + number1: { name: 'số 1', detail: 'Số đầu tiên, tham chiếu ô hoặc phạm vi ô mà chế độ sẽ được tính toán.' }, + number2: { name: 'số 2', detail: 'Tối đa 255 số bổ sung, tham chiếu ô hoặc phạm vi ô để tính chế độ.' }, + }, + }, + MODE_SNGL: { + description: 'Trả về giá trị xuất hiện nhiều nhất trong tập dữ liệu.', + abstract: 'Trả về giá trị xuất hiện nhiều nhất trong tập dữ liệu.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/mode-sngl-%E5%87%BD%E6%95%B0-f1267c16-66c6-4386-959f-8fba5f8bb7f8', + }, + ], + functionParameter: { + number1: { name: 'số 1', detail: 'Số đầu tiên, tham chiếu ô hoặc phạm vi ô mà chế độ sẽ được tính toán.' }, + number2: { name: 'số 2', detail: 'Tối đa 255 số bổ sung, tham chiếu ô hoặc phạm vi ô để tính chế độ.' }, + }, + }, + NEGBINOM_DIST: { + description: 'Trả về phân bố nhị thức âm', + abstract: 'Trả về phân bố nhị thức âm', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/negbinom-dist-%E5%87%BD%E6%95%B0-c8239f89-c2d0-45bd-b6af-172e570f8599', + }, + ], + functionParameter: { + numberF: { name: 'số lần thất bại.', detail: 'Số lần thất bại.' }, + numberS: { name: 'số lần thành công', detail: 'Số ngưỡng thành công.' }, + probabilityS: { name: 'xác suất thành công', detail: 'Xác suất thành công của mỗi phép thử.' }, + cumulative: { name: 'tích lũy', detail: 'Một giá trị lô-gic quyết định dạng thức của hàm. Nếu tích lũy là TRUE, hàm NEGBINOM.DIST trả về hàm phân bố tích lũy; nếu FALSE, nó trả về hàm mật độ xác suất.' }, + }, + }, NORM_DIST: { description: 'Trả về hàm phân phối tích lũy chuẩn', abstract: 'Trả về hàm phân phối tích lũy chuẩn', @@ -732,6 +1007,178 @@ export default { probability: { name: 'xác suất', detail: 'Một xác suất tương ứng với phân bố chuẩn.' }, }, }, + PEARSON: { + description: 'Trả về hệ số tương quan mô-men tích Pearson', + abstract: 'Trả về hệ số tương quan mô-men tích Pearson', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/pearson-%E5%87%BD%E6%95%B0-0c3e30fc-e5af-49c4-808a-3ef66e034c18', + }, + ], + functionParameter: { + array1: { name: 'mảng 1', detail: 'Mảng phụ thuộc của mảng hoặc phạm vi dữ liệu.' }, + array2: { name: 'mảng 2', detail: 'Mảng độc lập của mảng hoặc phạm vi dữ liệu.' }, + }, + }, + PERCENTILE_EXC: { + description: 'Trả về giá trị phân vị thứ k trong tập dữ liệu (loại trừ 0 và 1)', + abstract: 'Trả về giá trị phân vị thứ k trong tập dữ liệu (loại trừ 0 và 1)', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/percentile-exc-%E5%87%BD%E6%95%B0-bbaa7204-e9e1-4010-85bf-c31dc5dce4ba', + }, + ], + functionParameter: { + array: { name: 'mảng', detail: 'Mảng hoặc phạm vi dữ liệu xác định vị trí tương đối.' }, + k: { name: 'k', detail: 'Giá trị phần trăm từ 0 đến 1 (loại trừ 0 và 1).' }, + }, + }, + PERCENTILE_INC: { + description: 'Trả về giá trị phân vị thứ k trong tập dữ liệu (bao gồm 0 và 1)', + abstract: 'Trả về giá trị phân vị thứ k trong tập dữ liệu (bao gồm 0 và 1)', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/percentile-inc-%E5%87%BD%E6%95%B0-680f9539-45eb-410b-9a5e-c1355e5fe2ed', + }, + ], + functionParameter: { + array: { name: 'mảng', detail: 'Mảng hoặc phạm vi dữ liệu xác định vị trí tương đối.' }, + k: { name: 'k', detail: 'Giá trị phần trăm từ 0 đến 1 (bao gồm 0 và 1).' }, + }, + }, + PERCENTRANK_EXC: { + description: 'Trả về thứ hạng phần trăm của các giá trị trong tập dữ liệu (loại trừ 0 và 1)', + abstract: 'Trả về thứ hạng phần trăm của các giá trị trong tập dữ liệu (loại trừ 0 và 1)', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/percentrank-exc-%E5%87%BD%E6%95%B0-d8afee96-b7e2-4a2f-8c01-8fcdedaa6314', + }, + ], + functionParameter: { + array: { name: 'mảng', detail: 'Mảng hoặc phạm vi dữ liệu xác định vị trí tương đối.' }, + x: { name: 'x', detail: 'Giá trị mà bạn muốn biết thứ hạng của nó.' }, + significance: { name: 'chữ số có nghĩa', detail: 'Giá trị xác định số chữ số có nghĩa của giá trị phần trăm trả về. Nếu bỏ qua, hàm PERCENTRANK.EXC dùng ba chữ số (0.xxx).' }, + }, + }, + PERCENTRANK_INC: { + description: 'Trả về thứ hạng phần trăm của các giá trị trong tập dữ liệu (bao gồm 0 và 1)', + abstract: 'Trả về thứ hạng phần trăm của các giá trị trong tập dữ liệu (bao gồm 0 và 1)', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/percentrank-inc-%E5%87%BD%E6%95%B0-149592c9-00c0-49ba-86c1-c1f45b80463a', + }, + ], + functionParameter: { + array: { name: 'mảng', detail: 'Mảng hoặc phạm vi dữ liệu xác định vị trí tương đối.' }, + x: { name: 'x', detail: 'Giá trị mà bạn muốn biết thứ hạng của nó.' }, + significance: { name: 'chữ số có nghĩa', detail: 'Giá trị xác định số chữ số có nghĩa của giá trị phần trăm trả về. Nếu bỏ qua, hàm PERCENTRANK.INC dùng ba chữ số (0.xxx).' }, + }, + }, + PERMUT: { + description: 'Trả về số hoán vị của một số đối tượng nhất định', + abstract: 'Trả về số hoán vị của một số đối tượng nhất định', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/permut-%E5%87%BD%E6%95%B0-3bd1cb9a-2880-41ab-a197-f246a7a602d3', + }, + ], + functionParameter: { + number: { name: 'tổng cộng', detail: 'Số hạng mục.' }, + numberChosen: { name: 'số lượng mẫu', detail: 'Số lượng các mục trong mỗi sự sắp xếp.' }, + }, + }, + PERMUTATIONA: { + description: 'Trả về số hoán vị cho số đối tượng đã cho (với tần suất lặp) có thể được chọn từ tổng số đối tượng.', + abstract: 'Trả về số hoán vị cho số đối tượng đã cho (với tần suất lặp) có thể được chọn từ tổng số đối tượng.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/permutationa-%E5%87%BD%E6%95%B0-6c7d7fdc-d657-44e6-aa19-2857b25cae4e', + }, + ], + functionParameter: { + number: { name: 'tổng cộng', detail: 'Số hạng mục.' }, + numberChosen: { name: 'số lượng mẫu', detail: 'Số lượng các mục trong mỗi sự sắp xếp.' }, + }, + }, + PHI: { + description: 'Trả về giá trị của hàm mật độ cho một phân bố chuẩn chuẩn hóa.', + abstract: 'Trả về giá trị của hàm mật độ cho một phân bố chuẩn chuẩn hóa.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/phi-%E5%87%BD%E6%95%B0-23e49bc6-a8e8-402d-98d3-9ded87f6295c', + }, + ], + functionParameter: { + x: { name: 'x', detail: 'X là số bạn muốn tìm mật độ của phân bố chuẩn chuẩn hóa cho số này.' }, + }, + }, + POISSON_DIST: { + description: 'Trả về phân bố Poisson.', + abstract: 'Trả về phân bố Poisson.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/poisson-dist-%E5%87%BD%E6%95%B0-8fe148ff-39a2-46cb-abf3-7772695d9636', + }, + ], + functionParameter: { + x: { name: 'x', detail: 'Giá trị mà bạn muốn có phân bố của nó.' }, + mean: { name: 'trung độ số', detail: 'Trung độ số học của phân phối.' }, + cumulative: { name: 'tích lũy', detail: 'Một giá trị lô-gic quyết định dạng thức của hàm. Nếu lũy tích là ĐÚNG thì POISSON.DIST trả về hàm phân bố lũy tích; nếu SAI, nó trả về hàm mật độ xác suất.' }, + }, + }, + PROB: { + description: 'Trả về xác suất các giá trị trong một phạm vi nằm giữa hai giới hạn.', + abstract: 'Trả về xác suất các giá trị trong một phạm vi nằm giữa hai giới hạn.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/prob-%E5%87%BD%E6%95%B0-9ac30561-c81c-4259-8253-34f0a238fc49', + }, + ], + functionParameter: { + xRange: { name: 'số', detail: 'Phạm vi số với các giá trị xác suất tương ứng.' }, + probRange: { name: 'xác suất', detail: 'Một tập hợp các giá trị xác suất được liên kết với một giá trị số.' }, + lowerLimit: { name: 'giới hạn dưới', detail: 'Giới hạn dưới bằng số của xác suất được tính toán.' }, + upperLimit: { name: 'giới hạn trên', detail: 'Giới hạn trên bằng số của xác suất được tính toán.' }, + }, + }, + QUARTILE_EXC: { + description: 'Trả về các phần tư của tập dữ liệu (loại trừ 0 và 1)', + abstract: 'Trả về các phần tư của tập dữ liệu (loại trừ 0 và 1)', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/quartile-exc-%E5%87%BD%E6%95%B0-5a355b7a-840b-4a01-b0f1-f538c2864cad', + }, + ], + functionParameter: { + array: { name: 'mảng', detail: 'Một mảng hoặc phạm vi dữ liệu yêu cầu giá trị tứ phân vị.' }, + quart: { name: 'giá trị tứ phân', detail: 'Giá trị tứ phân vị cần trả về.' }, + }, + }, + QUARTILE_INC: { + description: 'Trả về các phần tư của tập dữ liệu (bao gồm 0 và 1)', + abstract: 'Trả về các phần tư của tập dữ liệu (bao gồm 0 và 1)', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/quartile-inc-%E5%87%BD%E6%95%B0-1bbacc80-5075-42f1-aed6-47d735c4819d', + }, + ], + functionParameter: { + array: { name: 'mảng', detail: 'Một mảng hoặc phạm vi dữ liệu yêu cầu giá trị tứ phân vị.' }, + quart: { name: 'giá trị tứ phân', detail: 'Giá trị tứ phân vị cần trả về.' }, + }, + }, RANK_AVG: { description: 'Trả về thứ hạng của một số trong một danh sách các số', abstract: 'Trả về thứ hạng của một số trong một danh sách các số', @@ -762,6 +1209,91 @@ export default { order: { name: 'xếp hạng số', detail: 'Một con số chỉ rõ cách xếp hạng số. 0 hoặc bị bỏ qua đối với thứ tự giảm dần, khác 0 đối với thứ tự tăng dần.' }, }, }, + RSQ: { + description: 'Trả về bình phương của hệ số tương quan thời điểm sản phẩm Pearson', + abstract: 'Trả về hệ số tương quan mô-men tích Pearson', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/rsq-%E5%87%BD%E6%95%B0-d7161715-250d-4a01-b80d-a8364f2be08f', + }, + ], + functionParameter: { + array1: { name: 'mảng 1', detail: 'Mảng phụ thuộc của mảng hoặc phạm vi dữ liệu.' }, + array2: { name: 'mảng 2', detail: 'Mảng độc lập của mảng hoặc phạm vi dữ liệu.' }, + }, + }, + SKEW: { + description: 'Trả về độ lệch của một phân bố.', + abstract: 'Trả về độ lệch của một phân bố.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/skew-%E5%87%BD%E6%95%B0-bdf49d86-b1ef-4804-a046-28eaea69c9fa', + }, + ], + functionParameter: { + number1: { name: 'số 1', detail: 'Số đầu tiên, tham chiếu ô hoặc phạm vi ô cần tính độ lệch.' }, + number2: { name: 'số 2', detail: 'Tối đa 255 số bổ sung, tham chiếu ô hoặc phạm vi ô để tính toán độ lệch.' }, + }, + }, + SKEW_P: { + description: 'Trả về độ lệch của phân bố dựa trên tổng thể mẫu', + abstract: 'Trả về độ lệch của phân bố dựa trên tổng thể mẫu', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/skew-p-%E5%87%BD%E6%95%B0-76530a5c-99b9-48a1-8392-26632d542fcb', + }, + ], + functionParameter: { + number1: { name: 'số 1', detail: 'Số đầu tiên, tham chiếu ô hoặc phạm vi ô cần tính độ lệch.' }, + number2: { name: 'số 2', detail: 'Tối đa 255 số bổ sung, tham chiếu ô hoặc phạm vi ô để tính toán độ lệch.' }, + }, + }, + SLOPE: { + description: 'Trả về độ dốc của đường hồi quy tuyến tính', + abstract: 'Trả về độ dốc của đường hồi quy tuyến tính', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/slope-%E5%87%BD%E6%95%B0-11fb8f97-3117-4813-98aa-61d7e01276b9', + }, + ], + functionParameter: { + knownYs: { name: 'mảng _y', detail: 'Mảng phụ thuộc của mảng hoặc phạm vi dữ liệu.' }, + knownXs: { name: 'mảng _x', detail: 'Mảng độc lập của mảng hoặc phạm vi dữ liệu.' }, + }, + }, + SMALL: { + description: 'Trả về giá trị nhỏ thứ k của tập dữ liệu.', + abstract: 'Trả về giá trị nhỏ thứ k của tập dữ liệu.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/small-%E5%87%BD%E6%95%B0-17da8222-7c82-42b2-961b-14c45384df07', + }, + ], + functionParameter: { + array: { name: 'mảng', detail: 'Mảng hoặc phạm vi dữ liệu dạng số mà bạn muốn xác định giá trị nhỏ thứ k của nó.' }, + k: { name: 'k', detail: 'Vị trí (từ giá trị nhỏ nhất) trong mảng hoặc phạm vi dữ liệu cần trả về.' }, + }, + }, + STANDARDIZE: { + description: 'Trả về giá trị chuẩn hóa', + abstract: 'Trả về giá trị chuẩn hóa', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/standardize-%E5%87%BD%E6%95%B0-81d66554-2d54-40ec-ba83-6437108ee775', + }, + ], + functionParameter: { + x: { name: 'x', detail: 'Giá trị bạn muốn chuẩn hóa.' }, + mean: { name: 'trung độ số', detail: 'Trung độ số học của phân phối.' }, + standardDev: { name: 'Độ lệch chuẩn', detail: 'Độ lệch chuẩn của phân phối.' }, + }, + }, STDEV_P: { description: 'Tính toán độ lệch chuẩn dựa trên toàn bộ tổng thể được cung cấp ở dạng đối số (bỏ qua giá trị lô-gic và văn bản).', abstract: 'Tính độ lệch chuẩn dựa trên toàn bộ quần thể mẫu', @@ -818,6 +1350,121 @@ export default { value2: { name: 'giá trị 2', detail: 'Đối số dạng số từ 2 đến 254 tương ứng với tổng thể. Bạn cũng có thể sử dụng một mảng đơn hay tham chiếu tới một mảng thay thế cho các đối số được phân tách bởi dấu phẩy.' }, }, }, + STEYX: { + description: 'Trả về sai số chuẩn của giá trị y dự đoán cho mỗi giá trị x trong hồi quy.', + abstract: 'Trả về sai số chuẩn của giá trị y dự đoán cho mỗi giá trị x trong hồi quy.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/steyx-%E5%87%BD%E6%95%B0-6ce74b2c-449d-4a6e-b9ac-f9cef5ba48ab', + }, + ], + functionParameter: { + knownYs: { name: 'mảng _y', detail: 'Mảng phụ thuộc của mảng hoặc phạm vi dữ liệu.' }, + knownXs: { name: 'mảng _x', detail: 'Mảng độc lập của mảng hoặc phạm vi dữ liệu.' }, + }, + }, + T_DIST: { + description: 'Trả về phân phối xác suất t-Student của Học sinh', + abstract: 'Trả về phân phối xác suất t-Student của Học sinh', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/t-dist-%E5%87%BD%E6%95%B0-4329459f-ae91-48c2-bba8-1ead1c6c21b2', + }, + ], + functionParameter: { + x: { name: 'x', detail: 'Cần tính giá trị số của phân bố.' }, + degFreedom: { name: 'bậc tự do', detail: 'Một số nguyên biểu thị số bậc tự do.' }, + cumulative: { name: 'tích lũy', detail: 'Một giá trị lô-gic quyết định dạng thức của hàm. Nếu lũy tích là ĐÚNG thì T.DIST trả về hàm phân bố lũy tích; nếu SAI, nó trả về hàm mật độ xác suất.' }, + }, + }, + T_DIST_2T: { + description: 'Trả về phân phối xác suất t-Student của Học sinh (hai đuôi)', + abstract: 'Trả về phân phối xác suất t-Student của Học sinh (hai đuôi)', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/t-dist-2t-%E5%87%BD%E6%95%B0-198e9340-e360-4230-bd21-f52f22ff5c28', + }, + ], + functionParameter: { + x: { name: 'x', detail: 'Cần tính giá trị số của phân bố.' }, + degFreedom: { name: 'bậc tự do', detail: 'Một số nguyên biểu thị số bậc tự do.' }, + }, + }, + T_DIST_RT: { + description: 'Trả về phân phối xác suất t-Student của Học sinh (đuôi bên phải)', + abstract: 'Trả về phân phối xác suất t-Student của Học sinh (đuôi bên phải)', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/t-dist-rt-%E5%87%BD%E6%95%B0-20a30020-86f9-4b35-af1f-7ef6ae683eda', + }, + ], + functionParameter: { + x: { name: 'x', detail: 'Cần tính giá trị số của phân bố.' }, + degFreedom: { name: 'bậc tự do', detail: 'Một số nguyên biểu thị số bậc tự do.' }, + }, + }, + T_INV: { + description: 'Trả về hàm nghịch đảo của phân bố xác suất t-Student của Học sinh', + abstract: 'Trả về hàm nghịch đảo của phân bố xác suất t-Student của Học sinh', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/t-inv-%E5%87%BD%E6%95%B0-2908272b-4e61-4942-9df9-a25fec9b0e2e', + }, + ], + functionParameter: { + probability: { name: 'xác suất', detail: 'Xác suất liên quan đến phân phối t-Student của Sinh viên.' }, + degFreedom: { name: 'bậc tự do', detail: 'Một số nguyên biểu thị số bậc tự do.' }, + }, + }, + T_INV_2T: { + description: 'Trả về hàm nghịch đảo của phân bố xác suất t-Student của Học sinh (hai đuôi)', + abstract: 'Trả về hàm nghịch đảo của phân bố xác suất t-Student của Học sinh (hai đuôi)', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/t-inv-2t-%E5%87%BD%E6%95%B0-ce72ea19-ec6c-4be7-bed2-b9baf2264f17', + }, + ], + functionParameter: { + probability: { name: 'xác suất', detail: 'Xác suất liên quan đến phân phối t-Student của Sinh viên.' }, + degFreedom: { name: 'bậc tự do', detail: 'Một số nguyên biểu thị số bậc tự do.' }, + }, + }, + T_TEST: { + description: 'Trả về xác suất kết hợp với Phép thử t-Student.', + abstract: 'Trả về xác suất kết hợp với Phép thử t-Student.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/t-test-%E5%87%BD%E6%95%B0-d4e08ec3-c545-485f-962e-276f7cbed055', + }, + ], + functionParameter: { + array1: { name: 'mảng 1', detail: 'Mảng thứ nhất của phạm vi dữ liệu.' }, + array2: { name: 'mảng 2', detail: 'Mảng thứ hai của phạm vi dữ liệu.' }, + tails: { name: 'đặc điểm đuôi', detail: 'Xác định số đuôi của phân phối. Nếu đuôi = 1, T.TEST sử dụng phân phối một phía. Nếu đuôi = 2, T.TEST sử dụng phân phối hai phía.' }, + type: { name: 'loại Phép thử', detail: 'Loại Phép thử t cần thực hiện.' }, + }, + }, + TRIMMEAN: { + description: 'Trả về trung bình của phần trong một tập dữ liệu.', + abstract: 'Trả về trung bình của phần trong một tập dữ liệu.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/trimmean-%E5%87%BD%E6%95%B0-d90c9878-a119-4746-88fa-63d988f511d3', + }, + ], + functionParameter: { + array: { name: 'mảng', detail: 'Mảng hoặc phạm vi giá trị cần cắt bớt và tính trung bình.' }, + percent: { name: 'tỷ lệ loại trừ', detail: 'Tỷ lệ các điểm dữ liệu cần loại bỏ ra khỏi việc tính toán.' }, + }, + }, VAR_P: { description: 'Tính toán phương sai dựa trên toàn bộ tập hợp (bỏ các giá trị lô-gic và văn bản trong tập hợp).', abstract: 'Tính toán phương sai dựa trên toàn bộ tập hợp', @@ -874,4 +1521,35 @@ export default { value2: { name: 'giá trị 2', detail: 'Là các đối số dạng số từ 2 đến 254 tương ứng với một tập hợp.' }, }, }, + WEIBULL_DIST: { + description: 'Trả về phân bố Weibull.', + abstract: 'Trả về phân bố Weibull.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/weibull-dist-%E5%87%BD%E6%95%B0-4e783c39-9325-49be-bbc9-a83ef82b45db', + }, + ], + functionParameter: { + x: { name: 'x', detail: 'Giá trị mà bạn muốn có phân bố của nó.' }, + alpha: { name: 'alpha', detail: 'Tham số đầu tiên của phân phối.' }, + beta: { name: 'beta', detail: 'Tham số thứ hai của phân phối.' }, + cumulative: { name: 'tích lũy', detail: 'Một giá trị lô-gic quyết định dạng thức của hàm. Nếu tích lũy là TRUE, hàm WEIBULL.DIST trả về hàm phân bố tích lũy; nếu FALSE, nó trả về hàm mật độ xác suất.' }, + }, + }, + Z_TEST: { + description: 'Trả về giá trị xác suất một phía của kiểm tra z.', + abstract: 'Trả về giá trị xác suất một phía của kiểm tra z.', + links: [ + { + title: 'Hướng dẫn', + url: 'https://support.microsoft.com/vi-vn/office/z-test-%E5%87%BD%E6%95%B0-d633d5a3-2031-4614-a016-92180ad82bee', + }, + ], + functionParameter: { + array: { name: 'mảng', detail: 'Mảng hay khoảng dữ liệu để kiểm tra x.' }, + x: { name: 'x', detail: 'Giá trị cần kiểm tra.' }, + sigma: { name: 'Độ lệch chuẩn', detail: 'Độ lệch chuẩn tổng thể (đã biết). Nếu bỏ qua, độ lệch chuẩn mẫu sẽ được dùng.' }, + }, + }, }; diff --git a/packages/sheets-formula-ui/src/locale/function-list/statistical/zh-CN.ts b/packages/sheets-formula-ui/src/locale/function-list/statistical/zh-CN.ts index 77ff2b3e7b81..7c39a555b1d6 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/statistical/zh-CN.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/statistical/zh-CN.ts @@ -636,8 +636,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + dataArray: { name: '数据数组', detail: '要对其频率进行计数的一组数值或对这组数值的引用。 如果 data_array 中不包含任何数值,则 FREQUENCY 返回一个零数组。' }, + binsArray: { name: '区间数组', detail: '要将 data_array 中的值插入到的间隔数组或对间隔的引用。 如果 bins_array 中不包含任何数值,则 FREQUENCY 返回 data_array 中的元素个数。' }, }, }, GAMMA: { @@ -650,8 +650,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number: { name: '数值', detail: '伽玛函数的输入值。' }, }, }, GAMMA_DIST: { @@ -664,8 +663,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要计算其分布的数值。' }, + alpha: { name: 'alpha', detail: '分布的第一个参数。' }, + beta: { name: 'beta', detail: '分布的第二个参数。' }, + cumulative: { name: '累积', detail: '决定函数形式的逻辑值。如果为TRUE,则 GAMMA.DIST 返回累积分布函数;如果为 FALSE,则返回概率密度函数。' }, }, }, GAMMA_INV: { @@ -678,8 +679,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '概率', detail: '与伽玛分布相关的概率。' }, + alpha: { name: 'alpha', detail: '分布的第一个参数。' }, + beta: { name: 'beta', detail: '分布的第二个参数。' }, }, }, GAMMALN: { @@ -692,8 +694,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '要计算其 GAMMALN 的数值。' }, }, }, GAMMALN_PRECISE: { @@ -706,8 +707,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '要计算其 GAMMALN.PRECISE 的数值。' }, }, }, GAUSS: { @@ -720,8 +720,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + z: { name: 'z', detail: '需要计算其分布的数值。' }, }, }, GEOMEAN: { @@ -734,8 +733,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数值 1', detail: '要计算几何平均值的第一个数字、单元格引用或单元格区域。' }, + number2: { name: '数值 2', detail: '要计算几何平均值的其他数字、单元格引用或单元格区域,最多可包含 255 个。' }, }, }, GROWTH: { @@ -748,8 +747,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + knownYs: { name: '已知数据_y', detail: '关系表达式 y = b*m^x 中已知的 y 值集合。' }, + knownXs: { name: '已知数据_x', detail: '关系表达式 y = b*m^x 中已知的 x 值集合。' }, + newXs: { name: '新数据_x', detail: '需要 GROWTH 返回对应 y 值的新 x 值。' }, + constb: { name: 'b', detail: '一个逻辑值,用于指定是否将常量 b 强制设为 1。' }, }, }, HARMEAN: { @@ -762,8 +763,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数值 1', detail: '要计算调和平均值的第一个数字、单元格引用或单元格区域。' }, + number2: { name: '数值 2', detail: '要计算调和平均值的其他数字、单元格引用或单元格区域,最多可包含 255 个。' }, }, }, HYPGEOM_DIST: { @@ -776,8 +777,11 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + sampleS: { name: '样本成功次数', detail: '样本中成功的次数。' }, + numberSample: { name: '样本大小', detail: '样本大小。' }, + populationS: { name: '总体成功次数', detail: '总体中成功的次数。' }, + numberPop: { name: '总体大小', detail: '总体大小。' }, + cumulative: { name: '累积', detail: '决定函数形式的逻辑值。如果为TRUE,则 HYPGEOM.DIST 返回累积分布函数;如果为 FALSE,则返回概率密度函数。' }, }, }, INTERCEPT: { @@ -804,8 +808,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数值 1', detail: '要计算峰值的第一个数字、单元格引用或单元格区域。' }, + number2: { name: '数值 2', detail: '要计算峰值的其他数字、单元格引用或单元格区域,最多可包含 255 个。' }, }, }, LARGE: { @@ -818,8 +822,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '数组', detail: '需要确定第 k 个最大值的数组或数据区域。' }, + k: { name: 'k', detail: '返回值在数组或数据单元格区域中的位置(从大到小排)。' }, }, }, LINEST: { @@ -851,8 +855,8 @@ export default { }, }, LOGNORM_DIST: { - description: '返回对数累积分布函数', - abstract: '返回对数累积分布函数', + description: '返回对数正态累积分布', + abstract: '返回对数正态累积分布', links: [ { title: '教学', @@ -860,13 +864,15 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要计算其分布的数值。' }, + mean: { name: '平均值', detail: '分布的算术平均值。' }, + standardDev: { name: '标准偏差', detail: '分布的标准偏差。' }, + cumulative: { name: '累积', detail: '决定函数形式的逻辑值。 如果为 TRUE,则 LOGNORM.DIST 返回累积分布函数;如果为 FALSE,则返回概率密度函数。' }, }, }, LOGNORM_INV: { - description: '返回对数累积分布的反函数', - abstract: '返回对数累积分布的反函数', + description: '返回对数正态累积分布的反函数', + abstract: '返回对数正态累积分布的反函数', links: [ { title: '教学', @@ -874,8 +880,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '概率', detail: '对应于对数正态分布的概率。' }, + mean: { name: '平均值', detail: '分布的算术平均值。' }, + standardDev: { name: '标准偏差', detail: '分布的标准偏差。' }, }, }, MAX: { @@ -939,8 +946,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数值 1', detail: '要计算中值的第一个数字、单元格引用或单元格区域。' }, + number2: { name: '数值 2', detail: '要计算中值的其他数字、单元格引用或单元格区域,最多可包含 255 个。' }, }, }, MIN: { @@ -1004,8 +1011,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数值 1', detail: '要计算众数的第一个数字、单元格引用或单元格区域。' }, + number2: { name: '数值 2', detail: '要计算众数的其他数字、单元格引用或单元格区域,最多可包含 255 个。' }, }, }, MODE_SNGL: { @@ -1018,8 +1025,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数值 1', detail: '要计算众数的第一个数字、单元格引用或单元格区域。' }, + number2: { name: '数值 2', detail: '要计算众数的其他数字、单元格引用或单元格区域,最多可包含 255 个。' }, }, }, NEGBINOM_DIST: { @@ -1032,8 +1039,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + numberF: { name: '失败次数', detail: '失败的次数。' }, + numberS: { name: '成功次数', detail: '成功次数的阈值。' }, + probabilityS: { name: '成功概率', detail: '成功的概率。' }, + cumulative: { name: '累积', detail: '决定函数形式的逻辑值。 如果为 TRUE,则 NEGBINOM.DIST 返回累积分布函数;如果为 FALSE,则返回概率密度函数。' }, }, }, NORM_DIST: { @@ -1104,13 +1113,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: '数据1', detail: '代表因变量数据的数组或矩阵的范围。' }, + array2: { name: '数据2', detail: '代表自变量数据的数组或矩阵的范围。' }, }, }, PERCENTILE_EXC: { - description: '返回某个区域中的数值的第 k 个百分点值,此处的 k 的范围为 0 到 1(不含 0 和 1)', - abstract: '返回某个区域中的数值的第 k 个百分点值,此处的 k 的范围为 0 到 1(不含 0 和 1)', + description: '返回数据集中第 k 个百分点的值 (不含 0 和 1)', + abstract: '返回数据集中第 k 个百分点的值 (不含 0 和 1)', links: [ { title: '教学', @@ -1118,13 +1127,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '数组', detail: '定义相对位置的数组或数据区域。' }, + k: { name: 'k', detail: '0 到 1 之间的百分点值 (不含 0 和 1)。' }, }, }, PERCENTILE_INC: { - description: '返回区域中数值的第 k 个百分点的值', - abstract: '返回区域中数值的第 k 个百分点的值', + description: '返回数据集中第 k 个百分点的值 (包含 0 和 1)', + abstract: '返回数据集中第 k 个百分点的值 (包含 0 和 1)', links: [ { title: '教学', @@ -1132,13 +1141,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '数组', detail: '定义相对位置的数组或数据区域。' }, + k: { name: 'k', detail: '0 到 1 之间的百分点值 (包含 0 和 1)。' }, }, }, PERCENTRANK_EXC: { - description: '将某个数值在数据集中的排位作为数据集的百分点值返回,此处的百分点值的范围为 0 到 1(不含 0 和 1)', - abstract: '将某个数值在数据集中的排位作为数据集的百分点值返回,此处的百分点值的范围为 0 到 1(不含 0 和 1)', + description: '返回数据集中值的百分比排位 (不含 0 和 1)', + abstract: '返回数据集中值的百分比排位 (不含 0 和 1)', links: [ { title: '教学', @@ -1146,13 +1155,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '数组', detail: '定义相对位置的数组或数据区域。' }, + x: { name: 'x', detail: '需要得到其排位的值。' }, + significance: { name: '有效位数', detail: '用于标识返回的百分比值的有效位数的值。 如果省略,则 PERCENTRANK.EXC 使用 3 位小数 (0.xxx)。' }, }, }, PERCENTRANK_INC: { - description: '返回数据集中值的百分比排位', - abstract: '返回数据集中值的百分比排位', + description: '返回数据集中值的百分比排位 (包含 0 和 1)', + abstract: '返回数据集中值的百分比排位 (包含 0 和 1)', links: [ { title: '教学', @@ -1160,8 +1170,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '数组', detail: '定义相对位置的数组或数据区域。' }, + x: { name: 'x', detail: '需要得到其排位的值。' }, + significance: { name: '有效位数', detail: '用于标识返回的百分比值的有效位数的值。 如果省略,则 PERCENTRANK.INC 使用 3 位小数 (0.xxx)。' }, }, }, PERMUT: { @@ -1174,8 +1185,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number: { name: '总数', detail: '项目的数量。' }, + numberChosen: { name: '样品数量', detail: '每一排列中项目的数量。' }, }, }, PERMUTATIONA: { @@ -1188,8 +1199,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number: { name: '总数', detail: '项目的数量。' }, + numberChosen: { name: '样品数量', detail: '每一排列中项目的数量。' }, }, }, PHI: { @@ -1202,8 +1213,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'X 是需要标准正态分布密度的数字。' }, }, }, POISSON_DIST: { @@ -1216,8 +1226,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要计算其分布的数值。' }, + mean: { name: '平均值', detail: '分布的算术平均值。' }, + cumulative: { name: '累积', detail: '决定函数形式的逻辑值。 如果为 TRUE,则 POISSON.DIST 返回累积分布函数;如果为 FALSE,则返回概率密度函数。' }, }, }, PROB: { @@ -1230,13 +1241,15 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + xRange: { name: '数值', detail: '具有各自相应概率值的数值区域。' }, + probRange: { name: '概率', detail: '与数值相关联的一组概率值。' }, + lowerLimit: { name: '下界', detail: '要计算其概率的数值下界。' }, + upperLimit: { name: '上界', detail: '要计算其概率的数值上界。' }, }, }, QUARTILE_EXC: { - description: '基于百分点值返回数据集的四分位,此处的百分点值的范围为 0 到 1(不含 0 和 1)', - abstract: '基于百分点值返回数据集的四分位,此处的百分点值的范围为 0 到 1(不含 0 和 1)', + description: '返回数据集的四分位数 (不含 0 和 1)', + abstract: '返回数据集的四分位数 (不含 0 和 1)', links: [ { title: '教学', @@ -1244,13 +1257,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '数组', detail: '要求得四分位数值的数组或数据区域。' }, + quart: { name: '四分位值', detail: '要返回的四分位数值。' }, }, }, QUARTILE_INC: { - description: '返回一组数据的四分位点', - abstract: '返回一组数据的四分位点', + description: '返回数据集的四分位数 (包含 0 和 1)', + abstract: '返回数据集的四分位数 (包含 0 和 1)', links: [ { title: '教学', @@ -1258,8 +1271,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '数组', detail: '要求得四分位数值的数组或数据区域。' }, + quart: { name: '四分位值', detail: '要返回的四分位数值。' }, }, }, RANK_AVG: { @@ -1302,13 +1315,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: '数据1', detail: '代表因变量数据的数组或矩阵的范围。' }, + array2: { name: '数据2', detail: '代表自变量数据的数组或矩阵的范围。' }, }, }, SKEW: { - description: '返回分布的不对称度', - abstract: '返回分布的不对称度', + description: '返回分布的偏斜度', + abstract: '返回分布的偏斜度', links: [ { title: '教学', @@ -1316,13 +1329,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数值 1', detail: '要计算偏斜度的第一个数字、单元格引用或单元格区域。' }, + number2: { name: '数值 2', detail: '要计算偏斜度的其他数字、单元格引用或单元格区域,最多可包含 255 个。' }, }, }, SKEW_P: { - description: '返回一个分布的不对称度:用来体现某一分布相对其平均值的不对称程度', - abstract: '返回一个分布的不对称度:用来体现某一分布相对其平均值的不对称程度', + description: '返回基于样本总体的分布的偏斜度', + abstract: '返回基于样本总体的分布的偏斜度', links: [ { title: '教学', @@ -1330,8 +1343,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '数值 1', detail: '要计算偏斜度的第一个数字、单元格引用或单元格区域。' }, + number2: { name: '数值 2', detail: '要计算偏斜度的其他数字、单元格引用或单元格区域,最多可包含 255 个。' }, }, }, SLOPE: { @@ -1344,8 +1357,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + knownYs: { name: '数据_y', detail: '代表因变量数据的数组或矩阵的范围。' }, + knownXs: { name: '数据_x', detail: '代表自变量数据的数组或矩阵的范围。' }, }, }, SMALL: { @@ -1358,8 +1371,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '数组', detail: '需要确定第 k 个最小值的数组或数据区域。' }, + k: { name: 'k', detail: '返回值在数组或数据单元格区域中的位置(从小到大排)。' }, }, }, STANDARDIZE: { @@ -1372,8 +1385,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要计算其正态化的数值。' }, + mean: { name: '平均值', detail: '分布的算术平均值。' }, + standardDev: { name: '标准偏差', detail: '分布的标准偏差。' }, }, }, STDEV_P: { @@ -1442,13 +1456,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + knownYs: { name: '数据_y', detail: '代表因变量数据的数组或矩阵的范围。' }, + knownXs: { name: '数据_x', detail: '代表自变量数据的数组或矩阵的范围。' }, }, }, T_DIST: { - description: '返回学生 t-分布的百分点(概率)', - abstract: '返回学生 t-分布的百分点(概率)', + description: '返回学生的 t 概率分布', + abstract: '返回学生的 t 概率分布', links: [ { title: '教学', @@ -1456,13 +1470,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要计算分布的数值。' }, + degFreedom: { name: '自由度', detail: '一个表示自由度数的整数。' }, + cumulative: { name: '累积', detail: '决定函数形式的逻辑值。 如果为 TRUE,则 T.DIST 返回累积分布函数;如果为 FALSE,则返回概率密度函数。' }, }, }, T_DIST_2T: { - description: '返回学生 t-分布的百分点(概率)', - abstract: '返回学生 t-分布的百分点(概率)', + description: '返回学生的 t 概率分布 (双尾)', + abstract: '返回学生的 t 概率分布 (双尾)', links: [ { title: '教学', @@ -1470,13 +1485,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要计算分布的数值。' }, + degFreedom: { name: '自由度', detail: '一个表示自由度数的整数。' }, }, }, T_DIST_RT: { - description: '返回学生 t-分布', - abstract: '返回学生 t-分布', + description: '返回学生的 t 概率分布 (右尾)', + abstract: '返回学生的 t 概率分布 (右尾)', links: [ { title: '教学', @@ -1484,13 +1499,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要计算分布的数值。' }, + degFreedom: { name: '自由度', detail: '一个表示自由度数的整数。' }, }, }, T_INV: { - description: '返回作为概率和自由度函数的学生 t 分布的 t 值', - abstract: '返回作为概率和自由度函数的学生 t 分布的 t 值', + description: '返回学生的 t 概率分布的反函数', + abstract: '返回学生的 t 概率分布的反函数', links: [ { title: '教学', @@ -1498,13 +1513,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '概率', detail: '与学生的 t 分布相关的概率。' }, + degFreedom: { name: '自由度', detail: '一个表示自由度数的整数。' }, }, }, T_INV_2T: { - description: '返回学生 t-分布的反函数', - abstract: '返回学生 t-分布的反函数', + description: '返回学生的 t 概率分布的反函数 (双尾)', + abstract: '返回学生的 t 概率分布的反函数 (双尾)', links: [ { title: '教学', @@ -1512,8 +1527,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '概率', detail: '与学生的 t 分布相关的概率。' }, + degFreedom: { name: '自由度', detail: '一个表示自由度数的整数。' }, }, }, T_TEST: { @@ -1526,8 +1541,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: '数组1', detail: '第一个数据数组或数据范围。' }, + array2: { name: '数组2', detail: '第二个数据数组或数据范围。' }, + tails: { name: '尾部特性', detail: '指定分布尾数。 如果 tails = 1,则 T.TEST 使用单尾分布。 如果 tails = 2,则 T.TEST 使用双尾分布。' }, + type: { name: '检验类型', detail: '要执行的 t 检验的类型。' }, }, }, TREND: { @@ -1554,8 +1571,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '数组', detail: '要求得内部平均值的数组或数据区域。' }, + percent: { name: '排除比例', detail: '从计算中排除数据点的百分比值。' }, }, }, VAR_P: { @@ -1624,8 +1641,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要计算其分布的数值。' }, + alpha: { name: 'alpha', detail: '分布的第一个参数。' }, + beta: { name: 'beta', detail: '分布的第二个参数。' }, + cumulative: { name: '累积', detail: '决定函数形式的逻辑值。如果为TRUE,则 WEIBULL.DIST 返回累积分布函数;如果为 FALSE,则返回概率密度函数。' }, }, }, Z_TEST: { @@ -1638,8 +1657,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '数组', detail: '用来检验 x 的数组或数据区域。' }, + x: { name: 'x', detail: '要测试的值。' }, + sigma: { name: '标准偏差', detail: '总体(已知)标准偏差。 如果省略,则使用样本标准偏差。' }, }, }, }; diff --git a/packages/sheets-formula-ui/src/locale/function-list/statistical/zh-TW.ts b/packages/sheets-formula-ui/src/locale/function-list/statistical/zh-TW.ts index fb7c4510a1ac..16ff5456e693 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/statistical/zh-TW.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/statistical/zh-TW.ts @@ -129,7 +129,7 @@ export default { }, ], functionParameter: { - probability: { name: '機率', detail: '這是 beta 分佈的相關機率。' }, + probability: { name: '機率', detail: 'beta 分佈的相關機率。' }, alpha: { name: 'alpha', detail: '分佈的第一個參數。' }, beta: { name: 'beta', detail: '分佈的第二個參數。' }, A: { name: '下限', detail: '函數的下限,預設值為 0。' }, @@ -180,12 +180,12 @@ export default { functionParameter: { trials: { name: '實驗次數', detail: '伯努利實驗的次數。' }, probabilityS: { name: '成功機率', detail: '每一次實驗的成功機率。' }, - alpha: { name: '目標機率', detail: '這是臨界值。' }, + alpha: { name: '目標機率', detail: '臨界值。' }, }, }, CHISQ_DIST: { - description: '返回 χ2 分佈的左尾機率。', - abstract: '返回 χ2 分佈的左尾機率。', + description: '傳回 χ2 分佈的左尾機率。', + abstract: '傳回 χ2 分佈的左尾機率。', links: [ { title: '教導', @@ -193,9 +193,9 @@ export default { }, ], functionParameter: { - x: { name: '值', detail: '這是用來評估分佈的值。' }, - degFreedom: { name: '自由度', detail: '這是自由度。' }, - cumulative: { name: '累積', detail: ' 這是決定函數形式的邏輯值。 如果為 TRUE,CHISQ.DIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, + x: { name: '值', detail: '用來評估分佈的值。' }, + degFreedom: { name: '自由度', detail: '自由度。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。 如果為 TRUE,CHISQ.DIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, }, }, CHISQ_DIST_RT: { @@ -208,13 +208,13 @@ export default { }, ], functionParameter: { - x: { name: '值', detail: '這是用來評估分佈的值。' }, - degFreedom: { name: '自由度', detail: '這是自由度。' }, + x: { name: '值', detail: '用來評估分佈的值。' }, + degFreedom: { name: '自由度', detail: '自由度。' }, }, }, CHISQ_INV: { - description: '返回 χ2 分佈的左尾機率的反函數值。', - abstract: '返回 χ2 分佈的左尾機率的反函數值。', + description: '傳回 χ2 分佈的左尾機率的反函數值。', + abstract: '傳回 χ2 分佈的左尾機率的反函數值。', links: [ { title: '教導', @@ -222,8 +222,8 @@ export default { }, ], functionParameter: { - probability: { name: '機率', detail: '這是與 χ2 分佈相關聯的機率。' }, - degFreedom: { name: '自由度', detail: '這是自由度。' }, + probability: { name: '機率', detail: '與 χ2 分佈相關聯的機率。' }, + degFreedom: { name: '自由度', detail: '自由度。' }, }, }, CHISQ_INV_RT: { @@ -236,8 +236,8 @@ export default { }, ], functionParameter: { - probability: { name: '機率', detail: '這是與 χ2 分佈相關聯的機率。' }, - degFreedom: { name: '自由度', detail: '這是自由度。' }, + probability: { name: '機率', detail: '與 χ2 分佈相關聯的機率。' }, + degFreedom: { name: '自由度', detail: '自由度。' }, }, }, CHISQ_TEST: { @@ -250,8 +250,8 @@ export default { }, ], functionParameter: { - actualRange: { name: '觀察範圍', detail: '這是觀察值範圍,用來檢定預期值。' }, - expectedRange: { name: '預期範圍', detail: '這是資料範圍,其內容為各欄總和乘各列總和後的值,再除以全部值總和的比率。' }, + actualRange: { name: '觀察範圍', detail: '觀察值範圍,用來檢定預期值。' }, + expectedRange: { name: '預期範圍', detail: '資料範圍,其內容為各欄總和乘各列總和後的值,再除以全部值總和的比率。' }, }, }, CONFIDENCE_NORM: { @@ -266,7 +266,7 @@ export default { functionParameter: { alpha: { name: 'alpha', detail: '用於計算置信水準的顯著水準。置信水準等於 100*(1 - alpha)%,換句話說,alpha 0.05 表示信賴水準為 95%。' }, standardDev: { name: '總體標準差', detail: '假設資料範圍的總體標準差已知。' }, - size: { name: '樣本大小', detail: '這是樣本大小。' }, + size: { name: '樣本大小', detail: '樣本大小。' }, }, }, CONFIDENCE_T: { @@ -281,7 +281,7 @@ export default { functionParameter: { alpha: { name: 'alpha', detail: '用於計算置信水準的顯著水準。置信水準等於 100*(1 - alpha)%,換句話說,alpha 0.05 表示信賴水準為 95%。' }, standardDev: { name: '總體標準差', detail: '假設資料範圍的總體標準差已知。' }, - size: { name: '樣本大小', detail: '這是樣本大小。' }, + size: { name: '樣本大小', detail: '樣本大小。' }, }, }, CORREL: { @@ -419,13 +419,13 @@ export default { }, ], functionParameter: { - number1: { name: '數值1', detail: '這是要計算平方差之總和的第 1 個引數。' }, - number2: { name: '數值2', detail: '這是要計算平方差之總和的第 2 到 255 個引數。' }, + number1: { name: '數值1', detail: '要計算平方差之總和的第 1 個引數。' }, + number2: { name: '數值2', detail: '要計算平方差之總和的第 2 到 255 個引數。' }, }, }, EXPON_DIST: { - description: '返回指數分佈', - abstract: '返回指數分佈', + description: '傳回指數分佈', + abstract: '傳回指數分佈', links: [ { title: '教導', @@ -433,14 +433,14 @@ export default { }, ], functionParameter: { - x: { name: '值', detail: '這是用來評估分佈的值。' }, - lambda: { name: 'lambda', detail: '這是參數值。' }, - cumulative: { name: '累積', detail: ' 這是決定函數形式的邏輯值。 如果為 TRUE,EXPON.DIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, + x: { name: '值', detail: '用來評估分佈的值。' }, + lambda: { name: 'lambda', detail: '參數值。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。 如果為 TRUE,EXPON.DIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, }, }, F_DIST: { - description: '返回 F 機率分佈', - abstract: '返回 F 機率分佈', + description: '傳回 F 機率分佈', + abstract: '傳回 F 機率分佈', links: [ { title: '教導', @@ -448,15 +448,15 @@ export default { }, ], functionParameter: { - x: { name: '值', detail: '這是用於評估函數的值。' }, - degFreedom1: { name: '分子自由度', detail: '這是分子的自由度。' }, - degFreedom2: { name: '分母自由度', detail: '這是分母的自由度。' }, - cumulative: { name: '累積', detail: ' 這是決定函數形式的邏輯值。 如果為 TRUE,F.DIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, + x: { name: '值', detail: '用於評估函數的值。' }, + degFreedom1: { name: '分子自由度', detail: '分子的自由度。' }, + degFreedom2: { name: '分母自由度', detail: '分母的自由度。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。 如果為 TRUE,F.DIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, }, }, F_DIST_RT: { - description: '返回 F 機率分佈(右尾)', - abstract: '返回 F 機率分佈(右尾)', + description: '傳回 F 機率分佈(右尾)', + abstract: '傳回 F 機率分佈(右尾)', links: [ { title: '教導', @@ -464,9 +464,9 @@ export default { }, ], functionParameter: { - x: { name: '值', detail: '這是用於評估函數的值。' }, - degFreedom1: { name: '分子自由度', detail: '這是分子的自由度。' }, - degFreedom2: { name: '分母自由度', detail: '這是分母的自由度。' }, + x: { name: '值', detail: '用於評估函數的值。' }, + degFreedom1: { name: '分子自由度', detail: '分子的自由度。' }, + degFreedom2: { name: '分母自由度', detail: '分母的自由度。' }, }, }, F_INV: { @@ -480,8 +480,8 @@ export default { ], functionParameter: { probability: { name: '機率', detail: 'F 累積分佈相關的機率' }, - degFreedom1: { name: '分子自由度', detail: '這是分子的自由度。' }, - degFreedom2: { name: '分母自由度', detail: '這是分母的自由度。' }, + degFreedom1: { name: '分子自由度', detail: '分子的自由度。' }, + degFreedom2: { name: '分母自由度', detail: '分母的自由度。' }, }, }, F_INV_RT: { @@ -495,8 +495,8 @@ export default { ], functionParameter: { probability: { name: '機率', detail: 'F 累積分佈相關的機率' }, - degFreedom1: { name: '分子自由度', detail: '這是分子的自由度。' }, - degFreedom2: { name: '分母自由度', detail: '這是分母的自由度。' }, + degFreedom1: { name: '分子自由度', detail: '分子的自由度。' }, + degFreedom2: { name: '分母自由度', detail: '分母的自由度。' }, }, }, F_TEST: { @@ -509,8 +509,8 @@ export default { }, ], functionParameter: { - array1: { name: '陣列1', detail: '這是第一個陣列或資料範圍。' }, - array2: { name: '陣列2', detail: '這是第一個陣列或資料範圍。' }, + array1: { name: '陣列1', detail: '第一個陣列或資料範圍。' }, + array2: { name: '陣列2', detail: '第二個陣列或資料範圍。' }, }, }, FISHER: { @@ -523,7 +523,7 @@ export default { }, ], functionParameter: { - x: { name: '數值', detail: '這是要轉換的數值。' }, + x: { name: '數值', detail: '要轉換的數值。' }, }, }, FISHERINV: { @@ -536,7 +536,7 @@ export default { }, ], functionParameter: { - y: { name: '數值', detail: '這是要執行反轉換的數值。' }, + y: { name: '數值', detail: '要執行反轉換的數值。' }, }, }, FORECAST: { @@ -549,7 +549,7 @@ export default { }, ], functionParameter: { - x: { name: 'x', detail: '這是要預測值的資料點。' }, + x: { name: 'x', detail: '要預測值的資料點。' }, knownYs: { name: '陣列_y', detail: '代表因變數資料的陣列或矩陣的範圍。' }, knownXs: { name: '陣列_x', detail: '代表自變數資料的陣列或矩陣的範圍。' }, }, @@ -621,7 +621,7 @@ export default { }, ], functionParameter: { - x: { name: 'x', detail: '這是要預測值的資料點。' }, + x: { name: 'x', detail: '要預測值的資料點。' }, knownYs: { name: '陣列_y', detail: '代表因變數資料的陣列或矩陣的範圍。' }, knownXs: { name: '陣列_x', detail: '代表自變數資料的陣列或矩陣的範圍。' }, }, @@ -636,13 +636,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + dataArray: { name: '資料陣列', detail: '所要計算頻率的一組數值的陣列或參照。 如果 data_array 沒有值,FREQUENCY 會傳回零陣列。' }, + binsArray: { name: '區間陣列', detail: '區間的陣列或參照,用以將 data_array 中的值分組。 如果 bins_array 沒有值,FREQUENCY 會傳回 data_array 中的元素個數。' }, }, }, GAMMA: { description: '傳回 γ 函數值', - abstract: '返回 γ 函數值', + abstract: '傳回 γ 函數值', links: [ { title: '教導', @@ -650,13 +650,12 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number: { name: '數值', detail: '伽瑪函數的輸入值。' }, }, }, GAMMA_DIST: { - description: '返回 γ 分佈', - abstract: '返回 γ 分佈', + description: '傳回 γ 分佈', + abstract: '傳回 γ 分佈', links: [ { title: '教導', @@ -664,8 +663,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '要找出分佈的數值。' }, + alpha: { name: 'alpha', detail: '分佈的第一個參數。' }, + beta: { name: 'beta', detail: '分佈的第二個參數。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。如果為 TRUE,則 GAMMA.DIST 傳回累積分佈函數;如果為 FALSE,則傳回機率密度函數。' }, }, }, GAMMA_INV: { @@ -678,8 +679,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '機率', detail: '與伽瑪分佈的相關機率。' }, + alpha: { name: 'alpha', detail: '分佈的第一個參數。' }, + beta: { name: 'beta', detail: '分佈的第二個參數。' }, }, }, GAMMALN: { @@ -692,8 +694,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '要計算 GAMMALN 的值。' }, }, }, GAMMALN_PRECISE: { @@ -706,8 +707,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '要計算 GAMMALN.PRECISE 的值。' }, }, }, GAUSS: { @@ -720,8 +720,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + z: { name: 'z', detail: '要找出分佈的數值。' }, }, }, GEOMEAN: { @@ -734,8 +733,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '數值 1', detail: '要計算幾何平均值的第一個數字、儲存格參考或儲存格區域。 ' }, + number2: { name: '數值 2', detail: '要計算幾何平均值的其他數字、儲存格參考或儲存格區域,最多可包含 255 個。 ' }, }, }, GROWTH: { @@ -748,8 +747,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + knownYs: { name: '已知資料_y', detail: '在 y = b*m^x 關係中一組已知的 y 值。' }, + knownXs: { name: '已知資料_x', detail: '在 y = b*m^x 關係中一組已知的 x 值。' }, + newXs: { name: '新資料_x', detail: '要 GROWTH 傳回對應 y 值的新 x 值。' }, + constb: { name: 'b', detail: '指定是否強迫常數 b 等於 1 的邏輯值。' }, }, }, HARMEAN: { @@ -762,8 +763,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '數值 1', detail: '要計算調和平均值的第一個數字、儲存格參考或儲存格區域。 ' }, + number2: { name: '數值 2', detail: '要計算調和平均值的其他數字、儲存格參考或儲存格區域,最多可包含 255 個。 ' }, }, }, HYPGEOM_DIST: { @@ -776,8 +777,11 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + sampleS: { name: '樣本成功次數', detail: '樣本中成功的次數。' }, + numberSample: { name: '樣本大小', detail: '樣本大小。' }, + populationS: { name: '總體成功次數', detail: '總體中成功的次數。' }, + numberPop: { name: '總體大小', detail: '總體大小。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。如果為 TRUE,則 HYPGEOM.DIST 傳回累積分佈函數;如果為 FALSE,則傳回機率密度函數。' }, }, }, INTERCEPT: { @@ -804,8 +808,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '數值 1', detail: '要計算峰值的第一個數字、儲存格參考或儲存格區域。 ' }, + number2: { name: '數值 2', detail: '要計算峰值的其他數字、儲存格參考或儲存格區域,最多可包含 255 個。 ' }, }, }, LARGE: { @@ -818,8 +822,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '陣列', detail: '要判斷第 k 個最大值的陣列或資料範圍。' }, + k: { name: 'k', detail: '要傳回之資料陣列或儲存格範圍中的位置 (由最大起算)。' }, }, }, LINEST: { @@ -851,8 +855,8 @@ export default { }, }, LOGNORM_DIST: { - description: '傳回對數累積分佈函數', - abstract: '傳回對數累積分佈函數', + description: '傳回對數常態累積分佈', + abstract: '傳回對數常態累積分佈', links: [ { title: '教導', @@ -860,13 +864,15 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '要找出分佈的數值。' }, + mean: { name: '平均值', detail: '分佈的算術平均值。' }, + standardDev: { name: '標準差', detail: '分佈的標準差。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。 如果為 TRUE,LOGNORM.DIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, }, }, LOGNORM_INV: { - description: '傳回對數累積分佈的反函數', - abstract: '傳回對數累積分佈的反函數', + description: '傳回對數常態累積分佈的反函數', + abstract: '傳回對數常態累積分佈的反函數', links: [ { title: '教導', @@ -874,8 +880,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '機率', detail: '對應到對數常態分佈的機率。' }, + mean: { name: '平均值', detail: '分佈的算術平均值。' }, + standardDev: { name: '標準差', detail: '分佈的標準差。' }, }, }, MAX: { @@ -939,8 +946,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '數值 1', detail: '要計算中位數的第一個數字、儲存格參考或儲存格區域。 ' }, + number2: { name: '數值 2', detail: '要計算中位數的其他數字、儲存格參考或儲存格區域,最多可包含 255 個。 ' }, }, }, MIN: { @@ -1004,8 +1011,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '數值 1', detail: '要計算眾數的第一個數字、儲存格參考或儲存格區域。 ' }, + number2: { name: '數值 2', detail: '要計算眾數的其他數字、儲存格參考或儲存格區域,最多可包含 255 個。 ' }, }, }, MODE_SNGL: { @@ -1018,8 +1025,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '數值 1', detail: '要計算眾數的第一個數字、儲存格參考或儲存格區域。 ' }, + number2: { name: '數值 2', detail: '要計算眾數的其他數字、儲存格參考或儲存格區域,最多可包含 255 個。 ' }, }, }, NEGBINOM_DIST: { @@ -1032,8 +1039,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + numberF: { name: '失敗次數', detail: '失敗的次數。' }, + numberS: { name: '成功次數', detail: '成功的閥值數目。' }, + probabilityS: { name: '成功機率', detail: '成功的機率。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。 如果為 TRUE,NEGBINOM.DIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, }, }, NORM_DIST: { @@ -1046,10 +1055,10 @@ export default { }, ], functionParameter: { - x: { name: 'x', detail: '這是您要找出分佈的數值。' }, - mean: { name: '平均值', detail: '這是分佈的算術平均值。' }, - standardDev: { name: '標準差', detail: '這是分佈的標準差。' }, - cumulative: { name: '累積', detail: ' 這是決定函數形式的邏輯值。 如果為 TRUE,NORM.DIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, + x: { name: 'x', detail: '要找出分佈的數值。' }, + mean: { name: '平均值', detail: '分佈的算術平均值。' }, + standardDev: { name: '標準差', detail: '分佈的標準差。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。 如果為 TRUE,NORM.DIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, }, }, NORM_INV: { @@ -1062,9 +1071,9 @@ export default { }, ], functionParameter: { - probability: { name: '機率', detail: '這是對應到常態分佈的機率。' }, - mean: { name: '平均值', detail: '這是分佈的算術平均值。' }, - standardDev: { name: '標準差', detail: '這是分佈的標準差。' }, + probability: { name: '機率', detail: '對應到常態分佈的機率。' }, + mean: { name: '平均值', detail: '分佈的算術平均值。' }, + standardDev: { name: '標準差', detail: '分佈的標準差。' }, }, }, NORM_S_DIST: { @@ -1077,8 +1086,8 @@ export default { }, ], functionParameter: { - z: { name: 'z', detail: '這是您要找出分佈的數值。' }, - cumulative: { name: '累積', detail: ' 這是決定函數形式的邏輯值。 如果為 TRUE,NORM.DIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, + z: { name: 'z', detail: '要找出分佈的數值。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。 如果為 TRUE,NORM.DIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, }, }, NORM_S_INV: { @@ -1091,12 +1100,12 @@ export default { }, ], functionParameter: { - probability: { name: '機率', detail: '這是對應到常態分佈的機率。' }, + probability: { name: '機率', detail: '對應到常態分佈的機率。' }, }, }, PEARSON: { description: '傳回 Pearson 乘積矩相關係數', - abstract: '返回 Pearson 積矩相關係數', + abstract: '傳回 Pearson 乘積矩相關係數', links: [ { title: '教導', @@ -1104,13 +1113,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: '陣列1', detail: '代表因變數資料的陣列或矩陣的範圍。' }, + array2: { name: '陣列2', detail: '代表自變數資料的陣列或矩陣的範圍。' }, }, }, PERCENTILE_EXC: { - description: '傳回某個區域中的數值的第 k 個百分點值,此處的 k 的範圍為 0 到 1(不含 0 和 1)', - abstract: '傳回某個區域中的數值的第 k 個百分點值,此處的 k 的範圍為 0 到 1(不含 0 和 1)', + description: '傳回資料集中第 k 個百分點的值 (不包括 0 與 1)', + abstract: '傳回資料集中第 k 個百分點的值 (不包括 0 與 1)', links: [ { title: '教導', @@ -1118,13 +1127,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '陣列', detail: '用以定義相對位置的陣列或資料範圍。' }, + k: { name: 'k', detail: '在 0 到 1 範圍內 (不包括 0 與 1) 的百分位數。' }, }, }, PERCENTILE_INC: { - description: '傳回區域中數值的第 k 個百分點的值', - abstract: '傳回區域中數值的第 k 個百分點的值', + description: '傳回資料集中第 k 個百分點的值 (包括 0 與 1)', + abstract: '傳回資料集中第 k 個百分點的值 (包括 0 與 1)', links: [ { title: '教導', @@ -1132,13 +1141,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '陣列', detail: '用以定義相對位置的陣列或資料範圍。' }, + k: { name: 'k', detail: '在 0 到 1 範圍內 (包括 0 與 1) 的百分位數。' }, }, }, PERCENTRANK_EXC: { - description: '將某個數值在資料集中的排位作為資料集的百分點值傳回,此處的百分點值的範圍為 0 到 1(不含 0 和 1)', - abstract: '將某個數值在資料集中的排位作為資料集的百分點值返回,此處的百分點值的範圍為 0 到 1(不含 0 和 1)', + description: '傳回資料集中值的百分比排位 (不包括 0 與 1)', + abstract: '傳回資料集中值的百分比排位 (不包括 0 與 1)', links: [ { title: '教導', @@ -1146,13 +1155,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '陣列', detail: '用以定義相對位置的陣列或資料範圍。' }, + x: { name: 'x', detail: '想要知道排名的數值。' }, + significance: { name: '有效位數', detail: '用以識別傳回百分比值的最高有效位數之數值。 如果省略,PERCENTRANK.EXC 會使用三位小數 (0.xxx)。' }, }, }, PERCENTRANK_INC: { - description: '傳回資料集中值的百分比排位', - abstract: '傳回資料集中值的百分比排位', + description: '傳回資料集中值的百分比排位 (包括 0 與 1)', + abstract: '傳回資料集中值的百分比排位 (包括 0 與 1)', links: [ { title: '教導', @@ -1160,8 +1170,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '陣列', detail: '用以定義相對位置的陣列或資料範圍。' }, + x: { name: 'x', detail: '想要知道排名的數值。' }, + significance: { name: '有效位數', detail: '用以識別傳回百分比值的最高有效位數之數值。 如果省略,PERCENTRANK.INC 會使用三位小數 (0.xxx)。' }, }, }, PERMUT: { @@ -1174,8 +1185,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number: { name: '總數', detail: '項目數。' }, + numberChosen: { name: '樣品數量', detail: '每個排列中的項目數。' }, }, }, PERMUTATIONA: { @@ -1188,8 +1199,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number: { name: '總數', detail: '項目數。' }, + numberChosen: { name: '樣品數量', detail: '每個排列中的項目數。' }, }, }, PHI: { @@ -1202,8 +1213,7 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: 'X 是要求標準常態分佈密度的數位。' }, }, }, POISSON_DIST: { @@ -1216,8 +1226,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '要找出分佈的數值。' }, + mean: { name: '平均值', detail: '分佈的算術平均值。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。 如果為 TRUE,POISSON.DIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, }, }, PROB: { @@ -1230,13 +1241,15 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + xRange: { name: '數值', detail: '具有各自對應機率值的數值區域。' }, + probRange: { name: '機率', detail: '與數值相關聯的一組機率值。' }, + lowerLimit: { name: '下界', detail: '要計算其機率的數值下界。' }, + upperLimit: { name: '上界', detail: '要計算其機率的數值上界。' }, }, }, QUARTILE_EXC: { - description: '基於百分點值傳回資料集的四分位,此處的百分點值的範圍為 0 到 1(不含 0 和 1)', - abstract: '基於百分點值傳回資料集的四分位,此處的百分點值的範圍為 0 到 1(不含 0 和 1)', + description: '傳回資料集的四分位數 (不包括 0 與 1)', + abstract: '傳回資料集的四分位數 (不包括 0 與 1)', links: [ { title: '教導', @@ -1244,13 +1257,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '陣列', detail: '要求得四分位數值的陣列或資料範圍。' }, + quart: { name: '四分位值', detail: '要傳回的四分位數值。' }, }, }, QUARTILE_INC: { - description: '傳回一組資料的四分位點', - abstract: '傳回一組資料的四分位點', + description: '傳回資料集的四分位數 (包括 0 與 1)', + abstract: '傳回資料集的四分位數 (包括 0 與 1)', links: [ { title: '教導', @@ -1258,8 +1271,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '陣列', detail: '要求得四分位數值的陣列或資料範圍。' }, + quart: { name: '四分位值', detail: '要傳回的四分位數值。' }, }, }, RANK_AVG: { @@ -1272,9 +1285,9 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要找出其排名的數字。' }, + number: { name: '數值', detail: '要找出其排名的數字。' }, ref: { name: '數位清單', detail: '數位清單的參照。會忽略 ref 中的非數值。' }, - order: { name: '排列方式', detail: '這是指定排列數值方式的數字。0 或省略為遞減順序排序,非 0 為遞增順序排序。' }, + order: { name: '排列方式', detail: '指定排列數值方式的數字。0 或省略為遞減順序排序,非 0 為遞增順序排序。' }, }, }, RANK_EQ: { @@ -1287,9 +1300,9 @@ export default { }, ], functionParameter: { - number: { name: '數值', detail: '這是要找出其排名的數字。' }, + number: { name: '數值', detail: '要找出其排名的數字。' }, ref: { name: '數位清單', detail: '數位清單的參照。會忽略 ref 中的非數值。' }, - order: { name: '排列方式', detail: '這是指定排列數值方式的數字。0 或省略為遞減順序排序,非 0 為遞增順序排序。' }, + order: { name: '排列方式', detail: '指定排列數值方式的數字。0 或省略為遞減順序排序,非 0 為遞增順序排序。' }, }, }, RSQ: { @@ -1302,13 +1315,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: '陣列1', detail: '代表因變數資料的陣列或矩陣的範圍。' }, + array2: { name: '陣列2', detail: '代表自變數資料的陣列或矩陣的範圍。' }, }, }, SKEW: { - description: '傳回分佈的不對稱度', - abstract: '返回分佈的不對稱度', + description: '傳回分佈的偏斜度', + abstract: '傳回分佈的偏斜度', links: [ { title: '教導', @@ -1316,13 +1329,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '數值 1', detail: '要計算偏斜度的第一個數字、儲存格參考或儲存格區域。 ' }, + number2: { name: '數值 2', detail: '要計算偏斜度的其他數字、儲存格參考或儲存格區域,最多可包含 255 個。 ' }, }, }, SKEW_P: { - description: '返回一個分佈的不對稱度:用來體現某一分佈相對其平均值的不對稱程度', - abstract: '傳回一個分佈的不對稱度:用來反映某一分佈相對其平均值的不對稱程度', + description: '傳回基於樣本總體的分佈的偏斜度', + abstract: '傳回基於樣本總體的分佈的偏斜度', links: [ { title: '教導', @@ -1330,13 +1343,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + number1: { name: '數值 1', detail: '要計算偏斜度的第一個數字、儲存格參考或儲存格區域。 ' }, + number2: { name: '數值 2', detail: '要計算偏斜度的其他數字、儲存格參考或儲存格區域,最多可包含 255 個。 ' }, }, }, SLOPE: { - description: '返回線性迴歸線的斜率', - abstract: '返回線性迴歸線的斜率', + description: '傳回線性迴歸線的斜率', + abstract: '傳回線性迴歸線的斜率', links: [ { title: '教導', @@ -1344,8 +1357,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + knownYs: { name: '陣列_y', detail: '代表因變數資料的陣列或矩陣的範圍。' }, + knownXs: { name: '陣列_x', detail: '代表自變數資料的陣列或矩陣的範圍。' }, }, }, SMALL: { @@ -1358,8 +1371,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '陣列', detail: '要判斷第 k 個最小值的陣列或資料範圍。' }, + k: { name: 'k', detail: '要傳回之資料陣列或儲存格範圍中的位置 (由最小起算)。' }, }, }, STANDARDIZE: { @@ -1372,8 +1385,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '要找出常態化的數值。' }, + mean: { name: '平均值', detail: '分佈的算術平均值。' }, + standardDev: { name: '標準差', detail: '分佈的標準差。' }, }, }, STDEV_P: { @@ -1442,13 +1456,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + knownYs: { name: '陣列_y', detail: '代表因變數資料的陣列或矩陣的範圍。' }, + knownXs: { name: '陣列_x', detail: '代表自變數資料的陣列或矩陣的範圍。' }, }, }, T_DIST: { - description: '傳回學生 t-分佈的百分點(機率)', - abstract: '返回學生 t-分佈的百分點(機率)', + description: '傳回學生的 t 機率分佈', + abstract: '傳回學生的 t 機率分佈', links: [ { title: '教導', @@ -1456,13 +1470,14 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要計算分佈的數值。' }, + degFreedom: { name: '自由度', detail: '一個表示自由度數的整數。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。 如果為 TRUE,T.DIST 會傳回累積分佈函數;如果為 FALSE,則會傳回機率密度函數。' }, }, }, T_DIST_2T: { - description: '傳回學生 t-分佈的百分點(機率)', - abstract: '返回學生 t-分佈的百分點(機率)', + description: '傳回學生的 t 機率分佈 (雙尾)', + abstract: '傳回學生的 t 機率分佈 (雙尾)', links: [ { title: '教導', @@ -1470,13 +1485,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要計算分佈的數值。' }, + degFreedom: { name: '自由度', detail: '一個表示自由度數的整數。' }, }, }, T_DIST_RT: { - description: '返回學生 t-分佈', - abstract: '返回學生 t-分佈', + description: '傳回學生的 t 機率分佈 (右尾)', + abstract: '傳回學生的 t 機率分佈 (右尾)', links: [ { title: '教導', @@ -1484,13 +1499,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '需要計算分佈的數值。' }, + degFreedom: { name: '自由度', detail: '一個表示自由度數的整數。' }, }, }, T_INV: { - description: '傳回作為機率和自由度函數的學生 t 分佈的 t 值', - abstract: '返回作為機率和自由度函數的學生 t 分佈的 t 值', + description: '傳回學生的 t 機率分佈的反函數', + abstract: '傳回學生的 t 機率分佈的反函數', links: [ { title: '教導', @@ -1498,13 +1513,13 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '機率', detail: '與學生的 t 分佈相關的機率。' }, + dedegFreedom: { name: '自由度', detail: '一個表示自由度數的整數。' }, }, }, T_INV_2T: { - description: '傳回學生 t-分佈的反函數', - abstract: '傳回學生 t-分佈的反函數', + description: '傳回學生的 t 機率分佈的反函數 (雙尾)', + abstract: '傳回學生的 t 機率分佈的反函數 (雙尾)', links: [ { title: '教導', @@ -1512,8 +1527,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + probability: { name: '機率', detail: '與學生的 t 分佈相關的機率。' }, + dedegFreedom: { name: '自由度', detail: '一個表示自由度數的整數。' }, }, }, T_TEST: { @@ -1526,8 +1541,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array1: { name: '陣列1', detail: '第一個陣列或資料範圍。' }, + array2: { name: '陣列2', detail: '第二個陣列或資料範圍。' }, + tails: { name: '尾部特性', detail: '指定分佈的尾數。 如果 tails = 1,T.TEST 會使用單尾分佈。 如果 tails = 2,T.TEST 會使用雙尾分佈。' }, + type: { name: '檢定類型', detail: '要執行的 t 檢定類型。' }, }, }, TREND: { @@ -1554,8 +1571,8 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '陣列', detail: '要求得內部平均值的陣列或資料範圍。' }, + percent: { name: '排除比例', detail: '從計算中排除資料點的百分比值。' }, }, }, VAR_P: { @@ -1615,8 +1632,8 @@ export default { }, }, WEIBULL_DIST: { - description: '返回 Weibull 分佈', - abstract: '返回 Weibull 分佈', + description: '傳回 Weibull 分佈', + abstract: '傳回 Weibull 分佈', links: [ { title: '教導', @@ -1624,8 +1641,10 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + x: { name: 'x', detail: '要找出分佈的數值。' }, + alpha: { name: 'alpha', detail: '分佈的第一個參數。' }, + beta: { name: 'beta', detail: '分佈的第二個參數。' }, + cumulative: { name: '累積', detail: '決定函數形式的邏輯值。如果為 TRUE,則 WEIBULL.DIST 傳回累積分佈函數;如果為 FALSE,則傳回機率密度函數。' }, }, }, Z_TEST: { @@ -1638,8 +1657,9 @@ export default { }, ], functionParameter: { - number1: { name: 'number1', detail: 'first' }, - number2: { name: 'number2', detail: 'second' }, + array: { name: '陣列', detail: '用來檢定 x 的陣列或資料範圍。' }, + x: { name: 'x', detail: '要檢定的值。' }, + sigma: { name: '標準差', detail: '總體(已知)標準差。如果省略,則使用樣本標準差。' }, }, }, }; diff --git a/packages/sheets-formula-ui/src/locale/function-list/text/zh-TW.ts b/packages/sheets-formula-ui/src/locale/function-list/text/zh-TW.ts index 7f37fc4d9552..9c3130e9a388 100644 --- a/packages/sheets-formula-ui/src/locale/function-list/text/zh-TW.ts +++ b/packages/sheets-formula-ui/src/locale/function-list/text/zh-TW.ts @@ -286,9 +286,9 @@ export default { }, ], functionParameter: { - text: { name: 'text', detail: '這是包含您想擷取之字元的文字字串。' }, - startNum: { name: 'start_num', detail: ' 這是要在文字中擷取之第一個字元的位置。 文字中的第一個字元start_num 1,依此類文字。\n如果start_num大於文字的長度,MID/MIDB 會傳回 “” (空白文字) 。\n如果start_num小於文字的長度,但start_num加上num_chars超過文字的長度,MID/MIDB 會傳回文字結尾的字元。\n如果 start_num 小於 1,MID/MIDB 會傳回 #VALUE! 錯誤值。' }, - numChars: { name: 'num_chars', detail: '指定您要 MID 從文字傳回的字元數。\n如果 num_chars 為負數,MID 會傳回 #VALUE! 的錯誤值。' }, + text: { name: 'text', detail: '包含想擷取之字元的文字字串。' }, + startNum: { name: 'start_num', detail: ' 要在文字中擷取之第一個字元的位置。 文字中的第一個字元start_num 1,依此類文字。\n如果start_num大於文字的長度,MID/MIDB 會傳回 “” (空白文字) 。\n如果start_num小於文字的長度,但start_num加上num_chars超過文字的長度,MID/MIDB 會傳回文字結尾的字元。\n如果 start_num 小於 1,MID/MIDB 會傳回 #VALUE! 錯誤值。' }, + numChars: { name: 'num_chars', detail: '指定要 MID 從文字傳回的字元數。\n如果 num_chars 為負數,MID 會傳回 #VALUE! 的錯誤值。' }, }, }, MIDB: { @@ -427,8 +427,8 @@ export default { }, ], functionParameter: { - text: { name: '文字', detail: '這是要重複的文字。' }, - numberTimes: { name: '重複次數', detail: '這是指定文字重複次數的正數。' }, + text: { name: '文字', detail: '要重複的文字。' }, + numberTimes: { name: '重複次數', detail: '指定文字重複次數的正數。' }, }, }, RIGHT: { @@ -540,7 +540,7 @@ export default { }, ], functionParameter: { - text: { name: '文字', detail: '您在此搜尋的文字。不允許萬用字元。' }, + text: { name: '文字', detail: '在此搜尋的文字。不允許萬用字元。' }, delimiter: { name: '分隔符號', detail: '標記要擷取之點之後的文字。' }, instanceNum: { name: '實例編號', detail: '要解壓縮文字的分隔符號實例。' }, matchMode: { name: '匹配模式', detail: '判斷文字搜尋是否區分大小寫。預設值會區分大小寫。' }, @@ -558,7 +558,7 @@ export default { }, ], functionParameter: { - text: { name: '文字', detail: '您在此搜尋的文字。不允許萬用字元。' }, + text: { name: '文字', detail: '在此搜尋的文字。不允許萬用字元。' }, delimiter: { name: '分隔符號', detail: '標記要擷取之點之後的文字。' }, instanceNum: { name: '實例編號', detail: '要解壓縮文字的分隔符號實例。' }, matchMode: { name: '匹配模式', detail: '判斷文字搜尋是否區分大小寫。預設值會區分大小寫。' }, diff --git a/packages/sheets-formula/src/services/function-list/compatibility.ts b/packages/sheets-formula/src/services/function-list/compatibility.ts index 3700073ebaa9..9bcdc8c2bef8 100644 --- a/packages/sheets-formula/src/services/function-list/compatibility.ts +++ b/packages/sheets-formula/src/services/function-list/compatibility.ts @@ -192,14 +192,14 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ { name: 'formula.functionList.CHITEST.functionParameter.actualRange.name', detail: 'formula.functionList.CHITEST.functionParameter.actualRange.detail', - example: '{58,35;11,25;10,23}', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.CHITEST.functionParameter.expectedRange.name', detail: 'formula.functionList.CHITEST.functionParameter.expectedRange.detail', - example: '{45.35,47.65;17.56,18.44;16.09,16.91}', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -243,14 +243,14 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ { name: 'formula.functionList.COVAR.functionParameter.array1.name', detail: 'formula.functionList.COVAR.functionParameter.array1.detail', - example: '{3,2,4,5,6}', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.COVAR.functionParameter.array2.name', detail: 'formula.functionList.COVAR.functionParameter.array2.detail', - example: '{9,7,12,15,17}', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -381,14 +381,14 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ { name: 'formula.functionList.FTEST.functionParameter.array1.name', detail: 'formula.functionList.FTEST.functionParameter.array1.detail', - example: '{58,35;11,25;10,23}', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.FTEST.functionParameter.array2.name', detail: 'formula.functionList.FTEST.functionParameter.array2.detail', - example: '{45.35,47.65;17.56,18.44;16.09,16.91}', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -401,16 +401,30 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ abstract: 'formula.functionList.GAMMADIST.abstract', functionParameter: [ { - name: 'formula.functionList.GAMMADIST.functionParameter.number1.name', - detail: 'formula.functionList.GAMMADIST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.GAMMADIST.functionParameter.x.name', + detail: 'formula.functionList.GAMMADIST.functionParameter.x.detail', + example: '10', require: 1, repeat: 0, }, { - name: 'formula.functionList.GAMMADIST.functionParameter.number2.name', - detail: 'formula.functionList.GAMMADIST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.GAMMADIST.functionParameter.alpha.name', + detail: 'formula.functionList.GAMMADIST.functionParameter.alpha.detail', + example: '8', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.GAMMADIST.functionParameter.beta.name', + detail: 'formula.functionList.GAMMADIST.functionParameter.beta.detail', + example: '2', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.GAMMADIST.functionParameter.cumulative.name', + detail: 'formula.functionList.GAMMADIST.functionParameter.cumulative.detail', + example: 'true', require: 1, repeat: 0, }, @@ -423,16 +437,23 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ abstract: 'formula.functionList.GAMMAINV.abstract', functionParameter: [ { - name: 'formula.functionList.GAMMAINV.functionParameter.number1.name', - detail: 'formula.functionList.GAMMAINV.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.GAMMAINV.functionParameter.probability.name', + detail: 'formula.functionList.GAMMAINV.functionParameter.probability.detail', + example: '0.068094', require: 1, repeat: 0, }, { - name: 'formula.functionList.GAMMAINV.functionParameter.number2.name', - detail: 'formula.functionList.GAMMAINV.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.GAMMAINV.functionParameter.alpha.name', + detail: 'formula.functionList.GAMMAINV.functionParameter.alpha.detail', + example: '9', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.GAMMAINV.functionParameter.beta.name', + detail: 'formula.functionList.GAMMAINV.functionParameter.beta.detail', + example: '2', require: 1, repeat: 0, }, @@ -445,16 +466,30 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ abstract: 'formula.functionList.HYPGEOMDIST.abstract', functionParameter: [ { - name: 'formula.functionList.HYPGEOMDIST.functionParameter.number1.name', - detail: 'formula.functionList.HYPGEOMDIST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.HYPGEOMDIST.functionParameter.sampleS.name', + detail: 'formula.functionList.HYPGEOMDIST.functionParameter.sampleS.detail', + example: '1', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.HYPGEOMDIST.functionParameter.numberSample.name', + detail: 'formula.functionList.HYPGEOMDIST.functionParameter.numberSample.detail', + example: '4', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.HYPGEOMDIST.functionParameter.populationS.name', + detail: 'formula.functionList.HYPGEOMDIST.functionParameter.populationS.detail', + example: '8', require: 1, repeat: 0, }, { - name: 'formula.functionList.HYPGEOMDIST.functionParameter.number2.name', - detail: 'formula.functionList.HYPGEOMDIST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.HYPGEOMDIST.functionParameter.numberPop.name', + detail: 'formula.functionList.HYPGEOMDIST.functionParameter.numberPop.detail', + example: '20', require: 1, repeat: 0, }, @@ -467,16 +502,23 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ abstract: 'formula.functionList.LOGINV.abstract', functionParameter: [ { - name: 'formula.functionList.LOGINV.functionParameter.number1.name', - detail: 'formula.functionList.LOGINV.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.LOGINV.functionParameter.probability.name', + detail: 'formula.functionList.LOGINV.functionParameter.probability.detail', + example: '0.908789', require: 1, repeat: 0, }, { - name: 'formula.functionList.LOGINV.functionParameter.number2.name', - detail: 'formula.functionList.LOGINV.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.LOGINV.functionParameter.mean.name', + detail: 'formula.functionList.LOGINV.functionParameter.mean.detail', + example: '40', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.LOGINV.functionParameter.standardDev.name', + detail: 'formula.functionList.LOGINV.functionParameter.standardDev.detail', + example: '1.5', require: 1, repeat: 0, }, @@ -489,16 +531,23 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ abstract: 'formula.functionList.LOGNORMDIST.abstract', functionParameter: [ { - name: 'formula.functionList.LOGNORMDIST.functionParameter.number1.name', - detail: 'formula.functionList.LOGNORMDIST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.LOGNORMDIST.functionParameter.x.name', + detail: 'formula.functionList.LOGNORMDIST.functionParameter.x.detail', + example: '42', require: 1, repeat: 0, }, { - name: 'formula.functionList.LOGNORMDIST.functionParameter.number2.name', - detail: 'formula.functionList.LOGNORMDIST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.LOGNORMDIST.functionParameter.mean.name', + detail: 'formula.functionList.LOGNORMDIST.functionParameter.mean.detail', + example: '40', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.LOGNORMDIST.functionParameter.standardDev.name', + detail: 'formula.functionList.LOGNORMDIST.functionParameter.standardDev.detail', + example: '1.5', require: 1, repeat: 0, }, @@ -513,16 +562,16 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ { name: 'formula.functionList.MODE.functionParameter.number1.name', detail: 'formula.functionList.MODE.functionParameter.number1.detail', - example: 'A1:A20', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.MODE.functionParameter.number2.name', detail: 'formula.functionList.MODE.functionParameter.number2.detail', - example: 'A1:A20', - require: 1, - repeat: 0, + example: '2', + require: 0, + repeat: 1, }, ], }, @@ -533,16 +582,23 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ abstract: 'formula.functionList.NEGBINOMDIST.abstract', functionParameter: [ { - name: 'formula.functionList.NEGBINOMDIST.functionParameter.number1.name', - detail: 'formula.functionList.NEGBINOMDIST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.NEGBINOMDIST.functionParameter.numberF.name', + detail: 'formula.functionList.NEGBINOMDIST.functionParameter.numberF.detail', + example: '10', require: 1, repeat: 0, }, { - name: 'formula.functionList.NEGBINOMDIST.functionParameter.number2.name', - detail: 'formula.functionList.NEGBINOMDIST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.NEGBINOMDIST.functionParameter.numberS.name', + detail: 'formula.functionList.NEGBINOMDIST.functionParameter.numberS.detail', + example: '5', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.NEGBINOMDIST.functionParameter.probabilityS.name', + detail: 'formula.functionList.NEGBINOMDIST.functionParameter.probabilityS.detail', + example: '0.25', require: 1, repeat: 0, }, @@ -650,16 +706,16 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ abstract: 'formula.functionList.PERCENTILE.abstract', functionParameter: [ { - name: 'formula.functionList.PERCENTILE.functionParameter.number1.name', - detail: 'formula.functionList.PERCENTILE.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.PERCENTILE.functionParameter.array.name', + detail: 'formula.functionList.PERCENTILE.functionParameter.array.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.PERCENTILE.functionParameter.number2.name', - detail: 'formula.functionList.PERCENTILE.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.PERCENTILE.functionParameter.k.name', + detail: 'formula.functionList.PERCENTILE.functionParameter.k.detail', + example: '0.3', require: 1, repeat: 0, }, @@ -672,19 +728,26 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ abstract: 'formula.functionList.PERCENTRANK.abstract', functionParameter: [ { - name: 'formula.functionList.PERCENTRANK.functionParameter.number1.name', - detail: 'formula.functionList.PERCENTRANK.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.PERCENTRANK.functionParameter.array.name', + detail: 'formula.functionList.PERCENTRANK.functionParameter.array.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.PERCENTRANK.functionParameter.number2.name', - detail: 'formula.functionList.PERCENTRANK.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.PERCENTRANK.functionParameter.x.name', + detail: 'formula.functionList.PERCENTRANK.functionParameter.x.detail', + example: '1.5', require: 1, repeat: 0, }, + { + name: 'formula.functionList.PERCENTRANK.functionParameter.significance.name', + detail: 'formula.functionList.PERCENTRANK.functionParameter.significance.detail', + example: '3', + require: 0, + repeat: 0, + }, ], }, { @@ -694,16 +757,23 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ abstract: 'formula.functionList.POISSON.abstract', functionParameter: [ { - name: 'formula.functionList.POISSON.functionParameter.number1.name', - detail: 'formula.functionList.POISSON.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.POISSON.functionParameter.x.name', + detail: 'formula.functionList.POISSON.functionParameter.x.detail', + example: '2', require: 1, repeat: 0, }, { - name: 'formula.functionList.POISSON.functionParameter.number2.name', - detail: 'formula.functionList.POISSON.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.POISSON.functionParameter.mean.name', + detail: 'formula.functionList.POISSON.functionParameter.mean.detail', + example: '5', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.POISSON.functionParameter.cumulative.name', + detail: 'formula.functionList.POISSON.functionParameter.cumulative.detail', + example: 'true', require: 1, repeat: 0, }, @@ -716,16 +786,16 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ abstract: 'formula.functionList.QUARTILE.abstract', functionParameter: [ { - name: 'formula.functionList.QUARTILE.functionParameter.number1.name', - detail: 'formula.functionList.QUARTILE.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.QUARTILE.functionParameter.array.name', + detail: 'formula.functionList.QUARTILE.functionParameter.array.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.QUARTILE.functionParameter.number2.name', - detail: 'formula.functionList.QUARTILE.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.QUARTILE.functionParameter.quart.name', + detail: 'formula.functionList.QUARTILE.functionParameter.quart.detail', + example: '1', require: 1, repeat: 0, }, @@ -811,16 +881,23 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ abstract: 'formula.functionList.TDIST.abstract', functionParameter: [ { - name: 'formula.functionList.TDIST.functionParameter.number1.name', - detail: 'formula.functionList.TDIST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.TDIST.functionParameter.x.name', + detail: 'formula.functionList.TDIST.functionParameter.x.detail', + example: '8', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.TDIST.functionParameter.degFreedom.name', + detail: 'formula.functionList.TDIST.functionParameter.degFreedom.detail', + example: '3', require: 1, repeat: 0, }, { - name: 'formula.functionList.TDIST.functionParameter.number2.name', - detail: 'formula.functionList.TDIST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.TDIST.functionParameter.tails.name', + detail: 'formula.functionList.TDIST.functionParameter.tails.detail', + example: '1', require: 1, repeat: 0, }, @@ -833,16 +910,16 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ abstract: 'formula.functionList.TINV.abstract', functionParameter: [ { - name: 'formula.functionList.TINV.functionParameter.number1.name', - detail: 'formula.functionList.TINV.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.TINV.functionParameter.probability.name', + detail: 'formula.functionList.TINV.functionParameter.probability.detail', + example: '0.75', require: 1, repeat: 0, }, { - name: 'formula.functionList.TINV.functionParameter.number2.name', - detail: 'formula.functionList.TINV.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.TINV.functionParameter.degFreedom.name', + detail: 'formula.functionList.TINV.functionParameter.degFreedom.detail', + example: '2', require: 1, repeat: 0, }, @@ -855,16 +932,30 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ abstract: 'formula.functionList.TTEST.abstract', functionParameter: [ { - name: 'formula.functionList.TTEST.functionParameter.number1.name', - detail: 'formula.functionList.TTEST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.TTEST.functionParameter.array1.name', + detail: 'formula.functionList.TTEST.functionParameter.array1.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.TTEST.functionParameter.number2.name', - detail: 'formula.functionList.TTEST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.TTEST.functionParameter.array2.name', + detail: 'formula.functionList.TTEST.functionParameter.array2.detail', + example: 'B1:B4', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.TTEST.functionParameter.tails.name', + detail: 'formula.functionList.TTEST.functionParameter.tails.detail', + example: '2', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.TTEST.functionParameter.type.name', + detail: 'formula.functionList.TTEST.functionParameter.type.detail', + example: '1', require: 1, repeat: 0, }, @@ -921,16 +1012,30 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ abstract: 'formula.functionList.WEIBULL.abstract', functionParameter: [ { - name: 'formula.functionList.WEIBULL.functionParameter.number1.name', - detail: 'formula.functionList.WEIBULL.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.WEIBULL.functionParameter.x.name', + detail: 'formula.functionList.WEIBULL.functionParameter.x.detail', + example: '105', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.WEIBULL.functionParameter.alpha.name', + detail: 'formula.functionList.WEIBULL.functionParameter.alpha.detail', + example: '20', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.WEIBULL.functionParameter.beta.name', + detail: 'formula.functionList.WEIBULL.functionParameter.beta.detail', + example: '100', require: 1, repeat: 0, }, { - name: 'formula.functionList.WEIBULL.functionParameter.number2.name', - detail: 'formula.functionList.WEIBULL.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.WEIBULL.functionParameter.cumulative.name', + detail: 'formula.functionList.WEIBULL.functionParameter.cumulative.detail', + example: 'true', require: 1, repeat: 0, }, @@ -943,19 +1048,26 @@ export const FUNCTION_LIST_COMPATIBILITY: IFunctionInfo[] = [ abstract: 'formula.functionList.ZTEST.abstract', functionParameter: [ { - name: 'formula.functionList.ZTEST.functionParameter.number1.name', - detail: 'formula.functionList.ZTEST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.ZTEST.functionParameter.array.name', + detail: 'formula.functionList.ZTEST.functionParameter.array.detail', + example: 'A2:A11', require: 1, repeat: 0, }, { - name: 'formula.functionList.ZTEST.functionParameter.number2.name', - detail: 'formula.functionList.ZTEST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.ZTEST.functionParameter.x.name', + detail: 'formula.functionList.ZTEST.functionParameter.x.detail', + example: '4', require: 1, repeat: 0, }, + { + name: 'formula.functionList.ZTEST.functionParameter.sigma.name', + detail: 'formula.functionList.ZTEST.functionParameter.sigma.detail', + example: '10', + require: 0, + repeat: 0, + }, ], }, ]; diff --git a/packages/sheets-formula/src/services/function-list/financial.ts b/packages/sheets-formula/src/services/function-list/financial.ts index 851c0ca9574f..a543320d45ea 100644 --- a/packages/sheets-formula/src/services/function-list/financial.ts +++ b/packages/sheets-formula/src/services/function-list/financial.ts @@ -823,7 +823,7 @@ export const FUNCTION_LIST_FINANCIAL: IFunctionInfo[] = [ { name: 'formula.functionList.FVSCHEDULE.functionParameter.schedule.name', detail: 'formula.functionList.FVSCHEDULE.functionParameter.schedule.detail', - example: '{0.09,0.11,0.1}', + example: 'A1:A4', require: 1, repeat: 0, }, @@ -931,7 +931,7 @@ export const FUNCTION_LIST_FINANCIAL: IFunctionInfo[] = [ { name: 'formula.functionList.IRR.functionParameter.values.name', detail: 'formula.functionList.IRR.functionParameter.values.detail', - example: '{-700000,120000,150000,180000,210000,260000}', + example: 'A1:A4', require: 1, repeat: 0, }, @@ -1039,7 +1039,7 @@ export const FUNCTION_LIST_FINANCIAL: IFunctionInfo[] = [ { name: 'formula.functionList.MIRR.functionParameter.values.name', detail: 'formula.functionList.MIRR.functionParameter.values.detail', - example: '{-120000,39000,30000,21000,37000,46000}', + example: 'A1:A4', require: 1, repeat: 0, }, @@ -1140,7 +1140,7 @@ export const FUNCTION_LIST_FINANCIAL: IFunctionInfo[] = [ { name: 'formula.functionList.NPV.functionParameter.value1.name', detail: 'formula.functionList.NPV.functionParameter.value1.detail', - example: '{-10000,3000,4200,6800}', + example: 'A1:A4', require: 1, repeat: 0, }, @@ -2078,14 +2078,14 @@ export const FUNCTION_LIST_FINANCIAL: IFunctionInfo[] = [ { name: 'formula.functionList.XIRR.functionParameter.values.name', detail: 'formula.functionList.XIRR.functionParameter.values.detail', - example: '{-10000,2750,4250,3250,2750}', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.XIRR.functionParameter.dates.name', detail: 'formula.functionList.XIRR.functionParameter.dates.detail', - example: '{39448,39508,39751,39859,39904}', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -2114,14 +2114,14 @@ export const FUNCTION_LIST_FINANCIAL: IFunctionInfo[] = [ { name: 'formula.functionList.XNPV.functionParameter.values.name', detail: 'formula.functionList.XNPV.functionParameter.values.detail', - example: '{-10000,2750,4250,3250,2750}', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.XNPV.functionParameter.dates.name', detail: 'formula.functionList.XNPV.functionParameter.dates.detail', - example: '{39448,39508,39751,39859,39904}', + example: 'B1:B4', require: 1, repeat: 0, }, diff --git a/packages/sheets-formula/src/services/function-list/lookup.ts b/packages/sheets-formula/src/services/function-list/lookup.ts index d12572aac6ad..f1390e54866f 100644 --- a/packages/sheets-formula/src/services/function-list/lookup.ts +++ b/packages/sheets-formula/src/services/function-list/lookup.ts @@ -113,7 +113,7 @@ export const FUNCTION_LIST_LOOKUP: IFunctionInfo[] = [ { name: 'formula.functionList.CHOOSECOLS.functionParameter.array.name', detail: 'formula.functionList.CHOOSECOLS.functionParameter.array.detail', - example: '{1,2,3;2,3,4}', + example: 'A1:C2', require: 1, repeat: 0, }, @@ -142,7 +142,7 @@ export const FUNCTION_LIST_LOOKUP: IFunctionInfo[] = [ { name: 'formula.functionList.CHOOSEROWS.functionParameter.array.name', detail: 'formula.functionList.CHOOSEROWS.functionParameter.array.detail', - example: '{1,2,3;2,3,4}', + example: 'A1:C2', require: 1, repeat: 0, }, diff --git a/packages/sheets-formula/src/services/function-list/math.ts b/packages/sheets-formula/src/services/function-list/math.ts index c8ed26770158..2220c92e2a44 100644 --- a/packages/sheets-formula/src/services/function-list/math.ts +++ b/packages/sheets-formula/src/services/function-list/math.ts @@ -782,7 +782,7 @@ export const FUNCTION_LIST_MATH: IFunctionInfo[] = [ { name: 'formula.functionList.MDETERM.functionParameter.array.name', detail: 'formula.functionList.MDETERM.functionParameter.array.detail', - example: '{3,6,1;1,1,0;3,10,2}', + example: 'A1:C3', require: 1, repeat: 0, }, @@ -797,7 +797,7 @@ export const FUNCTION_LIST_MATH: IFunctionInfo[] = [ { name: 'formula.functionList.MINVERSE.functionParameter.array.name', detail: 'formula.functionList.MINVERSE.functionParameter.array.detail', - example: '{3,6,1;1,1,0;3,10,2}', + example: 'A1:C3', require: 1, repeat: 0, }, @@ -1231,7 +1231,7 @@ export const FUNCTION_LIST_MATH: IFunctionInfo[] = [ { name: 'formula.functionList.SERIESSUM.functionParameter.coefficients.name', detail: 'formula.functionList.SERIESSUM.functionParameter.coefficients.detail', - example: '{1,-0.5,0.041666667,-0.001388889}', + example: 'A1:A4', require: 1, repeat: 0, }, diff --git a/packages/sheets-formula/src/services/function-list/statistical.ts b/packages/sheets-formula/src/services/function-list/statistical.ts index 19df3ea4c829..0a83fb89552b 100644 --- a/packages/sheets-formula/src/services/function-list/statistical.ts +++ b/packages/sheets-formula/src/services/function-list/statistical.ts @@ -455,14 +455,14 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.CHISQ_TEST.functionParameter.actualRange.name', detail: 'formula.functionList.CHISQ_TEST.functionParameter.actualRange.detail', - example: '{58,35;11,25;10,23}', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.CHISQ_TEST.functionParameter.expectedRange.name', detail: 'formula.functionList.CHISQ_TEST.functionParameter.expectedRange.detail', - example: '{45.35,47.65;17.56,18.44;16.09,16.91}', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -535,14 +535,14 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.CORREL.functionParameter.array1.name', detail: 'formula.functionList.CORREL.functionParameter.array1.detail', - example: '{3,2,4,5,6}', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.CORREL.functionParameter.array2.name', detail: 'formula.functionList.CORREL.functionParameter.array2.detail', - example: '{9,7,12,15,17}', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -676,14 +676,14 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.COVARIANCE_P.functionParameter.array1.name', detail: 'formula.functionList.COVARIANCE_P.functionParameter.array1.detail', - example: '{3,2,4,5,6}', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.COVARIANCE_P.functionParameter.array2.name', detail: 'formula.functionList.COVARIANCE_P.functionParameter.array2.detail', - example: '{9,7,12,15,17}', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -698,14 +698,14 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.COVARIANCE_S.functionParameter.array1.name', detail: 'formula.functionList.COVARIANCE_S.functionParameter.array1.detail', - example: '{3,2,4,5,6}', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.COVARIANCE_S.functionParameter.array2.name', detail: 'formula.functionList.COVARIANCE_S.functionParameter.array2.detail', - example: '{9,7,12,15,17}', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -894,14 +894,14 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.F_TEST.functionParameter.array1.name', detail: 'formula.functionList.F_TEST.functionParameter.array1.detail', - example: '{58,35;11,25;10,23}', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.F_TEST.functionParameter.array2.name', detail: 'formula.functionList.F_TEST.functionParameter.array2.detail', - example: '{45.35,47.65;17.56,18.44;16.09,16.91}', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -953,14 +953,14 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.FORECAST.functionParameter.knownYs.name', detail: 'formula.functionList.FORECAST.functionParameter.knownYs.detail', - example: '{6,7,9,15,21}', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.FORECAST.functionParameter.knownXs.name', detail: 'formula.functionList.FORECAST.functionParameter.knownXs.detail', - example: '{20,28,31,38,40}', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -1070,14 +1070,14 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.FORECAST_LINEAR.functionParameter.knownYs.name', detail: 'formula.functionList.FORECAST_LINEAR.functionParameter.knownYs.detail', - example: '{6,7,9,15,21}', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.FORECAST_LINEAR.functionParameter.knownXs.name', detail: 'formula.functionList.FORECAST_LINEAR.functionParameter.knownXs.detail', - example: '{20,28,31,38,40}', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -1090,16 +1090,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.FREQUENCY.abstract', functionParameter: [ { - name: 'formula.functionList.FREQUENCY.functionParameter.number1.name', - detail: 'formula.functionList.FREQUENCY.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.FREQUENCY.functionParameter.dataArray.name', + detail: 'formula.functionList.FREQUENCY.functionParameter.dataArray.detail', + example: 'A2:A10', require: 1, repeat: 0, }, { - name: 'formula.functionList.FREQUENCY.functionParameter.number2.name', - detail: 'formula.functionList.FREQUENCY.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.FREQUENCY.functionParameter.binsArray.name', + detail: 'formula.functionList.FREQUENCY.functionParameter.binsArray.detail', + example: 'B2:B4', require: 1, repeat: 0, }, @@ -1112,16 +1112,9 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.GAMMA.abstract', functionParameter: [ { - name: 'formula.functionList.GAMMA.functionParameter.number1.name', - detail: 'formula.functionList.GAMMA.functionParameter.number1.detail', - example: 'A1:A20', - require: 1, - repeat: 0, - }, - { - name: 'formula.functionList.GAMMA.functionParameter.number2.name', - detail: 'formula.functionList.GAMMA.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.GAMMA.functionParameter.number.name', + detail: 'formula.functionList.GAMMA.functionParameter.number.detail', + example: '2.5', require: 1, repeat: 0, }, @@ -1134,16 +1127,30 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.GAMMA_DIST.abstract', functionParameter: [ { - name: 'formula.functionList.GAMMA_DIST.functionParameter.number1.name', - detail: 'formula.functionList.GAMMA_DIST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.GAMMA_DIST.functionParameter.x.name', + detail: 'formula.functionList.GAMMA_DIST.functionParameter.x.detail', + example: '10', require: 1, repeat: 0, }, { - name: 'formula.functionList.GAMMA_DIST.functionParameter.number2.name', - detail: 'formula.functionList.GAMMA_DIST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.GAMMA_DIST.functionParameter.alpha.name', + detail: 'formula.functionList.GAMMA_DIST.functionParameter.alpha.detail', + example: '8', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.GAMMA_DIST.functionParameter.beta.name', + detail: 'formula.functionList.GAMMA_DIST.functionParameter.beta.detail', + example: '2', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.GAMMA_DIST.functionParameter.cumulative.name', + detail: 'formula.functionList.GAMMA_DIST.functionParameter.cumulative.detail', + example: 'true', require: 1, repeat: 0, }, @@ -1156,16 +1163,23 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.GAMMA_INV.abstract', functionParameter: [ { - name: 'formula.functionList.GAMMA_INV.functionParameter.number1.name', - detail: 'formula.functionList.GAMMA_INV.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.GAMMA_INV.functionParameter.probability.name', + detail: 'formula.functionList.GAMMA_INV.functionParameter.probability.detail', + example: '0.068094', require: 1, repeat: 0, }, { - name: 'formula.functionList.GAMMA_INV.functionParameter.number2.name', - detail: 'formula.functionList.GAMMA_INV.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.GAMMA_INV.functionParameter.alpha.name', + detail: 'formula.functionList.GAMMA_INV.functionParameter.alpha.detail', + example: '9', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.GAMMA_INV.functionParameter.beta.name', + detail: 'formula.functionList.GAMMA_INV.functionParameter.beta.detail', + example: '2', require: 1, repeat: 0, }, @@ -1178,16 +1192,9 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.GAMMALN.abstract', functionParameter: [ { - name: 'formula.functionList.GAMMALN.functionParameter.number1.name', - detail: 'formula.functionList.GAMMALN.functionParameter.number1.detail', - example: 'A1:A20', - require: 1, - repeat: 0, - }, - { - name: 'formula.functionList.GAMMALN.functionParameter.number2.name', - detail: 'formula.functionList.GAMMALN.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.GAMMALN.functionParameter.x.name', + detail: 'formula.functionList.GAMMALN.functionParameter.x.detail', + example: '4', require: 1, repeat: 0, }, @@ -1200,16 +1207,9 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.GAMMALN_PRECISE.abstract', functionParameter: [ { - name: 'formula.functionList.GAMMALN_PRECISE.functionParameter.number1.name', - detail: 'formula.functionList.GAMMALN_PRECISE.functionParameter.number1.detail', - example: 'A1:A20', - require: 1, - repeat: 0, - }, - { - name: 'formula.functionList.GAMMALN_PRECISE.functionParameter.number2.name', - detail: 'formula.functionList.GAMMALN_PRECISE.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.GAMMALN_PRECISE.functionParameter.x.name', + detail: 'formula.functionList.GAMMALN_PRECISE.functionParameter.x.detail', + example: '4', require: 1, repeat: 0, }, @@ -1222,16 +1222,9 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.GAUSS.abstract', functionParameter: [ { - name: 'formula.functionList.GAUSS.functionParameter.number1.name', - detail: 'formula.functionList.GAUSS.functionParameter.number1.detail', - example: 'A1:A20', - require: 1, - repeat: 0, - }, - { - name: 'formula.functionList.GAUSS.functionParameter.number2.name', - detail: 'formula.functionList.GAUSS.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.GAUSS.functionParameter.z.name', + detail: 'formula.functionList.GAUSS.functionParameter.z.detail', + example: '2', require: 1, repeat: 0, }, @@ -1246,16 +1239,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.GEOMEAN.functionParameter.number1.name', detail: 'formula.functionList.GEOMEAN.functionParameter.number1.detail', - example: 'A1:A20', + example: '1', require: 1, repeat: 0, }, { name: 'formula.functionList.GEOMEAN.functionParameter.number2.name', detail: 'formula.functionList.GEOMEAN.functionParameter.number2.detail', - example: 'A1:A20', - require: 1, - repeat: 0, + example: '2', + require: 0, + repeat: 1, }, ], }, @@ -1266,17 +1259,31 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.GROWTH.abstract', functionParameter: [ { - name: 'formula.functionList.GROWTH.functionParameter.number1.name', - detail: 'formula.functionList.GROWTH.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.GROWTH.functionParameter.knownYs.name', + detail: 'formula.functionList.GROWTH.functionParameter.knownYs.detail', + example: 'B2:B7', require: 1, repeat: 0, }, { - name: 'formula.functionList.GROWTH.functionParameter.number2.name', - detail: 'formula.functionList.GROWTH.functionParameter.number2.detail', - example: 'A1:A20', - require: 1, + name: 'formula.functionList.GROWTH.functionParameter.knownXs.name', + detail: 'formula.functionList.GROWTH.functionParameter.knownXs.detail', + example: 'A2:A7', + require: 0, + repeat: 0, + }, + { + name: 'formula.functionList.GROWTH.functionParameter.newXs.name', + detail: 'formula.functionList.GROWTH.functionParameter.newXs.detail', + example: 'A9:A10', + require: 0, + repeat: 0, + }, + { + name: 'formula.functionList.GROWTH.functionParameter.constb.name', + detail: 'formula.functionList.GROWTH.functionParameter.constb.detail', + example: 'true', + require: 0, repeat: 0, }, ], @@ -1290,16 +1297,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.HARMEAN.functionParameter.number1.name', detail: 'formula.functionList.HARMEAN.functionParameter.number1.detail', - example: 'A1:A20', + example: '1', require: 1, repeat: 0, }, { name: 'formula.functionList.HARMEAN.functionParameter.number2.name', detail: 'formula.functionList.HARMEAN.functionParameter.number2.detail', - example: 'A1:A20', - require: 1, - repeat: 0, + example: '2', + require: 0, + repeat: 1, }, ], }, @@ -1310,16 +1317,37 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.HYPGEOM_DIST.abstract', functionParameter: [ { - name: 'formula.functionList.HYPGEOM_DIST.functionParameter.number1.name', - detail: 'formula.functionList.HYPGEOM_DIST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.HYPGEOM_DIST.functionParameter.sampleS.name', + detail: 'formula.functionList.HYPGEOM_DIST.functionParameter.sampleS.detail', + example: '1', require: 1, repeat: 0, }, { - name: 'formula.functionList.HYPGEOM_DIST.functionParameter.number2.name', - detail: 'formula.functionList.HYPGEOM_DIST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.HYPGEOM_DIST.functionParameter.numberSample.name', + detail: 'formula.functionList.HYPGEOM_DIST.functionParameter.numberSample.detail', + example: '4', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.HYPGEOM_DIST.functionParameter.populationS.name', + detail: 'formula.functionList.HYPGEOM_DIST.functionParameter.populationS.detail', + example: '8', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.HYPGEOM_DIST.functionParameter.numberPop.name', + detail: 'formula.functionList.HYPGEOM_DIST.functionParameter.numberPop.detail', + example: '20', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.HYPGEOM_DIST.functionParameter.cumulative.name', + detail: 'formula.functionList.HYPGEOM_DIST.functionParameter.cumulative.detail', + example: 'true', require: 1, repeat: 0, }, @@ -1334,14 +1362,14 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.INTERCEPT.functionParameter.knownYs.name', detail: 'formula.functionList.INTERCEPT.functionParameter.knownYs.detail', - example: '{6,7,9,15,21}', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.INTERCEPT.functionParameter.knownXs.name', detail: 'formula.functionList.INTERCEPT.functionParameter.knownXs.detail', - example: '{20,28,31,38,40}', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -1356,16 +1384,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.KURT.functionParameter.number1.name', detail: 'formula.functionList.KURT.functionParameter.number1.detail', - example: 'A1:A20', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.KURT.functionParameter.number2.name', detail: 'formula.functionList.KURT.functionParameter.number2.detail', - example: 'A1:A20', - require: 1, - repeat: 0, + example: '4', + require: 0, + repeat: 1, }, ], }, @@ -1376,16 +1404,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.LARGE.abstract', functionParameter: [ { - name: 'formula.functionList.LARGE.functionParameter.number1.name', - detail: 'formula.functionList.LARGE.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.LARGE.functionParameter.array.name', + detail: 'formula.functionList.LARGE.functionParameter.array.detail', + example: 'A2:B6', require: 1, repeat: 0, }, { - name: 'formula.functionList.LARGE.functionParameter.number2.name', - detail: 'formula.functionList.LARGE.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.LARGE.functionParameter.k.name', + detail: 'formula.functionList.LARGE.functionParameter.k.detail', + example: '3', require: 1, repeat: 0, }, @@ -1442,16 +1470,30 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.LOGNORM_DIST.abstract', functionParameter: [ { - name: 'formula.functionList.LOGNORM_DIST.functionParameter.number1.name', - detail: 'formula.functionList.LOGNORM_DIST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.LOGNORM_DIST.functionParameter.x.name', + detail: 'formula.functionList.LOGNORM_DIST.functionParameter.x.detail', + example: '42', require: 1, repeat: 0, }, { - name: 'formula.functionList.LOGNORM_DIST.functionParameter.number2.name', - detail: 'formula.functionList.LOGNORM_DIST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.LOGNORM_DIST.functionParameter.mean.name', + detail: 'formula.functionList.LOGNORM_DIST.functionParameter.mean.detail', + example: '40', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.LOGNORM_DIST.functionParameter.standardDev.name', + detail: 'formula.functionList.LOGNORM_DIST.functionParameter.standardDev.detail', + example: '1.5', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.LOGNORM_DIST.functionParameter.cumulative.name', + detail: 'formula.functionList.LOGNORM_DIST.functionParameter.cumulative.detail', + example: 'true', require: 1, repeat: 0, }, @@ -1464,16 +1506,23 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.LOGNORM_INV.abstract', functionParameter: [ { - name: 'formula.functionList.LOGNORM_INV.functionParameter.number1.name', - detail: 'formula.functionList.LOGNORM_INV.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.LOGNORM_INV.functionParameter.probability.name', + detail: 'formula.functionList.LOGNORM_INV.functionParameter.probability.detail', + example: '0.908789', require: 1, repeat: 0, }, { - name: 'formula.functionList.LOGNORM_INV.functionParameter.number2.name', - detail: 'formula.functionList.LOGNORM_INV.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.LOGNORM_INV.functionParameter.mean.name', + detail: 'formula.functionList.LOGNORM_INV.functionParameter.mean.detail', + example: '40', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.LOGNORM_INV.functionParameter.standardDev.name', + detail: 'formula.functionList.LOGNORM_INV.functionParameter.standardDev.detail', + example: '1.5', require: 1, repeat: 0, }, @@ -1576,16 +1625,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.MEDIAN.functionParameter.number1.name', detail: 'formula.functionList.MEDIAN.functionParameter.number1.detail', - example: 'A1:A20', + example: '1', require: 1, repeat: 0, }, { name: 'formula.functionList.MEDIAN.functionParameter.number2.name', detail: 'formula.functionList.MEDIAN.functionParameter.number2.detail', - example: 'A1:A20', - require: 1, - repeat: 0, + example: '2', + require: 0, + repeat: 1, }, ], }, @@ -1686,16 +1735,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.MODE_MULT.functionParameter.number1.name', detail: 'formula.functionList.MODE_MULT.functionParameter.number1.detail', - example: 'A1:A20', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.MODE_MULT.functionParameter.number2.name', detail: 'formula.functionList.MODE_MULT.functionParameter.number2.detail', - example: 'A1:A20', - require: 1, - repeat: 0, + example: '2', + require: 0, + repeat: 1, }, ], }, @@ -1708,16 +1757,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.MODE_SNGL.functionParameter.number1.name', detail: 'formula.functionList.MODE_SNGL.functionParameter.number1.detail', - example: 'A1:A20', + example: 'A1:A4', require: 1, repeat: 0, }, { name: 'formula.functionList.MODE_SNGL.functionParameter.number2.name', detail: 'formula.functionList.MODE_SNGL.functionParameter.number2.detail', - example: 'A1:A20', - require: 1, - repeat: 0, + example: '2', + require: 0, + repeat: 1, }, ], }, @@ -1728,16 +1777,30 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.NEGBINOM_DIST.abstract', functionParameter: [ { - name: 'formula.functionList.NEGBINOM_DIST.functionParameter.number1.name', - detail: 'formula.functionList.NEGBINOM_DIST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.NEGBINOM_DIST.functionParameter.numberF.name', + detail: 'formula.functionList.NEGBINOM_DIST.functionParameter.numberF.detail', + example: '10', require: 1, repeat: 0, }, { - name: 'formula.functionList.NEGBINOM_DIST.functionParameter.number2.name', - detail: 'formula.functionList.NEGBINOM_DIST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.NEGBINOM_DIST.functionParameter.numberS.name', + detail: 'formula.functionList.NEGBINOM_DIST.functionParameter.numberS.detail', + example: '5', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.NEGBINOM_DIST.functionParameter.probabilityS.name', + detail: 'formula.functionList.NEGBINOM_DIST.functionParameter.probabilityS.detail', + example: '0.25', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.NEGBINOM_DIST.functionParameter.cumulative.name', + detail: 'formula.functionList.NEGBINOM_DIST.functionParameter.cumulative.detail', + example: 'true', require: 1, repeat: 0, }, @@ -1852,16 +1915,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.PEARSON.abstract', functionParameter: [ { - name: 'formula.functionList.PEARSON.functionParameter.number1.name', - detail: 'formula.functionList.PEARSON.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.PEARSON.functionParameter.array1.name', + detail: 'formula.functionList.PEARSON.functionParameter.array1.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.PEARSON.functionParameter.number2.name', - detail: 'formula.functionList.PEARSON.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.PEARSON.functionParameter.array2.name', + detail: 'formula.functionList.PEARSON.functionParameter.array2.detail', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -1874,16 +1937,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.PERCENTILE_EXC.abstract', functionParameter: [ { - name: 'formula.functionList.PERCENTILE_EXC.functionParameter.number1.name', - detail: 'formula.functionList.PERCENTILE_EXC.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.PERCENTILE_EXC.functionParameter.array.name', + detail: 'formula.functionList.PERCENTILE_EXC.functionParameter.array.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.PERCENTILE_EXC.functionParameter.number2.name', - detail: 'formula.functionList.PERCENTILE_EXC.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.PERCENTILE_EXC.functionParameter.k.name', + detail: 'formula.functionList.PERCENTILE_EXC.functionParameter.k.detail', + example: '0.3', require: 1, repeat: 0, }, @@ -1896,16 +1959,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.PERCENTILE_INC.abstract', functionParameter: [ { - name: 'formula.functionList.PERCENTILE_INC.functionParameter.number1.name', - detail: 'formula.functionList.PERCENTILE_INC.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.PERCENTILE_INC.functionParameter.array.name', + detail: 'formula.functionList.PERCENTILE_INC.functionParameter.array.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.PERCENTILE_INC.functionParameter.number2.name', - detail: 'formula.functionList.PERCENTILE_INC.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.PERCENTILE_INC.functionParameter.k.name', + detail: 'formula.functionList.PERCENTILE_INC.functionParameter.k.detail', + example: '0.3', require: 1, repeat: 0, }, @@ -1918,19 +1981,26 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.PERCENTRANK_EXC.abstract', functionParameter: [ { - name: 'formula.functionList.PERCENTRANK_EXC.functionParameter.number1.name', - detail: 'formula.functionList.PERCENTRANK_EXC.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.PERCENTRANK_EXC.functionParameter.array.name', + detail: 'formula.functionList.PERCENTRANK_EXC.functionParameter.array.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.PERCENTRANK_EXC.functionParameter.number2.name', - detail: 'formula.functionList.PERCENTRANK_EXC.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.PERCENTRANK_EXC.functionParameter.x.name', + detail: 'formula.functionList.PERCENTRANK_EXC.functionParameter.x.detail', + example: '1.5', require: 1, repeat: 0, }, + { + name: 'formula.functionList.PERCENTRANK_EXC.functionParameter.significance.name', + detail: 'formula.functionList.PERCENTRANK_EXC.functionParameter.significance.detail', + example: '3', + require: 0, + repeat: 0, + }, ], }, { @@ -1940,19 +2010,26 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.PERCENTRANK_INC.abstract', functionParameter: [ { - name: 'formula.functionList.PERCENTRANK_INC.functionParameter.number1.name', - detail: 'formula.functionList.PERCENTRANK_INC.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.PERCENTRANK_INC.functionParameter.array.name', + detail: 'formula.functionList.PERCENTRANK_INC.functionParameter.array.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.PERCENTRANK_INC.functionParameter.number2.name', - detail: 'formula.functionList.PERCENTRANK_INC.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.PERCENTRANK_INC.functionParameter.x.name', + detail: 'formula.functionList.PERCENTRANK_INC.functionParameter.x.detail', + example: '1.5', require: 1, repeat: 0, }, + { + name: 'formula.functionList.PERCENTRANK_INC.functionParameter.significance.name', + detail: 'formula.functionList.PERCENTRANK_INC.functionParameter.significance.detail', + example: '3', + require: 0, + repeat: 0, + }, ], }, { @@ -1962,16 +2039,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.PERMUT.abstract', functionParameter: [ { - name: 'formula.functionList.PERMUT.functionParameter.number1.name', - detail: 'formula.functionList.PERMUT.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.PERMUT.functionParameter.number.name', + detail: 'formula.functionList.PERMUT.functionParameter.number.detail', + example: '8', require: 1, repeat: 0, }, { - name: 'formula.functionList.PERMUT.functionParameter.number2.name', - detail: 'formula.functionList.PERMUT.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.PERMUT.functionParameter.numberChosen.name', + detail: 'formula.functionList.PERMUT.functionParameter.numberChosen.detail', + example: '2', require: 1, repeat: 0, }, @@ -1984,16 +2061,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.PERMUTATIONA.abstract', functionParameter: [ { - name: 'formula.functionList.PERMUTATIONA.functionParameter.number1.name', - detail: 'formula.functionList.PERMUTATIONA.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.PERMUT.functionParameter.number.name', + detail: 'formula.functionList.PERMUT.functionParameter.number.detail', + example: '8', require: 1, repeat: 0, }, { - name: 'formula.functionList.PERMUTATIONA.functionParameter.number2.name', - detail: 'formula.functionList.PERMUTATIONA.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.PERMUT.functionParameter.numberChosen.name', + detail: 'formula.functionList.PERMUT.functionParameter.numberChosen.detail', + example: '2', require: 1, repeat: 0, }, @@ -2006,16 +2083,9 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.PHI.abstract', functionParameter: [ { - name: 'formula.functionList.PHI.functionParameter.number1.name', - detail: 'formula.functionList.PHI.functionParameter.number1.detail', - example: 'A1:A20', - require: 1, - repeat: 0, - }, - { - name: 'formula.functionList.PHI.functionParameter.number2.name', - detail: 'formula.functionList.PHI.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.PHI.functionParameter.x.name', + detail: 'formula.functionList.PHI.functionParameter.x.detail', + example: '0.75', require: 1, repeat: 0, }, @@ -2028,16 +2098,23 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.POISSON_DIST.abstract', functionParameter: [ { - name: 'formula.functionList.POISSON_DIST.functionParameter.number1.name', - detail: 'formula.functionList.POISSON_DIST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.POISSON_DIST.functionParameter.x.name', + detail: 'formula.functionList.POISSON_DIST.functionParameter.x.detail', + example: '2', require: 1, repeat: 0, }, { - name: 'formula.functionList.POISSON_DIST.functionParameter.number2.name', - detail: 'formula.functionList.POISSON_DIST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.POISSON_DIST.functionParameter.mean.name', + detail: 'formula.functionList.POISSON_DIST.functionParameter.mean.detail', + example: '5', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.POISSON_DIST.functionParameter.cumulative.name', + detail: 'formula.functionList.POISSON_DIST.functionParameter.cumulative.detail', + example: 'true', require: 1, repeat: 0, }, @@ -2050,19 +2127,33 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.PROB.abstract', functionParameter: [ { - name: 'formula.functionList.PROB.functionParameter.number1.name', - detail: 'formula.functionList.PROB.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.PROB.functionParameter.xRange.name', + detail: 'formula.functionList.PROB.functionParameter.xRange.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.PROB.functionParameter.number2.name', - detail: 'formula.functionList.PROB.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.PROB.functionParameter.probRange.name', + detail: 'formula.functionList.PROB.functionParameter.probRange.detail', + example: 'B1:B4', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.PROB.functionParameter.lowerLimit.name', + detail: 'formula.functionList.PROB.functionParameter.lowerLimit.detail', + example: '1', require: 1, repeat: 0, }, + { + name: 'formula.functionList.PROB.functionParameter.upperLimit.name', + detail: 'formula.functionList.PROB.functionParameter.upperLimit.detail', + example: '3', + require: 0, + repeat: 0, + }, ], }, { @@ -2072,16 +2163,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.QUARTILE_EXC.abstract', functionParameter: [ { - name: 'formula.functionList.QUARTILE_EXC.functionParameter.number1.name', - detail: 'formula.functionList.QUARTILE_EXC.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.QUARTILE_EXC.functionParameter.array.name', + detail: 'formula.functionList.QUARTILE_EXC.functionParameter.array.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.QUARTILE_EXC.functionParameter.number2.name', - detail: 'formula.functionList.QUARTILE_EXC.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.QUARTILE_EXC.functionParameter.quart.name', + detail: 'formula.functionList.QUARTILE_EXC.functionParameter.quart.detail', + example: '1', require: 1, repeat: 0, }, @@ -2094,16 +2185,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.QUARTILE_INC.abstract', functionParameter: [ { - name: 'formula.functionList.QUARTILE_INC.functionParameter.number1.name', - detail: 'formula.functionList.QUARTILE_INC.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.QUARTILE_INC.functionParameter.array.name', + detail: 'formula.functionList.QUARTILE_INC.functionParameter.array.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.QUARTILE_INC.functionParameter.number2.name', - detail: 'formula.functionList.QUARTILE_INC.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.QUARTILE_INC.functionParameter.quart.name', + detail: 'formula.functionList.QUARTILE_INC.functionParameter.quart.detail', + example: '1', require: 1, repeat: 0, }, @@ -2174,16 +2265,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.RSQ.abstract', functionParameter: [ { - name: 'formula.functionList.RSQ.functionParameter.number1.name', - detail: 'formula.functionList.RSQ.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.RSQ.functionParameter.array1.name', + detail: 'formula.functionList.RSQ.functionParameter.array1.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.RSQ.functionParameter.number2.name', - detail: 'formula.functionList.RSQ.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.RSQ.functionParameter.array2.name', + detail: 'formula.functionList.RSQ.functionParameter.array2.detail', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -2198,16 +2289,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.SKEW.functionParameter.number1.name', detail: 'formula.functionList.SKEW.functionParameter.number1.detail', - example: 'A1:A20', + example: 'A1:C3', require: 1, repeat: 0, }, { name: 'formula.functionList.SKEW.functionParameter.number2.name', detail: 'formula.functionList.SKEW.functionParameter.number2.detail', - example: 'A1:A20', - require: 1, - repeat: 0, + example: '4', + require: 0, + repeat: 1, }, ], }, @@ -2220,16 +2311,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ { name: 'formula.functionList.SKEW_P.functionParameter.number1.name', detail: 'formula.functionList.SKEW_P.functionParameter.number1.detail', - example: 'A1:A20', + example: 'A1:C3', require: 1, repeat: 0, }, { name: 'formula.functionList.SKEW_P.functionParameter.number2.name', detail: 'formula.functionList.SKEW_P.functionParameter.number2.detail', - example: 'A1:A20', - require: 1, - repeat: 0, + example: '4', + require: 0, + repeat: 1, }, ], }, @@ -2240,16 +2331,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.SLOPE.abstract', functionParameter: [ { - name: 'formula.functionList.SLOPE.functionParameter.number1.name', - detail: 'formula.functionList.SLOPE.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.SLOPE.functionParameter.knownYs.name', + detail: 'formula.functionList.SLOPE.functionParameter.knownYs.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.SLOPE.functionParameter.number2.name', - detail: 'formula.functionList.SLOPE.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.SLOPE.functionParameter.knownXs.name', + detail: 'formula.functionList.SLOPE.functionParameter.knownXs.detail', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -2262,16 +2353,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.SMALL.abstract', functionParameter: [ { - name: 'formula.functionList.SMALL.functionParameter.number1.name', - detail: 'formula.functionList.SMALL.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.SMALL.functionParameter.array.name', + detail: 'formula.functionList.SMALL.functionParameter.array.detail', + example: 'A2:B6', require: 1, repeat: 0, }, { - name: 'formula.functionList.SMALL.functionParameter.number2.name', - detail: 'formula.functionList.SMALL.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.SMALL.functionParameter.k.name', + detail: 'formula.functionList.SMALL.functionParameter.k.detail', + example: '3', require: 1, repeat: 0, }, @@ -2284,16 +2375,23 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.STANDARDIZE.abstract', functionParameter: [ { - name: 'formula.functionList.STANDARDIZE.functionParameter.number1.name', - detail: 'formula.functionList.STANDARDIZE.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.STANDARDIZE.functionParameter.x.name', + detail: 'formula.functionList.STANDARDIZE.functionParameter.x.detail', + example: '42', require: 1, repeat: 0, }, { - name: 'formula.functionList.STANDARDIZE.functionParameter.number2.name', - detail: 'formula.functionList.STANDARDIZE.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.STANDARDIZE.functionParameter.mean.name', + detail: 'formula.functionList.STANDARDIZE.functionParameter.mean.detail', + example: '40', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.STANDARDIZE.functionParameter.standardDev.name', + detail: 'formula.functionList.STANDARDIZE.functionParameter.standardDev.detail', + example: '1.5', require: 1, repeat: 0, }, @@ -2394,16 +2492,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.STEYX.abstract', functionParameter: [ { - name: 'formula.functionList.STEYX.functionParameter.number1.name', - detail: 'formula.functionList.STEYX.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.STEYX.functionParameter.knownYs.name', + detail: 'formula.functionList.STEYX.functionParameter.knownYs.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.STEYX.functionParameter.number2.name', - detail: 'formula.functionList.STEYX.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.STEYX.functionParameter.knownXs.name', + detail: 'formula.functionList.STEYX.functionParameter.knownXs.detail', + example: 'B1:B4', require: 1, repeat: 0, }, @@ -2416,16 +2514,23 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.T_DIST.abstract', functionParameter: [ { - name: 'formula.functionList.T_DIST.functionParameter.number1.name', - detail: 'formula.functionList.T_DIST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.T_DIST.functionParameter.x.name', + detail: 'formula.functionList.T_DIST.functionParameter.x.detail', + example: '8', require: 1, repeat: 0, }, { - name: 'formula.functionList.T_DIST.functionParameter.number2.name', - detail: 'formula.functionList.T_DIST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.T_DIST.functionParameter.degFreedom.name', + detail: 'formula.functionList.T_DIST.functionParameter.degFreedom.detail', + example: '3', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.T_DIST.functionParameter.cumulative.name', + detail: 'formula.functionList.T_DIST.functionParameter.cumulative.detail', + example: 'true', require: 1, repeat: 0, }, @@ -2438,16 +2543,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.T_DIST_2T.abstract', functionParameter: [ { - name: 'formula.functionList.T_DIST_2T.functionParameter.number1.name', - detail: 'formula.functionList.T_DIST_2T.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.T_DIST_2T.functionParameter.x.name', + detail: 'formula.functionList.T_DIST_2T.functionParameter.x.detail', + example: '8', require: 1, repeat: 0, }, { - name: 'formula.functionList.T_DIST_2T.functionParameter.number2.name', - detail: 'formula.functionList.T_DIST_2T.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.T_DIST_2T.functionParameter.degFreedom.name', + detail: 'formula.functionList.T_DIST_2T.functionParameter.degFreedom.detail', + example: '3', require: 1, repeat: 0, }, @@ -2460,16 +2565,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.T_DIST_RT.abstract', functionParameter: [ { - name: 'formula.functionList.T_DIST_RT.functionParameter.number1.name', - detail: 'formula.functionList.T_DIST_RT.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.T_DIST_RT.functionParameter.x.name', + detail: 'formula.functionList.T_DIST_RT.functionParameter.x.detail', + example: '8', require: 1, repeat: 0, }, { - name: 'formula.functionList.T_DIST_RT.functionParameter.number2.name', - detail: 'formula.functionList.T_DIST_RT.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.T_DIST_RT.functionParameter.degFreedom.name', + detail: 'formula.functionList.T_DIST_RT.functionParameter.degFreedom.detail', + example: '3', require: 1, repeat: 0, }, @@ -2482,16 +2587,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.T_INV.abstract', functionParameter: [ { - name: 'formula.functionList.T_INV.functionParameter.number1.name', - detail: 'formula.functionList.T_INV.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.T_INV.functionParameter.probability.name', + detail: 'formula.functionList.T_INV.functionParameter.probability.detail', + example: '0.75', require: 1, repeat: 0, }, { - name: 'formula.functionList.T_INV.functionParameter.number2.name', - detail: 'formula.functionList.T_INV.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.T_INV.functionParameter.degFreedom.name', + detail: 'formula.functionList.T_INV.functionParameter.degFreedom.detail', + example: '2', require: 1, repeat: 0, }, @@ -2504,16 +2609,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.T_INV_2T.abstract', functionParameter: [ { - name: 'formula.functionList.T_INV_2T.functionParameter.number1.name', - detail: 'formula.functionList.T_INV_2T.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.T_INV_2T.functionParameter.probability.name', + detail: 'formula.functionList.T_INV_2T.functionParameter.probability.detail', + example: '0.75', require: 1, repeat: 0, }, { - name: 'formula.functionList.T_INV_2T.functionParameter.number2.name', - detail: 'formula.functionList.T_INV_2T.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.T_INV_2T.functionParameter.degFreedom.name', + detail: 'formula.functionList.T_INV_2T.functionParameter.degFreedom.detail', + example: '2', require: 1, repeat: 0, }, @@ -2526,16 +2631,30 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.T_TEST.abstract', functionParameter: [ { - name: 'formula.functionList.T_TEST.functionParameter.number1.name', - detail: 'formula.functionList.T_TEST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.T_TEST.functionParameter.array1.name', + detail: 'formula.functionList.T_TEST.functionParameter.array1.detail', + example: 'A1:A4', require: 1, repeat: 0, }, { - name: 'formula.functionList.T_TEST.functionParameter.number2.name', - detail: 'formula.functionList.T_TEST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.T_TEST.functionParameter.array2.name', + detail: 'formula.functionList.T_TEST.functionParameter.array2.detail', + example: 'B1:B4', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.T_TEST.functionParameter.tails.name', + detail: 'formula.functionList.T_TEST.functionParameter.tails.detail', + example: '2', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.T_TEST.functionParameter.type.name', + detail: 'formula.functionList.T_TEST.functionParameter.type.detail', + example: '1', require: 1, repeat: 0, }, @@ -2570,16 +2689,16 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.TRIMMEAN.abstract', functionParameter: [ { - name: 'formula.functionList.TRIMMEAN.functionParameter.number1.name', - detail: 'formula.functionList.TRIMMEAN.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.TRIMMEAN.functionParameter.array.name', + detail: 'formula.functionList.TRIMMEAN.functionParameter.array.detail', + example: 'A2:A12', require: 1, repeat: 0, }, { - name: 'formula.functionList.TRIMMEAN.functionParameter.number2.name', - detail: 'formula.functionList.TRIMMEAN.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.TRIMMEAN.functionParameter.percent.name', + detail: 'formula.functionList.TRIMMEAN.functionParameter.percent.detail', + example: '0.2', require: 1, repeat: 0, }, @@ -2680,16 +2799,30 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.WEIBULL_DIST.abstract', functionParameter: [ { - name: 'formula.functionList.WEIBULL_DIST.functionParameter.number1.name', - detail: 'formula.functionList.WEIBULL_DIST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.WEIBULL_DIST.functionParameter.x.name', + detail: 'formula.functionList.WEIBULL_DIST.functionParameter.x.detail', + example: '105', require: 1, repeat: 0, }, { - name: 'formula.functionList.WEIBULL_DIST.functionParameter.number2.name', - detail: 'formula.functionList.WEIBULL_DIST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.WEIBULL_DIST.functionParameter.alpha.name', + detail: 'formula.functionList.WEIBULL_DIST.functionParameter.alpha.detail', + example: '20', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.WEIBULL_DIST.functionParameter.beta.name', + detail: 'formula.functionList.WEIBULL_DIST.functionParameter.beta.detail', + example: '100', + require: 1, + repeat: 0, + }, + { + name: 'formula.functionList.WEIBULL_DIST.functionParameter.cumulative.name', + detail: 'formula.functionList.WEIBULL_DIST.functionParameter.cumulative.detail', + example: 'true', require: 1, repeat: 0, }, @@ -2702,19 +2835,26 @@ export const FUNCTION_LIST_STATISTICAL: IFunctionInfo[] = [ abstract: 'formula.functionList.Z_TEST.abstract', functionParameter: [ { - name: 'formula.functionList.Z_TEST.functionParameter.number1.name', - detail: 'formula.functionList.Z_TEST.functionParameter.number1.detail', - example: 'A1:A20', + name: 'formula.functionList.Z_TEST.functionParameter.array.name', + detail: 'formula.functionList.Z_TEST.functionParameter.array.detail', + example: 'A2:A11', require: 1, repeat: 0, }, { - name: 'formula.functionList.Z_TEST.functionParameter.number2.name', - detail: 'formula.functionList.Z_TEST.functionParameter.number2.detail', - example: 'A1:A20', + name: 'formula.functionList.Z_TEST.functionParameter.x.name', + detail: 'formula.functionList.Z_TEST.functionParameter.x.detail', + example: '4', require: 1, repeat: 0, }, + { + name: 'formula.functionList.Z_TEST.functionParameter.sigma.name', + detail: 'formula.functionList.Z_TEST.functionParameter.sigma.detail', + example: '10', + require: 0, + repeat: 0, + }, ], }, ]; diff --git a/packages/sheets-formula/src/services/function-list/text.ts b/packages/sheets-formula/src/services/function-list/text.ts index 5d00bb92e92c..dafa408ce126 100644 --- a/packages/sheets-formula/src/services/function-list/text.ts +++ b/packages/sheets-formula/src/services/function-list/text.ts @@ -927,7 +927,7 @@ export const FUNCTION_LIST_TEXT: IFunctionInfo[] = [ { name: 'formula.functionList.TEXTSPLIT.functionParameter.text.name', detail: 'formula.functionList.TEXTSPLIT.functionParameter.text.detail', - example: '{1,2,3;4,5,6}', + example: 'A1:C2', require: 1, repeat: 0, },