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.
138 lines
2.9 KiB
138 lines
2.9 KiB
'use strict'
|
|
|
|
module.exports = boxIntersectWrapper
|
|
|
|
var pool = require('typedarray-pool')
|
|
var sweep = require('./lib/sweep')
|
|
var boxIntersectIter = require('./lib/intersect')
|
|
|
|
function boxEmpty(d, box) {
|
|
for(var j=0; j<d; ++j) {
|
|
if(!(box[j] <= box[j+d])) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
//Unpack boxes into a flat typed array, remove empty boxes
|
|
function convertBoxes(boxes, d, data, ids) {
|
|
var ptr = 0
|
|
var count = 0
|
|
for(var i=0, n=boxes.length; i<n; ++i) {
|
|
var b = boxes[i]
|
|
if(boxEmpty(d, b)) {
|
|
continue
|
|
}
|
|
for(var j=0; j<2*d; ++j) {
|
|
data[ptr++] = b[j]
|
|
}
|
|
ids[count++] = i
|
|
}
|
|
return count
|
|
}
|
|
|
|
//Perform type conversions, check bounds
|
|
function boxIntersect(red, blue, visit, full) {
|
|
var n = red.length
|
|
var m = blue.length
|
|
|
|
//If either array is empty, then we can skip this whole thing
|
|
if(n <= 0 || m <= 0) {
|
|
return
|
|
}
|
|
|
|
//Compute dimension, if it is 0 then we skip
|
|
var d = (red[0].length)>>>1
|
|
if(d <= 0) {
|
|
return
|
|
}
|
|
|
|
var retval
|
|
|
|
//Convert red boxes
|
|
var redList = pool.mallocDouble(2*d*n)
|
|
var redIds = pool.mallocInt32(n)
|
|
n = convertBoxes(red, d, redList, redIds)
|
|
|
|
if(n > 0) {
|
|
if(d === 1 && full) {
|
|
//Special case: 1d complete
|
|
sweep.init(n)
|
|
retval = sweep.sweepComplete(
|
|
d, visit,
|
|
0, n, redList, redIds,
|
|
0, n, redList, redIds)
|
|
} else {
|
|
|
|
//Convert blue boxes
|
|
var blueList = pool.mallocDouble(2*d*m)
|
|
var blueIds = pool.mallocInt32(m)
|
|
m = convertBoxes(blue, d, blueList, blueIds)
|
|
|
|
if(m > 0) {
|
|
sweep.init(n+m)
|
|
|
|
if(d === 1) {
|
|
//Special case: 1d bipartite
|
|
retval = sweep.sweepBipartite(
|
|
d, visit,
|
|
0, n, redList, redIds,
|
|
0, m, blueList, blueIds)
|
|
} else {
|
|
//General case: d>1
|
|
retval = boxIntersectIter(
|
|
d, visit, full,
|
|
n, redList, redIds,
|
|
m, blueList, blueIds)
|
|
}
|
|
|
|
pool.free(blueList)
|
|
pool.free(blueIds)
|
|
}
|
|
}
|
|
|
|
pool.free(redList)
|
|
pool.free(redIds)
|
|
}
|
|
|
|
return retval
|
|
}
|
|
|
|
|
|
var RESULT
|
|
|
|
function appendItem(i,j) {
|
|
RESULT.push([i,j])
|
|
}
|
|
|
|
function intersectFullArray(x) {
|
|
RESULT = []
|
|
boxIntersect(x, x, appendItem, true)
|
|
return RESULT
|
|
}
|
|
|
|
function intersectBipartiteArray(x, y) {
|
|
RESULT = []
|
|
boxIntersect(x, y, appendItem, false)
|
|
return RESULT
|
|
}
|
|
|
|
//User-friendly wrapper, handle full input and no-visitor cases
|
|
function boxIntersectWrapper(arg0, arg1, arg2) {
|
|
var result
|
|
switch(arguments.length) {
|
|
case 1:
|
|
return intersectFullArray(arg0)
|
|
case 2:
|
|
if(typeof arg1 === 'function') {
|
|
return boxIntersect(arg0, arg0, arg1, true)
|
|
} else {
|
|
return intersectBipartiteArray(arg0, arg1)
|
|
}
|
|
case 3:
|
|
return boxIntersect(arg0, arg1, arg2, false)
|
|
default:
|
|
throw new Error('box-intersect: Invalid arguments')
|
|
}
|
|
} |