/**
 * Check the similarity between array created by xyMassCenterVector
 * @param array1 - first mass center vector.
 * @param array2 - second mass center vector.
 * @param options - options.
 * @returns similarity score between 0 and 1.
 */
export function xMassCenterVectorSimilarity(array1, array2, options = {}) {
    const { recenter = true, similarityFct = (a, b) => (a === b ? 1 : 0), } = options;
    const depth1 = getDepth(array1);
    const depth2 = getDepth(array2);
    const depth = Math.min(depth1, depth2);
    // need to copy the array because we shift the data in place if recenter is true
    if (recenter) {
        array1 = array1.slice();
    }
    let similarity = 0;
    // we will compare level by level
    // and recenter the array at each level
    for (let level = 0; level < depth; level++) {
        const maxSimilarity = 1 / depth / (1 << level);
        for (let slot = 0; slot < 1 << level; slot++) {
            const index = (1 << level) - 1 + slot;
            const value1 = array1[index];
            const value2 = array2[index];
            similarity += similarityFct(value1, value2) * maxSimilarity;
            if (recenter) {
                shiftSubtree(array1, depth, level, slot, value2 - value1);
            }
        }
    }
    return similarity;
}
function shiftSubtree(array, depth, level, slot, shift) {
    for (let currentLevel = level; currentLevel < depth; currentLevel++) {
        const levelSlotShift = slot * (1 << (currentLevel - level));
        const levelShift = (1 << currentLevel) - 1;
        const levelSlotSize = 1 << (currentLevel - level);
        for (let slotIndex = levelSlotShift; slotIndex < levelSlotShift + levelSlotSize; slotIndex++) {
            const index = levelShift + slotIndex;
            array[index] += shift;
        }
    }
}
function getDepth(array) {
    const depth = Math.log2(array.length + 1);
    if (depth % 1 !== 0) {
        throw new Error('the array length is not a power of 2 minus 1');
    }
    return depth;
}
//# sourceMappingURL=xMassCenterVectorSimilarity.js.map