diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index bc57d11..0000000 --- a/.eslintrc.yml +++ /dev/null @@ -1 +0,0 @@ -extends: cheminfo-typescript diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..b905e35 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,14 @@ +import cheminfo from 'eslint-config-cheminfo-typescript'; +import globals from 'globals'; + +export default [ + ...cheminfo, + { + languageOptions: { + globals: { + ...globals.node, + }, + }, + rules: {} + } +] \ No newline at end of file diff --git a/package.json b/package.json index dc2ee84..5eedb14 100644 --- a/package.json +++ b/package.json @@ -42,15 +42,15 @@ }, "homepage": "https://github.com/mljs/fcnnls#readme", "devDependencies": { - "@vitest/coverage-v8": "^0.34.5", - "eslint": "^8.50.0", - "eslint-config-cheminfo-typescript": "^12.0.4", - "prettier": "^3.0.3", - "rimraf": "^5.0.5", - "typescript": "^5.2.2", - "vitest": "^0.34.5" + "@vitest/coverage-v8": "^2.1.3", + "eslint": "^9.12.0", + "eslint-config-cheminfo-typescript": "^16.0.0", + "prettier": "^3.3.3", + "rimraf": "^6.0.1", + "typescript": "^5.6.3", + "vitest": "^2.1.3" }, "dependencies": { - "ml-matrix": "^6.10.5" + "ml-matrix": "^6.11.1" } } diff --git a/src/__tests__/fcnnls.test.ts b/src/__tests__/fcnnls.test.ts index 5072997..5d52a56 100644 --- a/src/__tests__/fcnnls.test.ts +++ b/src/__tests__/fcnnls.test.ts @@ -1,5 +1,5 @@ -import { readFileSync } from 'fs'; -import { join } from 'path'; +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; import { Matrix } from 'ml-matrix'; import { it, describe, expect } from 'vitest'; @@ -8,31 +8,31 @@ import { fcnnls } from '../fcnnls'; import { assertResult } from './assertResult'; -const concentration = readFileSync(join(__dirname, 'data/matrix.txt'), 'utf-8'); +const concentration = readFileSync(join(__dirname, 'data/matrix.txt'), 'utf8'); const linesA = concentration.split(/[\r\n]+/); const A: number[][] = []; for (const line of linesA) { - A.push(line.split(',').map((value) => Number(value))); + A.push(line.split(',').map(Number)); } let matrix = new Matrix(A); matrix = matrix.transpose(); -const proportion = readFileSync(join(__dirname, 'data/x_fcnnls.txt'), 'utf-8'); +const proportion = readFileSync(join(__dirname, 'data/x_fcnnls.txt'), 'utf8'); const linesk = proportion.split(/[\r\n]+/); const k: number[][] = []; for (const line of linesk) { - k.push(line.split(',').map((value) => Number(value))); + k.push(line.split(',').map(Number)); } k.splice(133, 1); const answer = new Matrix(k); -const observation = readFileSync(join(__dirname, 'data/target.txt'), 'utf-8'); +const observation = readFileSync(join(__dirname, 'data/target.txt'), 'utf8'); const lines = observation.split(/[\r\n]+/); const b: number[][] = []; for (const line of lines) { - b.push(line.split(',').map((value) => Number(value))); + b.push(line.split(',').map(Number)); } let target = new Matrix(b); diff --git a/src/cssls.ts b/src/cssls.ts index f77c6a9..d588547 100644 --- a/src/cssls.ts +++ b/src/cssls.ts @@ -12,7 +12,12 @@ import { sortCollectionSet } from './util/sortCollectionSet'; * Solves XtX*K = XtY for the variables in Pset * if XtX (or XtX(vars,vars)) is singular, performs the svd and find pseudo-inverse, otherwise (even if ill-conditioned) finds inverse with LU decomposition and solves the set of equations * it is consistent with matlab results for ill-conditioned matrices (at least consistent with test 'ill-conditioned square X rank 2, Y 3x1' in cssls.test) - * @param Cssls object, @see {@link Cssls} + * @param options - @see {@link Cssls} + * @param options.XtX + * @param options.XtY + * @param options.Pset + * @param options.nColsX + * @param options.nColsY */ export function cssls({ XtX, XtY, Pset, nColsX, nColsY }: Cssls): Matrix { let K = Matrix.zeros(nColsX, nColsY); diff --git a/src/fcnnls.ts b/src/fcnnls.ts index 03e0797..8a65edf 100644 --- a/src/fcnnls.ts +++ b/src/fcnnls.ts @@ -31,7 +31,7 @@ export interface FcnnlsOptions { * Fast Combinatorial Non-negative Least Squares with multiple Right Hand Side * @param X - The data/input/predictors matrix * @param Y - The response matrix - * @param options {@link FcnnlsOptions} + * @param options - {@link FcnnlsOptions} * @returns By default, the object with the matrix of coefficients K. Please see {@link FcnnlsOutput} for more information. */ export function fcnnls( @@ -175,10 +175,7 @@ export function fcnnls( } for (let j = 0; j < m; j++) { - Pset[Hset[j]].splice( - Pset[Hset[j]].findIndex((item) => item === minIdx[j]), - 1, - ); + Pset[Hset[j]].splice(Pset[Hset[j]].indexOf(minIdx[j]), 1); } L = cssls({ diff --git a/src/initialisation.ts b/src/initialisation.ts index 16cf118..f924b19 100644 --- a/src/initialisation.ts +++ b/src/initialisation.ts @@ -13,8 +13,13 @@ interface Initialisation { /** * Solves OLS problem, overwriting the negative values of K with 0. * It also pre-computes part of the pseudo-inverse used to solve Least Squares. - * @param XtX - input data matrix - * @param XtY - output data matrix + * @param options + * @param options.XtX - input data matrix + * @param options.XtY - output data matrix + * @param options.nRowsX + * @param options.nColsX + * @param options.nRowsY + * @param options.nColsY * @returns initial values for the algorithm (including the solution K to least squares, overwriting of negative values with 0) */ export function initialisation({ diff --git a/src/optimality.ts b/src/optimality.ts index 67d0fa0..19247bb 100644 --- a/src/optimality.ts +++ b/src/optimality.ts @@ -4,7 +4,20 @@ import { setDifference } from './util/setDifference'; /** * Checks whether the solution has converged - * @param see {@link OptimalityParams} for a description. + * {@link OptimalityParams} for a description. + * @param options + * @param options.iter + * @param options.maxIter + * @param options.XtX + * @param options.XtY + * @param options.Fset + * @param options.Pset + * @param options.W + * @param options.K + * @param options.l + * @param options.p + * @param options.D + * @param options.gradientTolerance * @returns Pset, Fset, W */ export function optimality({ @@ -51,7 +64,7 @@ export function optimality({ Fset = setDifference(Fset, Jset); // For non-optimal solutions, add the appropriate variables to Pset - if (Fset.length !== 0) { + if (Fset.length > 0) { for (let j = 0; j < Fset.length; j++) { for (let i = 0; i < l; i++) { if (Pset[Fset[j]].includes(i)) W.set(i, Fset[j], -Infinity); diff --git a/src/util/diff.ts b/src/util/diff.ts index 3f7d385..02d7385 100644 --- a/src/util/diff.ts +++ b/src/util/diff.ts @@ -1,6 +1,6 @@ /** * Computes an array containing the difference of consecutive numbers - * @param Array v from which it computes the difference + * @param v - v from which it computes the difference * @returns - Array of consecutive differences */ export function diff(v: number[]) { diff --git a/src/util/getRSE.ts b/src/util/getRSE.ts index a988062..7672678 100644 --- a/src/util/getRSE.ts +++ b/src/util/getRSE.ts @@ -2,7 +2,11 @@ import { Matrix } from 'ml-matrix'; /** * Return the root square error of the solution. - * @param object with X, K, Y, and error @see {@link GetRSEInput} + * @param object - with X, K, Y, and error @see {@link GetRSEInput} + * @param object.X + * @param object.K + * @param object.Y + * @param object.error * @returns the root squared error array. */ export function getRSE({ X, K, Y, error }: GetRSEInput) { diff --git a/src/util/selection.ts b/src/util/selection.ts index 98f2647..a032d28 100644 --- a/src/util/selection.ts +++ b/src/util/selection.ts @@ -1,6 +1,7 @@ /** * Returns a new array based on extraction of specific indices of an array - * @param collection or array + * @param collection - or array + * @param vector * @param indices */ export function selection( diff --git a/src/util/setDifference.ts b/src/util/setDifference.ts index 5ea4a27..2befc07 100644 --- a/src/util/setDifference.ts +++ b/src/util/setDifference.ts @@ -1,7 +1,7 @@ /** * Computes the set difference A\B - * @param set A as an array - * @param set B as an array + * @param A - First array of numbers + * @param B - Second array of numbers * @returns Elements of A that are not in B */ export function setDifference(A: number[], B: number[]) { diff --git a/src/util/sortArray.ts b/src/util/sortArray.ts index dc69a88..8d3c497 100644 --- a/src/util/sortArray.ts +++ b/src/util/sortArray.ts @@ -1,7 +1,7 @@ /** * Sorts an array and returns an object with the sorted array and the corresponding indices. * @param array - * @returns {values, indices} + * @returns */ export function sortArray(array: number[]) { const v = array.map((value, index) => { diff --git a/src/util/sortCollectionSet.ts b/src/util/sortCollectionSet.ts index af8062a..d285f62 100644 --- a/src/util/sortCollectionSet.ts +++ b/src/util/sortCollectionSet.ts @@ -1,7 +1,6 @@ /** * From an array of arrays it constructs a unique key for each array, * given by its values, such that same arrays have same keys. - * * @param collection - Array of arrays * @returns - Array of objects with the original array, its index and its key */ @@ -10,7 +9,9 @@ function addUniqueKeyToColumns(collection: number[][]) { //indices of positive values within the column. (Pset) let key = BigInt(0); // items will be the indexes of Pset, so it's always an integer. - positiveRows.forEach((item) => (key |= BigInt(1) << BigInt(item))); + for (const item of positiveRows) { + key |= BigInt(1) << BigInt(item); + } return { positiveRows, columnIndexInK, key }; }); } @@ -38,7 +39,7 @@ export function sortCollectionSet(collection: number[][]) { indices.push([]); sorted.push(set.positiveRows); } - indices[indices.length - 1].push(set.columnIndexInK); + indices.at(-1).push(set.columnIndexInK); } const result = {