Skip to content

Commit

Permalink
fix(formula): fix bug
Browse files Browse the repository at this point in the history
  • Loading branch information
wpxp123456 authored and wpxp123456 committed Oct 29, 2024
1 parent d157071 commit cdcfad8
Show file tree
Hide file tree
Showing 34 changed files with 348 additions and 56 deletions.
4 changes: 4 additions & 0 deletions packages/engine-formula/src/basics/statistical.ts
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,10 @@ export function hypergeometricCDF(x: number, n: number, M: number, N: number): n
}

export function hypergeometricPDF(x: number, n: number, M: number, N: number): number {
if (n - x > N - M) {
return 0;
}

return calculateCombin(M, x) * calculateCombin(N - M, n - x) / calculateCombin(N, n);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,50 @@ describe('Test hypgeomdist function', () => {
[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);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
* 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';
import type { ArrayValueObject } from '../../../engine/value-object/array-value-object';

export class Negbinomdist extends BaseFunction {
override minParams = 3;
Expand Down Expand Up @@ -92,7 +92,7 @@ export class Negbinomdist extends BaseFunction {
const numberSValue = Math.floor(+_numberSObject.getValue());
const probabilitySValue = +_probabilitySObject.getValue();

if (numberFValue < 0 || numberSValue < 1 || probabilitySValue < 0 || probabilitySValue > 1) {
if (numberFValue < 0 || numberSValue < 1 || probabilitySValue <= 0 || probabilitySValue >= 1) {
return ErrorValueObject.create(ErrorType.NUM);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ describe('Test geomean function', () => {
const number5 = ErrorValueObject.create(ErrorType.NAME);
const number6 = NumberValueObject.create(-3);
const result = testFunction.calculate(number, number2, number3, number4);
expect(getObjectValue(result)).toStrictEqual(3);
expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE);

const result2 = testFunction.calculate(number, number2, number3, number4, number5);
const result2 = testFunction.calculate(number, number2, number3, number5);
expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME);

const result3 = testFunction.calculate(number, number2, number3, number4, number6);
const result3 = testFunction.calculate(number, number2, number3, number6);
expect(getObjectValue(result3)).toStrictEqual(ErrorType.NUM);
});

Expand Down
12 changes: 10 additions & 2 deletions packages/engine-formula/src/functions/statistical/geomean/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
* 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';
import type { ArrayValueObject } from '../../../engine/value-object/array-value-object';
import type { BaseValueObject } from '../../../engine/value-object/base-value-object';

export class Geomean extends BaseFunction {
override minParams = 1;
Expand Down Expand Up @@ -72,6 +72,14 @@ export class Geomean extends BaseFunction {
return variant;
}

if (variant.isString()) {
const _variant = variant.convertToNumberObjectValue();

if (_variant.isError()) {
return _variant;
}
}

if (variant.isNull() || variant.isBoolean()) {
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ describe('Test harmean function', () => {
const number5 = ErrorValueObject.create(ErrorType.NAME);
const number6 = NumberValueObject.create(-3);
const result = testFunction.calculate(number, number2, number3, number4);
expect(getObjectValue(result)).toStrictEqual(3);
expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE);

const result2 = testFunction.calculate(number, number2, number3, number4, number5);
const result2 = testFunction.calculate(number, number2, number3, number5);
expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME);

const result3 = testFunction.calculate(number, number2, number3, number4, number6);
const result3 = testFunction.calculate(number, number2, number3, number6);
expect(getObjectValue(result3)).toStrictEqual(ErrorType.NUM);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ export class Harmean extends BaseFunction {
return variant;
}

if (variant.isString()) {
const _variant = variant.convertToNumberObjectValue();

if (_variant.isError()) {
return _variant;
}
}

if (variant.isNull() || variant.isBoolean()) {
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,51 @@ describe('Test hypgeomDist function', () => {
[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);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ describe('Test kurt function', () => {
const number5 = ErrorValueObject.create(ErrorType.NAME);
const number6 = NumberValueObject.create(-3);
const result = testFunction.calculate(number, number2, number3, number4);
expect(getObjectValue(result)).toStrictEqual(ErrorType.DIV_BY_ZERO);
expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE);

const result2 = testFunction.calculate(number, number2, number3, number4, number5);
const result2 = testFunction.calculate(number, number2, number3, number5);
expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME);

const result3 = testFunction.calculate(number, number2, number3, number4, number6);
const result3 = testFunction.calculate(number, number2, number3, number6);
expect(getObjectValue(result3)).toStrictEqual(ErrorType.DIV_BY_ZERO);
});

Expand Down
16 changes: 14 additions & 2 deletions packages/engine-formula/src/functions/statistical/kurt/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
* 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';
import type { ArrayValueObject } from '../../../engine/value-object/array-value-object';
import type { BaseValueObject } from '../../../engine/value-object/base-value-object';

export class Kurt extends BaseFunction {
override minParams = 1;
Expand All @@ -35,6 +35,18 @@ export class Kurt extends BaseFunction {
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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,23 @@ describe('Test large function', () => {
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([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
* 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';
import type { ArrayValueObject } from '../../../engine/value-object/array-value-object';
import type { BaseValueObject } from '../../../engine/value-object/base-value-object';

export class Large extends BaseFunction {
override minParams = 2;
Expand Down Expand Up @@ -82,7 +82,7 @@ export class Large extends BaseFunction {
return valueObject as ErrorValueObject;
}

if (valueObject.isNull() || valueObject.isBoolean()) {
if (valueObject.isNull() || valueObject.isBoolean() || valueObject.isString()) {
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,13 @@ describe('Test lognormInv function', () => {
[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);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
* 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';
import type { ArrayValueObject } from '../../../engine/value-object/array-value-object';

export class LognormInv extends BaseFunction {
override minParams = 3;
Expand Down Expand Up @@ -98,6 +98,10 @@ export class LognormInv extends BaseFunction {

const result = lognormalINV(probabilityValue, meanValue, standardDevValue);

if (Number.isNaN(result) || !Number.isFinite(result)) {
return ErrorValueObject.create(ErrorType.NUM);
}

return NumberValueObject.create(result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ describe('Test median function', () => {
const number5 = ErrorValueObject.create(ErrorType.NAME);
const number6 = NumberValueObject.create(-3);
const result = testFunction.calculate(number, number2, number3, number4);
expect(getObjectValue(result)).toStrictEqual(3);
expect(getObjectValue(result)).toStrictEqual(ErrorType.VALUE);

const result2 = testFunction.calculate(number, number2, number3, number4, number5);
const result2 = testFunction.calculate(number, number2, number3, number5);
expect(getObjectValue(result2)).toStrictEqual(ErrorType.NAME);

const result3 = testFunction.calculate(number, number2, number3, number4, number6);
const result3 = testFunction.calculate(number, number2, number3, number6);
expect(getObjectValue(result3)).toStrictEqual(0);
});

Expand Down Expand Up @@ -94,6 +94,16 @@ describe('Test median function', () => {
});
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);
});
});
});
Loading

0 comments on commit cdcfad8

Please sign in to comment.