Skip to content

Commit

Permalink
feat(formula): add some engineering function (#2893)
Browse files Browse the repository at this point in the history
Co-authored-by: wpxp123456 <Wpxp1223456>
  • Loading branch information
wpxp123456 authored Aug 13, 2024
1 parent e07e0c8 commit 9386c6b
Show file tree
Hide file tree
Showing 76 changed files with 6,359 additions and 650 deletions.
470 changes: 470 additions & 0 deletions packages/engine-formula/src/basics/engineering.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -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 { describe, expect, it } from 'vitest';

import { FUNCTION_NAMES_ENGINEERING } from '../../function-names';
import { Besseli } from '../index';
import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object';
import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object';
import { ErrorType } from '../../../../basics/error-type';
import { ErrorValueObject } from '../../../../engine/value-object/base-value-object';

describe('Test besseli function', () => {
const testFunction = new Besseli(FUNCTION_NAMES_ENGINEERING.BESSELI);

describe('Besseli', () => {
it('Value is normal number', () => {
const x = NumberValueObject.create(1.5);
const n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).toBe(0.981666428475166);
});

it('Value is number string', () => {
const x = StringValueObject.create('-0.5');
const n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).toBe(-0.25789430328903556);
});

it('Value is normal string', () => {
const x = StringValueObject.create('test');
const n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).toBe(ErrorType.VALUE);
});

it('Value is boolean', () => {
const x = BooleanValueObject.create(true);
const n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).toBe(ErrorType.VALUE);
});

it('Value is null', () => {
const x = NullValueObject.create();
const n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).toBe(ErrorType.NA);
});

it('Value is blank cell', () => {
const x = ArrayValueObject.create({
calculateValueList: transformToValueObject([
[null],
]),
rowCount: 1,
columnCount: 1,
unitId: '',
sheetId: '',
row: 0,
column: 0,
});
const n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).toBe(0);
});

it('Value is error', () => {
const x = ErrorValueObject.create(ErrorType.NAME);
const n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).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 n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).toStrictEqual(ErrorType.VALUE);
});
});
});
60 changes: 60 additions & 0 deletions packages/engine-formula/src/functions/engineering/besseli/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* 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 { BESSEL, checkVariantsErrorIsArrayOrBoolean } from '../../../basics/engineering';
import { ErrorType } from '../../../basics/error-type';
import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object';
import { BaseFunction } from '../../base-function';
import { NumberValueObject } from '../../../engine/value-object/primitive-object';

export class Besseli extends BaseFunction {
override minParams = 2;

override maxParams = 2;

override calculate(x: BaseValueObject, n: BaseValueObject) {
if (x.isNull() || n.isNull()) {
return ErrorValueObject.create(ErrorType.NA);
}

const { isError, errorObject, variants } = checkVariantsErrorIsArrayOrBoolean(x, n);

if (isError) {
return errorObject as ErrorValueObject;
}

const [xObject, nObject] = variants as BaseValueObject[];

const xValue = +xObject.getValue();
const nValue = Math.floor(+nObject.getValue());

if (Number.isNaN(xValue) || Number.isNaN(nValue)) {
return ErrorValueObject.create(ErrorType.VALUE);
}

if (nValue < 0) {
return ErrorValueObject.create(ErrorType.NUM);
}

const result = BESSEL.besseli(xValue, nValue);

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
@@ -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 { describe, expect, it } from 'vitest';

import { FUNCTION_NAMES_ENGINEERING } from '../../function-names';
import { Besselj } from '../index';
import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object';
import { ArrayValueObject, transformToValueObject } from '../../../../engine/value-object/array-value-object';
import { ErrorType } from '../../../../basics/error-type';
import { ErrorValueObject } from '../../../../engine/value-object/base-value-object';

describe('Test besselj function', () => {
const testFunction = new Besselj(FUNCTION_NAMES_ENGINEERING.BESSELJ);

describe('Besselj', () => {
it('Value is normal number', () => {
const x = NumberValueObject.create(1.5);
const n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).toBe(0.5579365078908043);
});

it('Value is number string', () => {
const x = StringValueObject.create('-0.5');
const n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).toBe(-0.24226845767957006);
});

it('Value is normal string', () => {
const x = StringValueObject.create('test');
const n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).toBe(ErrorType.VALUE);
});

it('Value is boolean', () => {
const x = BooleanValueObject.create(true);
const n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).toBe(ErrorType.VALUE);
});

it('Value is null', () => {
const x = NullValueObject.create();
const n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).toBe(ErrorType.NA);
});

it('Value is blank cell', () => {
const x = ArrayValueObject.create({
calculateValueList: transformToValueObject([
[null],
]),
rowCount: 1,
columnCount: 1,
unitId: '',
sheetId: '',
row: 0,
column: 0,
});
const n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).toBe(0);
});

it('Value is error', () => {
const x = ErrorValueObject.create(ErrorType.NAME);
const n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).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 n = NumberValueObject.create(1);
const result = testFunction.calculate(x, n);
expect(result.getValue()).toStrictEqual(ErrorType.VALUE);
});
});
});
60 changes: 60 additions & 0 deletions packages/engine-formula/src/functions/engineering/besselj/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* 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 { BESSEL, checkVariantsErrorIsArrayOrBoolean } from '../../../basics/engineering';
import { ErrorType } from '../../../basics/error-type';
import { type BaseValueObject, ErrorValueObject } from '../../../engine/value-object/base-value-object';
import { BaseFunction } from '../../base-function';
import { NumberValueObject } from '../../../engine/value-object/primitive-object';

export class Besselj extends BaseFunction {
override minParams = 2;

override maxParams = 2;

override calculate(x: BaseValueObject, n: BaseValueObject) {
if (x.isNull() || n.isNull()) {
return ErrorValueObject.create(ErrorType.NA);
}

const { isError, errorObject, variants } = checkVariantsErrorIsArrayOrBoolean(x, n);

if (isError) {
return errorObject as ErrorValueObject;
}

const [xObject, nObject] = variants as BaseValueObject[];

const xValue = +xObject.getValue();
const nValue = Math.floor(+nObject.getValue());

if (Number.isNaN(xValue) || Number.isNaN(nValue)) {
return ErrorValueObject.create(ErrorType.VALUE);
}

if (nValue < 0) {
return ErrorValueObject.create(ErrorType.NUM);
}

const result = BESSEL.besselj(xValue, nValue);

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

return NumberValueObject.create(result);
}
}
Loading

0 comments on commit 9386c6b

Please sign in to comment.