StackGenVis: Alignment of Data, Algorithms, and Models for Stacking Ensemble Learning Using Performance Metrics https://doi.org/10.1109/TVCG.2020.3030352
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
StackGenVis/frontend/node_modules/box-intersect/lib/median.js

142 lines
3.4 KiB

'use strict'
module.exports = findMedian
var genPartition = require('./partition')
var partitionStartLessThan = genPartition('lo<p0', ['p0'])
var PARTITION_THRESHOLD = 8 //Cut off for using insertion sort in findMedian
//Base case for median finding: Use insertion sort
function insertionSort(d, axis, start, end, boxes, ids) {
var elemSize = 2 * d
var boxPtr = elemSize * (start+1) + axis
for(var i=start+1; i<end; ++i, boxPtr+=elemSize) {
var x = boxes[boxPtr]
for(var j=i, ptr=elemSize*(i-1);
j>start && boxes[ptr+axis] > x;
--j, ptr-=elemSize) {
//Swap
var aPtr = ptr
var bPtr = ptr+elemSize
for(var k=0; k<elemSize; ++k, ++aPtr, ++bPtr) {
var y = boxes[aPtr]
boxes[aPtr] = boxes[bPtr]
boxes[bPtr] = y
}
var tmp = ids[j]
ids[j] = ids[j-1]
ids[j-1] = tmp
}
}
}
//Find median using quick select algorithm
// takes O(n) time with high probability
function findMedian(d, axis, start, end, boxes, ids) {
if(end <= start+1) {
return start
}
var lo = start
var hi = end
var mid = ((end + start) >>> 1)
var elemSize = 2*d
var pivot = mid
var value = boxes[elemSize*mid+axis]
while(lo < hi) {
if(hi - lo < PARTITION_THRESHOLD) {
insertionSort(d, axis, lo, hi, boxes, ids)
value = boxes[elemSize*mid+axis]
break
}
//Select pivot using median-of-3
var count = hi - lo
var pivot0 = (Math.random()*count+lo)|0
var value0 = boxes[elemSize*pivot0 + axis]
var pivot1 = (Math.random()*count+lo)|0
var value1 = boxes[elemSize*pivot1 + axis]
var pivot2 = (Math.random()*count+lo)|0
var value2 = boxes[elemSize*pivot2 + axis]
if(value0 <= value1) {
if(value2 >= value1) {
pivot = pivot1
value = value1
} else if(value0 >= value2) {
pivot = pivot0
value = value0
} else {
pivot = pivot2
value = value2
}
} else {
if(value1 >= value2) {
pivot = pivot1
value = value1
} else if(value2 >= value0) {
pivot = pivot0
value = value0
} else {
pivot = pivot2
value = value2
}
}
//Swap pivot to end of array
var aPtr = elemSize * (hi-1)
var bPtr = elemSize * pivot
for(var i=0; i<elemSize; ++i, ++aPtr, ++bPtr) {
var x = boxes[aPtr]
boxes[aPtr] = boxes[bPtr]
boxes[bPtr] = x
}
var y = ids[hi-1]
ids[hi-1] = ids[pivot]
ids[pivot] = y
//Partition using pivot
pivot = partitionStartLessThan(
d, axis,
lo, hi-1, boxes, ids,
value)
//Swap pivot back
var aPtr = elemSize * (hi-1)
var bPtr = elemSize * pivot
for(var i=0; i<elemSize; ++i, ++aPtr, ++bPtr) {
var x = boxes[aPtr]
boxes[aPtr] = boxes[bPtr]
boxes[bPtr] = x
}
var y = ids[hi-1]
ids[hi-1] = ids[pivot]
ids[pivot] = y
//Swap pivot to last pivot
if(mid < pivot) {
hi = pivot-1
while(lo < hi &&
boxes[elemSize*(hi-1)+axis] === value) {
hi -= 1
}
hi += 1
} else if(pivot < mid) {
lo = pivot + 1
while(lo < hi &&
boxes[elemSize*lo+axis] === value) {
lo += 1
}
} else {
break
}
}
//Make sure pivot is at start
return partitionStartLessThan(
d, axis,
start, mid, boxes, ids,
boxes[elemSize*mid+axis])
}