Skip to content

Commit

Permalink
feat: matrixZPivotRescale and matrixZPivotRescale can use any NumberA…
Browse files Browse the repository at this point in the history
…rrayConstructors

feat: matrixZPivotRescale and matrixZPivotRescale can use any NumberArrayConstructors

* fix: DataXY<Float64Array> from xyIntegral

* fix: generalize matrixCreateEmpty

* fix: matrixZPivotRescale can use NumberArrayConstructors

* chore: sort xy index

* chore: use toStrictEqual
  • Loading branch information
jobo322 authored Mar 7, 2024
1 parent cfc5d86 commit 28ab4a4
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 31 deletions.
2 changes: 1 addition & 1 deletion src/__tests__/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ exports[`test existence of exported functions 1`] = `
"xyCheck",
"xyCovariance",
"xyCumulativeDistributionStatistics",
"xyEnsureFloat64",
"xyEnsureGrowingX",
"xyEquallySpaced",
"xyExtract",
Expand Down Expand Up @@ -108,7 +109,6 @@ exports[`test existence of exported functions 1`] = `
"xyToXYObject",
"xyUniqueX",
"xyWeightedMerge",
"xyEnsureFloat64",
"xy2ToXY",
"xreimSortX",
"xreimZeroFilling",
Expand Down
17 changes: 17 additions & 0 deletions src/matrix/__tests__/matrixCreateEmpty.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,20 @@ test('matrixCreateEmpty with Array constructor', () => {
[0, 0],
]);
});

test('matrixCreateEmpty with Int16Array constructor', () => {
const matrix = matrixCreateEmpty({
nbColumns: 2,
nbRows: 3,
ArrayConstructor: Int16Array,
});
expect(matrix).toHaveLength(3);
expect(matrix[0]).toHaveLength(2);
expect(matrix[0]).toBeInstanceOf(Int16Array);

expect(matrix).toStrictEqual([
Int16Array.from([0, 0]),
Int16Array.from([0, 0]),
Int16Array.from([0, 0]),
]);
});
18 changes: 18 additions & 0 deletions src/matrix/__tests__/matrixZPivotRescale.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,21 @@ test('with negative larger number', () => {
[-30, 10, -30, 10],
]);
});

test('only positive number in Int16 output', () => {
const data = [
[1, 3, 2, 2],
[2, 2, 1, 3],
[3, 1, 3, 1],
];
const result = matrixZPivotRescale(data, {
max: 30,
ArrayConstructor: Int16Array,
});

expect(result).toStrictEqual([
Int16Array.from([10, 30, 20, 20]),
Int16Array.from([20, 20, 10, 30]),
Int16Array.from([30, 10, 30, 10]),
]);
});
16 changes: 8 additions & 8 deletions src/matrix/matrixCreateEmpty.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { DoubleMatrix } from '../types';
import {
createDoubleArray,
DoubleArrayConstructor,
DoubleArrayType,
createNumberArray,
NumberArrayConstructor,
NumberArrayType,
} from '../utils';

export interface MatrixCreateEmptyOptions<
ArrayConstructorType extends DoubleArrayConstructor = Float64ArrayConstructor,
ArrayConstructorType extends NumberArrayConstructor = Float64ArrayConstructor,
> {
/**
* Matrix from which to extract nbRows and nbColumns
Expand All @@ -33,20 +33,20 @@ export interface MatrixCreateEmptyOptions<
* Create a new matrix based on the size of the current one or by using specific dimensions.
*/
export function matrixCreateEmpty<
ArrayConstructorType extends DoubleArrayConstructor = Float64ArrayConstructor,
ArrayConstructorType extends NumberArrayConstructor = Float64ArrayConstructor,
>(
options: MatrixCreateEmptyOptions<ArrayConstructorType>,
): Array<DoubleArrayType<ArrayConstructorType>> {
): Array<NumberArrayType<ArrayConstructorType>> {
const {
matrix,
nbRows = matrix?.length || 1,
nbColumns = matrix?.[0].length || 1,
ArrayConstructor = Float64Array as ArrayConstructorType,
} = options;

const newMatrix: Array<DoubleArrayType<ArrayConstructorType>> = [];
const newMatrix: Array<NumberArrayType<ArrayConstructorType>> = [];
for (let row = 0; row < nbRows; row++) {
newMatrix.push(createDoubleArray(ArrayConstructor, nbColumns));
newMatrix.push(createNumberArray(ArrayConstructor, nbColumns));
}
return newMatrix;
}
4 changes: 2 additions & 2 deletions src/matrix/matrixMaxAbsoluteZ.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { DoubleMatrix } from '../types';
import { NumberArray } from 'cheminfo-types';

/**
* Returns the max absolute values of Z.
*
* @param matrix - matrix [rows][cols].
*/
export function matrixMaxAbsoluteZ(matrix: DoubleMatrix): number {
export function matrixMaxAbsoluteZ(matrix: NumberArray[]): number {
if (matrix.length === 0 || matrix[0].length === 0) {
throw new Error('matrix must have at least 1 row and 1 column');
}
Expand Down
13 changes: 7 additions & 6 deletions src/matrix/matrixZPivotRescale.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { DoubleMatrix } from '../types';
import { DoubleArrayConstructor, DoubleArrayType } from '../utils';
import { NumberArray } from 'cheminfo-types';

import { NumberArrayConstructor, NumberArrayType } from '../utils';

import { matrixCreateEmpty } from './matrixCreateEmpty';
import { matrixMaxAbsoluteZ } from './matrixMaxAbsoluteZ';

export interface MatrixZPivotRescaleOptions<
ArrayConstructorType extends DoubleArrayConstructor = Float64ArrayConstructor,
ArrayConstructorType extends NumberArrayConstructor = Float64ArrayConstructor,
> {
/**
* max
Expand All @@ -26,11 +27,11 @@ export interface MatrixZPivotRescaleOptions<
* @param options - Options.
*/
export function matrixZPivotRescale<
ArrayConstructorType extends DoubleArrayConstructor = Float64ArrayConstructor,
ArrayConstructorType extends NumberArrayConstructor = Float64ArrayConstructor,
>(
matrix: DoubleMatrix,
matrix: NumberArray[],
options: MatrixZPivotRescaleOptions<ArrayConstructorType> = {},
): Array<DoubleArrayType<DoubleArrayConstructor>> {
): Array<NumberArrayType<NumberArrayConstructor>> {
const { max = 1, ArrayConstructor } = options;
const nbColumns = matrix[0].length;
const nbRows = matrix.length;
Expand Down
17 changes: 12 additions & 5 deletions src/xy/__tests__/xyIntegral.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { xyEnsureFloat64 } from '../xyEnsureFloat64';
import { xyIntegral } from '../xyIntegral';

test('zero element', () => {
Expand All @@ -12,33 +13,39 @@ test('one element', () => {
const x = [1];
const y = [2];
const result = xyIntegral({ x, y });
expect(result).toStrictEqual({ x: [1], y: [0] });
expect(result).toStrictEqual(xyEnsureFloat64({ x: [1], y: [0] }));
});

test('no from to', () => {
const x = [0, 1, 2, 3];
const y = [1, 1, 1, 1];
const result = xyIntegral({ x, y });
expect(result).toStrictEqual({ x: [0, 1, 2, 3], y: [0, 1, 2, 3] });
expect(result).toStrictEqual(
xyEnsureFloat64({ x: [0, 1, 2, 3], y: [0, 1, 2, 3] }),
);
});

test('no from to with xyIntegral', () => {
const x = [0, 1, 2, 3];
const y = [1, 1, 1, 1];
const result = xyIntegral({ x, y }, { from: 1, to: 2 });
expect(result).toStrictEqual({ x: [1, 2], y: [0, 1] });
expect(result).toStrictEqual(xyEnsureFloat64({ x: [1, 2], y: [0, 1] }));
});

test('xyIntegral too large', () => {
const x = [1, 2, 3, 4];
const y = [10, 20, 30, 40];
const result = xyIntegral({ x, y }, { from: 2, to: 6 });
expect(result).toStrictEqual({ x: [2, 3, 4], y: [0, 25, 60] });
expect(result).toStrictEqual(
xyEnsureFloat64({ x: [2, 3, 4], y: [0, 25, 60] }),
);
});

test('no from to and inverse', () => {
const x = [1, 2, 3, 4];
const y = [10, 20, 30, 40];
const result = xyIntegral({ x, y }, { reverse: true });
expect(result).toStrictEqual({ x: [1, 2, 3, 4], y: [75, 60, 35, 0] });
expect(result).toStrictEqual(
xyEnsureFloat64({ x: [1, 2, 3, 4], y: [75, 60, 35, 0] }),
);
});
2 changes: 1 addition & 1 deletion src/xy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export * from './xyAlign';
export * from './xyCheck';
export * from './xyCovariance';
export * from './xyCumulativeDistributionStatistics';
export * from './xyEnsureFloat64';
export * from './xyEnsureGrowingX';
export * from './xyEquallySpaced';
export * from './xyExtract';
Expand Down Expand Up @@ -38,4 +39,3 @@ export * from './xyToXYArray';
export * from './xyToXYObject';
export * from './xyUniqueX';
export * from './xyWeightedMerge';
export * from './xyEnsureFloat64';
22 changes: 14 additions & 8 deletions src/xy/xyIntegral.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,30 +40,36 @@ export interface XYIntegralOptions {
export function xyIntegral(
data: DataXY,
options: XYIntegralOptions = {},
): DataXY<number[]> {
): DataXY<Float64Array> {
const { reverse = false } = options;
xyCheck(data, { minLength: 1 });
const { x, y } = data;

const { fromIndex, toIndex } = xGetFromToIndex(x, options);

let xyIntegration = 0;
let currentxyIntegral;
const currentxyIntegral = {
x: new Float64Array(toIndex - fromIndex + 1),
y: new Float64Array(toIndex - fromIndex + 1),
};
let index = 0;
if (reverse) {
currentxyIntegral = { x: [x[toIndex]], y: [0] };
currentxyIntegral.y[index] = 0;
currentxyIntegral.x[index++] = x[toIndex];
for (let i = toIndex; i > fromIndex; i--) {
xyIntegration += ((x[i] - x[i - 1]) * (y[i - 1] + y[i])) / 2;
currentxyIntegral.x.push(x[i - 1]);
currentxyIntegral.y.push(xyIntegration);
currentxyIntegral.x[index] = x[i - 1];
currentxyIntegral.y[index++] = xyIntegration;
}
currentxyIntegral.x.reverse();
currentxyIntegral.y.reverse();
} else {
currentxyIntegral = { x: [x[fromIndex]], y: [0] };
currentxyIntegral.y[index] = 0;
currentxyIntegral.x[index++] = x[fromIndex];
for (let i = fromIndex; i < toIndex; i++) {
xyIntegration += ((x[i + 1] - x[i]) * (y[i + 1] + y[i])) / 2;
currentxyIntegral.x.push(x[i + 1]);
currentxyIntegral.y.push(xyIntegration);
currentxyIntegral.x[index] = x[i + 1];
currentxyIntegral.y[index++] = xyIntegration;
}
}

Expand Down

0 comments on commit 28ab4a4

Please sign in to comment.