diff --git a/src/index.ts b/src/index.ts index fd75d1cf..7ad396b0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -59,7 +59,7 @@ export * from './x/utils/getOutputArray'; export * from './xy/xyAlign'; export * from './xy/xyCheck'; -export * from './xy/xyClosestX'; +export * from './xy/xyFindClosestPoint'; export * from './xy/xyCovariance'; export * from './xy/xyCumulativeDistributionStatistics'; export * from './xy/xyEnsureGrowingX'; diff --git a/src/xy/__tests__/xyClosestX.test.ts b/src/xy/__tests__/xyClosestX.test.ts deleted file mode 100644 index 131a7ac8..00000000 --- a/src/xy/__tests__/xyClosestX.test.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { xyClosestX } from '../xyClosestX'; - -describe('closestX', () => { - it('should yield the correct result with even element array', () => { - const x = [-1, 0, 1, 2, 3, 4, 5, 6]; - const y = [10, 11, 12, 13, 14, 15, 16, 17]; - expect(xyClosestX({ x, y }, { target: -2 })).toStrictEqual({ - x: -1, - y: 10, - }); - expect(xyClosestX({ x, y }, { target: 0.6 })).toStrictEqual({ - x: 1, - y: 12, - }); - expect(xyClosestX({ x, y }, { target: 4.3 })).toStrictEqual({ - x: 4, - y: 15, - }); - expect(xyClosestX({ x, y }, { target: 6 })).toStrictEqual({ x: 6, y: 17 }); - expect(xyClosestX({ x, y }, { target: 7 })).toStrictEqual({ x: 6, y: 17 }); - }); - - it('should yield the correct result with odd element array', () => { - const x = [-1, 0, 1, 2, 3, 4, 5, 6, 7]; - const y = [10, 11, 12, 13, 14, 15, 16, 17, 18]; - expect(xyClosestX({ x, y }, { target: -2 })).toStrictEqual({ - x: -1, - y: 10, - }); - expect(xyClosestX({ x, y }, { target: 0.6 })).toStrictEqual({ - x: 1, - y: 12, - }); - expect(xyClosestX({ x, y }, { target: 4.3 })).toStrictEqual({ - x: 4, - y: 15, - }); - expect(xyClosestX({ x, y }, { target: 6 })).toStrictEqual({ x: 6, y: 17 }); - expect(xyClosestX({ x, y }, { target: 7 })).toStrictEqual({ x: 7, y: 18 }); - expect(xyClosestX({ x, y }, { target: 8 })).toStrictEqual({ x: 7, y: 18 }); - }); - - it('should yield the correct result with odd element array and descending order', () => { - let x = [7, 6, 5, 4, 3, 2, 1, 0, -1]; - let y = [18, 17, 16, 15, 14, 13, 12, 11, 10]; - expect(xyClosestX({ x, y }, { target: -2, reverse: true })).toStrictEqual({ - x: -1, - y: 10, - }); - expect(xyClosestX({ x, y }, { target: 0.6, reverse: true })).toStrictEqual({ - x: 1, - y: 12, - }); - expect(xyClosestX({ x, y }, { target: 4.3, reverse: true })).toStrictEqual({ - x: 4, - y: 15, - }); - expect(xyClosestX({ x, y }, { target: 6, reverse: true })).toStrictEqual({ - x: 6, - y: 17, - }); - expect(xyClosestX({ x, y }, { target: 7, reverse: true })).toStrictEqual({ - x: 7, - y: 18, - }); - expect(xyClosestX({ x, y }, { target: 8, reverse: true })).toStrictEqual({ - x: 7, - y: 18, - }); - }); -}); diff --git a/src/xy/__tests__/xyFindClosestPoint.test.ts b/src/xy/__tests__/xyFindClosestPoint.test.ts new file mode 100644 index 00000000..6544f63b --- /dev/null +++ b/src/xy/__tests__/xyFindClosestPoint.test.ts @@ -0,0 +1,57 @@ +import { xyFindClosestPoint } from '../xyFindClosestPoint'; + +describe('closestX', () => { + it('should yield the correct result with even element array', () => { + const x = [-1, 0, 1, 2, 3, 4, 5, 6]; + const y = [10, 11, 12, 13, 14, 15, 16, 17]; + expect(xyFindClosestPoint({ x, y }, -2)).toStrictEqual({ + x: -1, + y: 10, + }); + expect(xyFindClosestPoint({ x, y }, 0.6)).toStrictEqual({ + x: 1, + y: 12, + }); + expect(xyFindClosestPoint({ x, y }, 4.3)).toStrictEqual({ + x: 4, + y: 15, + }); + expect(xyFindClosestPoint({ x, y }, 6)).toStrictEqual({ + x: 6, + y: 17, + }); + expect(xyFindClosestPoint({ x, y }, 7)).toStrictEqual({ + x: 6, + y: 17, + }); + }); + + it('should yield the correct result with odd element array', () => { + const x = [-1, 0, 1, 2, 3, 4, 5, 6, 7]; + const y = [10, 11, 12, 13, 14, 15, 16, 17, 18]; + expect(xyFindClosestPoint({ x, y }, -2)).toStrictEqual({ + x: -1, + y: 10, + }); + expect(xyFindClosestPoint({ x, y }, 0.6)).toStrictEqual({ + x: 1, + y: 12, + }); + expect(xyFindClosestPoint({ x, y }, 4.3)).toStrictEqual({ + x: 4, + y: 15, + }); + expect(xyFindClosestPoint({ x, y }, 6)).toStrictEqual({ + x: 6, + y: 17, + }); + expect(xyFindClosestPoint({ x, y }, 7)).toStrictEqual({ + x: 7, + y: 18, + }); + expect(xyFindClosestPoint({ x, y }, 8)).toStrictEqual({ + x: 7, + y: 18, + }); + }); +}); diff --git a/src/xy/xyClosestX.ts b/src/xy/xyClosestX.ts deleted file mode 100644 index 78e606f9..00000000 --- a/src/xy/xyClosestX.ts +++ /dev/null @@ -1,61 +0,0 @@ -import binarySearch from 'binary-search'; -import { DataXY } from 'cheminfo-types'; - -import { numberSortAscending, numberSortDescending } from '../utils/numberSort'; - -/**Findding the closest points - * - * @param data - points in cartesian space - * @param options - options - * @returns - closest point - */ -export function xyClosestX( - /** points */ - data: DataXY, - options: { - /** The target to which the x-coordinates should be close to - * @default x[0] - */ - target: number; - /** The reverse option - * @default false - */ - reverse?: boolean; - }, -): { - x: number; - y: number; -} { - const { x, y } = data; - const { target = x[0], reverse = false } = options; - - let index; - if (reverse) { - index = binarySearch(x, target, numberSortDescending); - } else { - index = binarySearch(x, target, numberSortAscending); - } - - if (index >= 0) { - return { - x: x[index], - y: y[index], - }; - } else { - index = ~index; - if ( - (index !== 0 && Math.abs(x[index] - target) > 0.5) || - index === x.length - ) { - return { - x: x[index - 1], - y: y[index - 1], - }; - } else { - return { - x: x[index], - y: y[index], - }; - } - } -} diff --git a/src/xy/xyFindClosestPoint.ts b/src/xy/xyFindClosestPoint.ts new file mode 100644 index 00000000..78e546f1 --- /dev/null +++ b/src/xy/xyFindClosestPoint.ts @@ -0,0 +1,25 @@ +import binarySearch from 'binary-search'; +import { DataXY, PointXY } from 'cheminfo-types'; + +import { xFindClosestIndex } from '../x/xFindClosestIndex'; + +/** + * Finds the closest point + * + * @param data - x array should be sorted and ascending + * @param target - target to search + * @returns - closest point + */ +export function xyFindClosestPoint( + /** points */ + data: DataXY, + target: number, +): PointXY { + const { x, y } = data; + + const index = xFindClosestIndex(x, target); + return { + x: x[index], + y: y[index], + }; +}