Skip to content
Snippets Groups Projects
Commit a8d057aa authored by Alexander Rose's avatar Alexander Rose
Browse files

added intersectionSize to interval, sorted-array, ordered-set

parent 87eafde5
No related branches found
No related tags found
No related merge requests found
...@@ -73,4 +73,10 @@ describe('interval', () => { ...@@ -73,4 +73,10 @@ describe('interval', () => {
test('predIndexInt3', Interval.findPredecessorIndexInInterval(Interval.ofRange(3, 10), 5, Interval.ofRange(2, 6)), 2); test('predIndexInt3', Interval.findPredecessorIndexInInterval(Interval.ofRange(3, 10), 5, Interval.ofRange(2, 6)), 2);
testI('findRange', Interval.findRange(r05, 2, 3), Interval.ofRange(2, 3)); testI('findRange', Interval.findRange(r05, 2, 3), Interval.ofRange(2, 3));
test('intersectionSize1', Interval.intersectionSize(Interval.ofRange(0, 5), Interval.ofRange(0, 5)), 6);
test('intersectionSize2', Interval.intersectionSize(Interval.ofRange(0, 5), Interval.ofRange(1, 2)), 2);
test('intersectionSize3', Interval.intersectionSize(Interval.ofRange(1, 2), Interval.ofRange(0, 5)), 2);
test('intersectionSize4', Interval.intersectionSize(Interval.ofRange(0, 5), Interval.ofRange(3, 8)), 3);
test('intersectionSize5', Interval.intersectionSize(Interval.ofRange(0, 5), Interval.ofRange(6, 8)), 0);
}); });
\ No newline at end of file
...@@ -116,6 +116,13 @@ describe('ordered set', () => { ...@@ -116,6 +116,13 @@ describe('ordered set', () => {
expect(OrderedSet.findRange(arr136, 2, 7)).toEqual(iB(1, 3)); expect(OrderedSet.findRange(arr136, 2, 7)).toEqual(iB(1, 3));
}) })
it('intersectionSize', () => {
expect(OrderedSet.intersectionSize(arr136, range1_4)).toEqual(2);
expect(OrderedSet.intersectionSize(arr12369, range1_4)).toEqual(3);
expect(OrderedSet.intersectionSize(OrderedSet.ofSortedArray([12, 13, 16]), range1_4)).toEqual(0);
expect(OrderedSet.intersectionSize(OrderedSet.ofSortedArray([1, 2, 4]), range1_4)).toEqual(3);
})
testEq('union ES', OrderedSet.union(empty, singleton10), [10]); testEq('union ES', OrderedSet.union(empty, singleton10), [10]);
testEq('union ER', OrderedSet.union(empty, range1_4), [1, 2, 3, 4]); testEq('union ER', OrderedSet.union(empty, range1_4), [1, 2, 3, 4]);
testEq('union EA', OrderedSet.union(empty, arr136), [1, 3, 6]); testEq('union EA', OrderedSet.union(empty, arr136), [1, 3, 6]);
......
...@@ -63,6 +63,8 @@ describe('sortedArray', () => { ...@@ -63,6 +63,8 @@ describe('sortedArray', () => {
compareArrays(SortedArray.indicesOf(SortedArray.ofSortedArray([10, 11, 12]), SortedArray.ofSortedArray([10, 12, 14])), [0, 2]); compareArrays(SortedArray.indicesOf(SortedArray.ofSortedArray([10, 11, 12]), SortedArray.ofSortedArray([10, 12, 14])), [0, 2]);
}) })
test('intersectionSize', SortedArray.intersectionSize(a1234, a2468), 2);
// console.log(Interval.findPredecessorIndexInInterval(Interval.ofBounds(0, 3), 2, Interval.ofBounds(0, 3))) // console.log(Interval.findPredecessorIndexInInterval(Interval.ofBounds(0, 3), 2, Interval.ofBounds(0, 3)))
// console.log(SortedArray.findPredecessorIndexInInterval(SortedArray.ofSortedArray([0, 1, 2]), 2, Interval.ofBounds(0, 3))) // console.log(SortedArray.findPredecessorIndexInInterval(SortedArray.ofSortedArray([0, 1, 2]), 2, Interval.ofBounds(0, 3)))
}); });
\ No newline at end of file
...@@ -58,4 +58,8 @@ export function findRange(int: Tuple, min: number, max: number) { ...@@ -58,4 +58,8 @@ export function findRange(int: Tuple, min: number, max: number) {
export function intersect(a: Tuple, b: Tuple) { export function intersect(a: Tuple, b: Tuple) {
if (!areIntersecting(a, b)) return Empty; if (!areIntersecting(a, b)) return Empty;
return ofBounds(Math.max(start(a), start(b)), Math.min(end(a), end(b))); return ofBounds(Math.max(start(a), start(b)), Math.min(end(a), end(b)));
}
export function intersectionSize(a: Tuple, b: Tuple) {
return size(findRange(a, min(b), max(b)))
} }
\ No newline at end of file
...@@ -72,6 +72,14 @@ export function findRange(set: OrderedSetImpl, min: number, max: number) { ...@@ -72,6 +72,14 @@ export function findRange(set: OrderedSetImpl, min: number, max: number) {
return I.is(set) ? I.findRange(set, min, max) : S.findRange(set, min, max); return I.is(set) ? I.findRange(set, min, max) : S.findRange(set, min, max);
} }
export function intersectionSize(a: OrderedSetImpl, b: OrderedSetImpl): number {
if (I.is(a)) {
if (I.is(b)) return I.intersectionSize(a, b);
return intersectionSizeSI(b, a);
} else if (I.is(b)) return intersectionSizeSI(a, b);
return S.intersectionSize(a, b);
}
export function union(a: OrderedSetImpl, b: OrderedSetImpl) { export function union(a: OrderedSetImpl, b: OrderedSetImpl) {
if (I.is(a)) { if (I.is(a)) {
if (I.is(b)) return unionII(a, b); if (I.is(b)) return unionII(a, b);
...@@ -165,6 +173,12 @@ function unionSI(a: S, b: I) { ...@@ -165,6 +173,12 @@ function unionSI(a: S, b: I) {
return ofSortedArray(indices); return ofSortedArray(indices);
} }
function intersectionSizeSI(a: S, b: I): number {
if (!I.size(b)) return 0;
const r = S.findRange(a, I.min(b), I.max(b));
return I.end(r) - I.start(r);
}
function intersectSI(a: S, b: I) { function intersectSI(a: S, b: I) {
if (!I.size(b)) return Empty; if (!I.size(b)) return Empty;
......
...@@ -161,15 +161,8 @@ export function isSubset(a: Nums, b: Nums) { ...@@ -161,15 +161,8 @@ export function isSubset(a: Nums, b: Nums) {
export function union(a: Nums, b: Nums) { export function union(a: Nums, b: Nums) {
if (a === b) return a; if (a === b) return a;
const { startI: sI, startJ: sJ, endI, endJ } = getSuitableIntersectionRange(a, b); const { startI, startJ, endI, endJ } = getSuitableIntersectionRange(a, b);
let i = sI, j = sJ; const commonCount = getCommonCount(a, b, startI, startJ, endI, endJ);
let commonCount = 0;
while (i < endI && j < endJ) {
const x = a[i], y = b[j];
if (x < y) { i++; }
else if (x > y) { j++; }
else { i++; j++; commonCount++; }
}
const lenA = a.length, lenB = b.length; const lenA = a.length, lenB = b.length;
// A === B || B is subset of A ==> A // A === B || B is subset of A ==> A
...@@ -181,12 +174,12 @@ export function union(a: Nums, b: Nums) { ...@@ -181,12 +174,12 @@ export function union(a: Nums, b: Nums) {
let offset = 0; let offset = 0;
// insert the "prefixes" // insert the "prefixes"
for (let k = 0; k < sI; k++) indices[offset++] = a[k]; for (let k = 0; k < startI; k++) indices[offset++] = a[k];
for (let k = 0; k < sJ; k++) indices[offset++] = b[k]; for (let k = 0; k < startJ; k++) indices[offset++] = b[k];
// insert the common part // insert the common part
i = sI; let i = startI;
j = sJ; let j = startJ;
while (i < endI && j < endJ) { while (i < endI && j < endJ) {
const x = a[i], y = b[j]; const x = a[i], y = b[j];
if (x < y) { indices[offset++] = x; i++; } if (x < y) { indices[offset++] = x; i++; }
...@@ -201,11 +194,14 @@ export function union(a: Nums, b: Nums) { ...@@ -201,11 +194,14 @@ export function union(a: Nums, b: Nums) {
return ofSortedArray(indices); return ofSortedArray(indices);
} }
export function intersect(a: Nums, b: Nums) { export function intersectionSize(a: Nums, b: Nums) {
if (a === b) return a; if (a === b) return size(a);
const { startI, startJ, endI, endJ } = getSuitableIntersectionRange(a, b);
return getCommonCount(a, b, startI, startJ, endI, endJ);
}
const { startI: sI, startJ: sJ, endI, endJ } = getSuitableIntersectionRange(a, b); function getCommonCount(a: Nums, b: Nums, startI: number, startJ: number, endI: number, endJ: number) {
let i = sI, j = sJ; let i = startI, j = startJ;
let commonCount = 0; let commonCount = 0;
while (i < endI && j < endJ) { while (i < endI && j < endJ) {
const x = a[i], y = b[j]; const x = a[i], y = b[j];
...@@ -213,6 +209,14 @@ export function intersect(a: Nums, b: Nums) { ...@@ -213,6 +209,14 @@ export function intersect(a: Nums, b: Nums) {
else if (x > y) { j++; } else if (x > y) { j++; }
else { i++; j++; commonCount++; } else { i++; j++; commonCount++; }
} }
return commonCount;
}
export function intersect(a: Nums, b: Nums) {
if (a === b) return a;
const { startI, startJ, endI, endJ } = getSuitableIntersectionRange(a, b);
const commonCount = getCommonCount(a, b, startI, startJ, endI, endJ);
const lenA = a.length, lenB = b.length; const lenA = a.length, lenB = b.length;
// no common elements // no common elements
...@@ -224,8 +228,8 @@ export function intersect(a: Nums, b: Nums) { ...@@ -224,8 +228,8 @@ export function intersect(a: Nums, b: Nums) {
const indices = new Int32Array(commonCount); const indices = new Int32Array(commonCount);
let offset = 0; let offset = 0;
i = sI; let i = startI;
j = sJ; let j = startJ;
while (i < endI && j < endJ) { while (i < endI && j < endJ) {
const x = a[i], y = b[j]; const x = a[i], y = b[j];
if (x < y) { i++; } if (x < y) { i++; }
......
...@@ -45,6 +45,8 @@ namespace Interval { ...@@ -45,6 +45,8 @@ namespace Interval {
export const findPredecessorIndex: <T extends number = number>(interval: Interval<T>, x: T) => number = Impl.findPredecessorIndex as any; export const findPredecessorIndex: <T extends number = number>(interval: Interval<T>, x: T) => number = Impl.findPredecessorIndex as any;
export const findPredecessorIndexInInterval: <T extends number = number>(interval: Interval<T>, x: T, bounds: Interval) => number = Impl.findPredecessorIndexInInterval as any; export const findPredecessorIndexInInterval: <T extends number = number>(interval: Interval<T>, x: T, bounds: Interval) => number = Impl.findPredecessorIndexInInterval as any;
export const findRange: <T extends number = number>(interval: Interval<T>, min: T, max: T) => Interval = Impl.findRange as any; export const findRange: <T extends number = number>(interval: Interval<T>, min: T, max: T) => Interval = Impl.findRange as any;
/** Size of the intersection of the two intervals */
export const intersectionSize: <T extends number = number>(a: Interval<T>, b: Interval<T>) => number = Impl.intersectionSize as any;
/** Get a new interval that is the intersection of the two intervals */ /** Get a new interval that is the intersection of the two intervals */
export const intersect: <T extends number = number>(a: Interval<T>, b: Interval<T>) => Interval<T> = Impl.intersect as any; export const intersect: <T extends number = number>(a: Interval<T>, b: Interval<T>) => Interval<T> = Impl.intersect as any;
......
...@@ -40,6 +40,7 @@ namespace OrderedSet { ...@@ -40,6 +40,7 @@ namespace OrderedSet {
export const findPredecessorIndex: <T extends number = number>(set: OrderedSet<T>, x: number) => number = Base.findPredecessorIndex as any; export const findPredecessorIndex: <T extends number = number>(set: OrderedSet<T>, x: number) => number = Base.findPredecessorIndex as any;
export const findPredecessorIndexInInterval: <T extends number = number>(set: OrderedSet<T>, x: T, range: Interval) => number = Base.findPredecessorIndexInInterval as any; export const findPredecessorIndexInInterval: <T extends number = number>(set: OrderedSet<T>, x: T, range: Interval) => number = Base.findPredecessorIndexInInterval as any;
export const findRange: <T extends number = number>(set: OrderedSet<T>, min: T, max: T) => Interval = Base.findRange as any; export const findRange: <T extends number = number>(set: OrderedSet<T>, min: T, max: T) => Interval = Base.findRange as any;
export const intersectionSize: <T extends number = number>(a: OrderedSet<T>, b: OrderedSet<T>) => number = Base.intersectionSize as any;
export function forEach<T extends number, Ctx>(set: OrderedSet<T>, f: (v: T, i: number, ctx: Ctx) => void, ctx?: Ctx): Ctx { export function forEach<T extends number, Ctx>(set: OrderedSet<T>, f: (v: T, i: number, ctx: Ctx) => void, ctx?: Ctx): Ctx {
return Base.forEach(set as any, f as any, ctx); return Base.forEach(set as any, f as any, ctx);
......
...@@ -42,6 +42,7 @@ namespace SortedArray { ...@@ -42,6 +42,7 @@ namespace SortedArray {
export const findPredecessorIndex: <T extends number = number>(array: SortedArray<T>, x: T) => number = Impl.findPredecessorIndex as any; export const findPredecessorIndex: <T extends number = number>(array: SortedArray<T>, x: T) => number = Impl.findPredecessorIndex as any;
export const findPredecessorIndexInInterval: <T extends number = number>(array: SortedArray<T>, x: T, bounds: Interval) => number = Impl.findPredecessorIndexInInterval as any; export const findPredecessorIndexInInterval: <T extends number = number>(array: SortedArray<T>, x: T, bounds: Interval) => number = Impl.findPredecessorIndexInInterval as any;
export const findRange: <T extends number = number>(array: SortedArray<T>, min: T, max: T) => Interval = Impl.findRange as any; export const findRange: <T extends number = number>(array: SortedArray<T>, min: T, max: T) => Interval = Impl.findRange as any;
export const intersectionSize: <T extends number = number>(a: SortedArray<T>, b: SortedArray<T>) => number = Impl.intersectionSize as any;
export const deduplicate: <T extends number = number>(array: SortedArray<T>) => SortedArray<T> = Impl.deduplicate as any; export const deduplicate: <T extends number = number>(array: SortedArray<T>) => SortedArray<T> = Impl.deduplicate as any;
/** Returns indices of xs in the array. E.g. indicesOf([10, 11, 12], [10, 12]) ==> [0, 2] */ /** Returns indices of xs in the array. E.g. indicesOf([10, 11, 12], [10, 12]) ==> [0, 2] */
......
...@@ -41,8 +41,7 @@ export function getPolymerElementCount(unit: Unit) { ...@@ -41,8 +41,7 @@ export function getPolymerElementCount(unit: Unit) {
case Unit.Kind.Gaussians: case Unit.Kind.Gaussians:
while (polymerIt.hasNext) { while (polymerIt.hasNext) {
const { start, end } = polymerIt.move() const { start, end } = polymerIt.move()
// TODO add OrderedSet.intersectionSize count += OrderedSet.intersectionSize(Interval.ofBounds(elements[start], elements[end - 1]), elements)
count += OrderedSet.size(OrderedSet.intersect(Interval.ofBounds(elements[start], elements[end - 1]), elements))
} }
break break
} }
...@@ -222,7 +221,7 @@ export class AtomicPolymerBackboneIterator<T extends number = number> implements ...@@ -222,7 +221,7 @@ export class AtomicPolymerBackboneIterator<T extends number = number> implements
} }
this.hasNext = residueIt.hasNext || polymerIt.hasNext this.hasNext = residueIt.hasNext || polymerIt.hasNext
// console.log('hasNext', this.hasNext) // console.log('hasNext', this.hasNext)
// console.log('value', this.value) // console.log('value', this.value)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment