import type { DataXY } from 'cheminfo-types'; interface XYWeightedMergeOptions { /** * window for abscissas to merge * @default 0.001 */ groupWidth?: number; } /** * Merge abscissas values on similar ordinates and weight the group of abscissas * @param data - object containing 2 properties x and y * @param options - options * @returns array of merged and weighted points */ export function xyWeightedMerge( data: DataXY, options: XYWeightedMergeOptions = {}, ): DataXY { const { x, y } = data; const { groupWidth = 0.001 } = options; const merged: DataXY = { x: [], y: [] }; const weightedAbscissa: DataXY = { x: [], y: [] }; let size = 0; let index = 0; while (index < x.length) { if (size === 0 || x[index] - merged.x[size - 1] > groupWidth) { weightedAbscissa.x.push(x[index] * y[index]); weightedAbscissa.y.push(y[index]); merged.x.push(x[index]); merged.y.push(y[index]); index++; size++; } else { weightedAbscissa.x[size - 1] += x[index] * y[index]; weightedAbscissa.y[size - 1] += y[index]; merged.x[size - 1] = x[index]; merged.y[size - 1] += y[index]; index++; } } for (let i = 0; i < merged.x.length; i++) { merged.x[i] = weightedAbscissa.x[i] / weightedAbscissa.y[i]; } return merged; }