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.
142 lines
3.4 KiB
142 lines
3.4 KiB
4 years ago
|
'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])
|
||
|
}
|