diff --git a/examples/js/src/interpolation.js b/examples/js/src/interpolation.js deleted file mode 100644 index 0136ef1..0000000 --- a/examples/js/src/interpolation.js +++ /dev/null @@ -1,195 +0,0 @@ -function doInterpolation(sampleSet, remainderSet, interpSubset, properties) { - var distance = calculateDistancePoker; - // var distance = calculateEuclideanDistance; - - console.log("Brute-force"); - - for (var i = 0; i < remainderSet.length; i++) { - var node = remainderSet[i], - minNode = sampleSet[0], - minDist = 0, - sampleCache = []; - - minDist = distance(node, minNode, properties); - - for (var j = 1, sample; j < sampleSet.length; j++) { - sample = sampleSet[j]; - if ((sample !== node) && (distance(node, sample, properties) < minDist)) { - minDist = distance(node, sample, properties); - minNode = sample; - } - } - - // console.log() - - for (var k = 0; k < interpSubset.length; k++) { - sampleCache[k] = distance(node, interpSubset[k], properties); - } - var radius = distance(node, minNode, properties); - placeNearToNearestNeighbour(node, minNode, interpSubset, sampleCache, radius); - } -} - - -function placeNearToNearestNeighbour(node, minNode, sample, sampleCache, radius) { - var - dist0 = 0.0, - dist90 = 0.0, - dist180 = 0.0, - dist270 = 0.0, - lowBound = 0.0, - highBound = 0.0; - - dist0 = sumDistToSample(node, centerPoint(0, radius, minNode.x, minNode.y), sample, sampleCache); - dist90 = sumDistToSample(node, centerPoint(90, radius, minNode.x, minNode.y), sample, sampleCache); - dist180 = sumDistToSample(node, centerPoint(180, radius, minNode.x, minNode.y), sample, sampleCache); - dist270 = sumDistToSample(node, centerPoint(270, radius, minNode.x, minNode.y), sample, sampleCache); - - // console.log(dist0, dist90, dist180, dist270); - - // Determine the closest quadrant - - if (dist0 == dist180) { - if (dist90 > dist270) - lowBound = highBound = 270; - else - lowBound = highBound = 90; - - } else if (dist90 == dist270) { - if (dist0 > dist180) - lowBound = highBound = 180; - else - lowBound = highBound = 0; - } else if (dist0 > dist180) { - if (dist90 > dist270) { - lowBound = 180; - highBound = 270; - } else { - lowBound = 90; - highBound = 180; - } - } else { - if (dist90 > dist270) { - lowBound = 270; - highBound = 360; - } else { - lowBound = 0; - highBound = 90; - } - } - - var angle = binarySearch(lowBound, highBound, minNode.x, minNode.y, radius, node, sample, sampleCache); - var newPoint = centerPoint(angle, radius, minNode.x, minNode.y); - - // console.log(newPoint); - node.x = newPoint.x; - node.y = newPoint.y; - - // for (var i = 0; i < 20; i++) { - // var forces = sumForcesToSample(node, sample, sampleCache); - // // console.log(forces); - // node.x += forces.x; - // node.y += forces.y; - // } - -} - - -function centerPoint(angle, radius, posX, posY) { - var x = posX + Math.cos(toRadians(angle) * radius); - var y = posY + Math.sin(toRadians(angle) * radius); - - return { - x: x, - y: y - }; -} - -function toRadians(degrees) { - return degrees * (Math.PI / 180); -} - -function sumDistToSample(node, point, sample, sampleCache) { - var total = 0.0; - // console.log(total, sample); - - for (var i = 0; i < sample.length; i++) { - var s = sample[i]; - var realDist = Math.hypot(s.x - point.x, s.y - point.y); - var desDist = sampleCache[i]; - total += Math.abs(realDist - desDist); - } - - return total; -} - - -function sumForcesToSample(node, sample, sampleCache) { - var x = 0, - y = 0, - // len = 0, - dist = 0, - force, - SPRING_FORCE = 0.7; - - for (var i = 0, unitX, unitY; i < sample.length; i++) { - var s = sample[i]; - if (s !== node) { - unitX = s.x - node.x; - unitY = s.y - node.y; - - // Normalize coordinates - len = Math.sqrt(unitX * unitX + unitY * unitY); - unitX /= len; - unitY /= len; - - console.log(unitX, unitY); - - var realDist = Math.sqrt(unitX * unitX + unitY * unitY); - var desDist = sampleCache[i]; - dist += realDist - desDist; - force = (SPRING_FORCE * dist); - - x += unitX * force; - y += unitY * force; - } - - x *= (1.0 / sample.length); - y *= (1.0 / sample.length); - - return { - x: x, - y: y - }; - } -} - - -function binarySearch(lb, hb, x, y, r, node, sample, sampleCache) { - while (lb <= hb) { - var mid = Math.round((lb + hb) / 2); - - if ((mid === lb) || (mid === hb)) { - if (sumDistToSample(node, centerPoint(lb, r, x, y), sample, sampleCache) >= - sumDistToSample(node, centerPoint(hb, r, x, y), sample, sampleCache)) { - return hb; - } else { - return lb; - } - } else { - var distMidLeft = sumDistToSample(node, centerPoint(mid + 1, r, x, y), sample, sampleCache); - var distMidRight = sumDistToSample(node, centerPoint(mid - 1, r, x, y), sample, sampleCache); - var distMid = sumDistToSample(node, centerPoint(mid, r, x, y), sample, sampleCache); - - if (distMid > distMidLeft) { - lb = mid + 1; - } else if (distMid > distMidRight) { - hb = mid - 1; - } else { - return mid; - } - } - } - - return -1; -} diff --git a/examples/js/src/interpolationPivots.js b/examples/js/src/interpolationPivots.js deleted file mode 100644 index 7fd2e4d..0000000 --- a/examples/js/src/interpolationPivots.js +++ /dev/null @@ -1,269 +0,0 @@ -function doInterpolationPivots(sampleSet, remainderSet, interpSubset, properties) { - var distance = calculateDistancePoker; - // var distance = calculateEuclideanDistance; - - // Pivot based parent finding - - var numBuckets = Math.floor(Math.sqrt(sampleSet.length)), - // numPivots = Math.floor(Math.sqrt(sampleSet.length)), - numPivots = 3, - parents = [], - maxDists = [], - bucketWidths = [], - pivotsBuckets = []; - - console.log("Parents, pivots=", numPivots); - - var pivots = createRandomSample(sampleSet.concat(remainderSet), sampleSet.length, numPivots); - - for (var i = 0; i < numPivots; i++) { - pivotsBuckets[i] = []; - for (var j = 0; j < numBuckets; j++) { - pivotsBuckets[i][j] = []; - } - } - - // Pre-processing - var fullDists = [] - for (var i = 0; i < sampleSet.length; i++) { - fullDists[i] = []; - } - - for (var j = 0, maxDist = -1; j < numPivots; j++) { - var c1 = pivots[j]; - for (var i = 0; i < sampleSet.length; i++) { - var c2 = sampleSet[i]; - if (c1 !== c2) { - var dist = distance(c1, c2, properties); - // console.log(dist, c1, c2); - if (dist > maxDist) { - maxDist = dist; - } - fullDists[i][j] = dist; - } else { - fullDists[i][j] = 0.0001; - } - } - maxDists.push(maxDist); - bucketWidths.push(maxDist / numBuckets); - } - - // console.log(fullDists); - - for (var j = 0; j < numPivots; j++) { - var bucketWidth = bucketWidths[j]; - for (var i = 0; i < sampleSet.length; i++) { - var tmp = pivotsBuckets[j][Math.floor((fullDists[i][j] - 0.0001) / bucketWidth)]; - // pivotsBuckets[j][Math.floor((fullDists[i][j] - 0.0001) / bucketWidth)].push(sampleSet[i]); - // console.log(tmp, i, j, bucketWidth, Math.floor((fullDists[i][j] - 0.0001) / bucketWidth)); - tmp.push(sampleSet[i]); - } - } - - for (var i = 0; i < remainderSet.length; i++) { - var node = remainderSet[i], - minNode = sampleSet[0], - minDist = 0, - sampleCache = []; - - // Pivot based parent search - - var node = remainderSet[i]; - var clDist = Number.MAX_VALUE; - for (var p = 0; p < numPivots; p++) { - var comp = pivots[p]; - var bucketWidth = bucketWidths[p]; - if (node !== comp) { - var dist = distance(node, comp, properties); - bNum = Math.floor((dist - 0.0001) / bucketWidth); - if (bNum >= numBuckets) { - bNum = numBuckets - 1; - } else if (bNum < 0) { - bNum = 0; - } - var bucketContents = pivotsBuckets[p][bNum]; - for (var w = 0; w < bucketContents.length; w++) { - var c1 = bucketContents[w]; - if (c1 != node) { - dist = distance(c1, node, properties); - if (dist <= clDist) { - clDist = dist; - minNode = bucketContents[w]; - } - } - } - } - } - - - for (var k = 0; k < interpSubset.length; k++) { - sampleCache[k] = distance(node, interpSubset[k], properties); - } - var radius = distance(node, minNode, properties); - placeNearToNearestNeighbour(node, minNode, interpSubset, sampleCache, radius); - } -} - - -function placeNearToNearestNeighbour(node, minNode, sample, sampleCache, radius) { - var - dist0 = 0.0, - dist90 = 0.0, - dist180 = 0.0, - dist270 = 0.0, - lowBound = 0.0, - highBound = 0.0; - - dist0 = sumDistToSample(node, centerPoint(0, radius, minNode.x, minNode.y), sample, sampleCache); - dist90 = sumDistToSample(node, centerPoint(90, radius, minNode.x, minNode.y), sample, sampleCache); - dist180 = sumDistToSample(node, centerPoint(180, radius, minNode.x, minNode.y), sample, sampleCache); - dist270 = sumDistToSample(node, centerPoint(270, radius, minNode.x, minNode.y), sample, sampleCache); - - // console.log(dist0, dist90, dist180, dist270); - - // Determine the closest quadrant - - if (dist0 == dist180) { - if (dist90 > dist270) - lowBound = highBound = 270; - else - lowBound = highBound = 90; - - } else if (dist90 == dist270) { - if (dist0 > dist180) - lowBound = highBound = 180; - else - lowBound = highBound = 0; - } else if (dist0 > dist180) { - if (dist90 > dist270) { - lowBound = 180; - highBound = 270; - } else { - lowBound = 90; - highBound = 180; - } - } else { - if (dist90 > dist270) { - lowBound = 270; - highBound = 360; - } else { - lowBound = 0; - highBound = 90; - } - } - - var angle = binarySearch(lowBound, highBound, minNode.x, minNode.y, radius, node, sample, sampleCache); - var newPoint = centerPoint(angle, radius, minNode.x, minNode.y); - - // console.log(newPoint); - node.x = newPoint.x; - node.y = newPoint.y; - - // for (var i = 0; i < 20; i++) { - // var forces = sumForcesToSample(node, sample, sampleCache); - // // console.log(forces); - // node.x += forces.x; - // node.y += forces.y; - // } - -} - - -function centerPoint(angle, radius, posX, posY) { - var x = posX + Math.cos(toRadians(angle) * radius); - var y = posY + Math.sin(toRadians(angle) * radius); - - return { - x: x, - y: y - }; -} - -function toRadians(degrees) { - return degrees * (Math.PI / 180); -} - -function sumDistToSample(node, point, sample, sampleCache) { - var total = 0.0; - // console.log(total, sample); - - for (var i = 0; i < sample.length; i++) { - var s = sample[i]; - var realDist = Math.hypot(s.x - point.x, s.y - point.y); - var desDist = sampleCache[i]; - total += Math.abs(realDist - desDist); - } - - return total; -} - - -function sumForcesToSample(node, sample, sampleCache) { - var x = 0, - y = 0, - // len = 0, - dist = 0, - force, - SPRING_FORCE = 0.7; - - for (var i = 0, unitX, unitY; i < sample.length; i++) { - var s = sample[i]; - if (s !== node) { - unitX = s.x - node.x; - unitY = s.y - node.y; - - // Normalize coordinates - len = Math.sqrt(unitX * unitX + unitY * unitY); - unitX /= len; - unitY /= len; - - console.log(unitX, unitY); - - var realDist = Math.sqrt(unitX * unitX + unitY * unitY); - var desDist = sampleCache[i]; - dist += realDist - desDist; - force = (SPRING_FORCE * dist); - - x += unitX * force; - y += unitY * force; - } - - x *= (1.0 / sample.length); - y *= (1.0 / sample.length); - - return { - x: x, - y: y - }; - } -} - - -function binarySearch(lb, hb, x, y, r, node, sample, sampleCache) { - while (lb <= hb) { - var mid = Math.round((lb + hb) / 2); - - if ((mid === lb) || (mid === hb)) { - if (sumDistToSample(node, centerPoint(lb, r, x, y), sample, sampleCache) >= - sumDistToSample(node, centerPoint(hb, r, x, y), sample, sampleCache)) { - return hb; - } else { - return lb; - } - } else { - var distMidLeft = sumDistToSample(node, centerPoint(mid + 1, r, x, y), sample, sampleCache); - var distMidRight = sumDistToSample(node, centerPoint(mid - 1, r, x, y), sample, sampleCache); - var distMid = sumDistToSample(node, centerPoint(mid, r, x, y), sample, sampleCache); - - if (distMid > distMidLeft) { - lb = mid + 1; - } else if (distMid > distMidRight) { - hb = mid - 1; - } else { - return mid; - } - } - } - - return -1; -} diff --git a/examples/js/src/neighbourSampling-papaparsing-nist-images.js b/examples/js/src/neighbourSampling-papaparsing-nist-images.js deleted file mode 100644 index 7a0b539..0000000 --- a/examples/js/src/neighbourSampling-papaparsing-nist-images.js +++ /dev/null @@ -1,579 +0,0 @@ -// Get the width and heigh of the SVG element. -var width = +document.getElementById('svg').clientWidth, - height = +document.getElementById('svg').clientHeight; - -var svg = d3.select("svg") - .call(d3.zoom().scaleExtent([0.0001, 1000000]).on("zoom", function () { - svg.attr("transform", d3.event.transform); - })) - .append("g"); - - -var div = d3.select("body").append("div") - .attr("class", "tooltip") - .style("opacity", 0); - -var brush = d3.brush() - .extent([[-9999999, -9999999], [9999999, 9999999]]) - .on("end", brushEnded); - -svg.append("g") - .attr("class", "brush") - .call(brush); - -var intercom = Intercom.getInstance(); - -intercom.on("select", unSelectNodes); - -var imgs = svg.selectAll("image"); - -var links = [], - nodes, - node, - props, - norm, - p1 = 0, - p2 = 0, - size, - distanceFunction, - simulation, - velocities = [], - rendering = true, // Rendering during the execution. - forceName = "forces", - springForce = false, - tooltipWidth = 0, - fileName = "", - selectedData, - clickedIndex = -1; - -// Default parameters -var MULTIPLIER = 50, - PERPLEXITY = 30, - LEARNING_RATE = 10, - NEIGHBOUR_SIZE = 6, - SAMPLE_SIZE = 3, - PIVOTS = false, - NUM_PIVOTS = 3, - ITERATIONS = 300, - FULL_ITERATIONS = 20, - NODE_SIZE = 10, - COLOR_ATTRIBUTE = ""; - -// Create a color scheme for a range of numbers. -var color = d3.scaleOrdinal(d3.schemeCategory10); - -/** - * Parse the data from the provided csv file using Papa Parse library - * @param {file} evt - csv file. - */ -function parseFile(evt) { - // Clear the previous nodes - d3.selectAll(".nodes").remove(); - springForce = false; - - fileName = evt.target.files[0].name; - - Papa.parse(evt.target.files[0], { - header: true, - dynamicTyping: true, - skipEmptyLines: true, - complete: function (results) { - processData(results.data, results.error); - } - }); -} - -/** - * Process the data and pass it into D3 force simulation. - * @param {array} data - * @param {object} error - */ -function processData(data, error) { - if (error) throw error.message; - - nodes = data; - - // Number of iterations before stopping. - size = nodes.length; - - console.log("Number of iterations: ", ITERATIONS); - - // Start by placing the nodes at the center (its starting positions). - simulation = d3.forceSimulation(); - - console.log("n =", nodes.length); - - // Calculate normalization arguments and get the list of - // properties of the nodes. - norm = calculateNormalization(nodes); - props = Object.keys(nodes[0]); - COLOR_ATTRIBUTE = props[0]; - - var opts = document.getElementById('color_attr').options; - - props.forEach(function (d) { - opts.add(new Option(d, d, (d === COLOR_ATTRIBUTE) ? true : false)); - }); - - // Add the nodes to DOM. - node = svg.append("g") - .attr("class", "nodes") - .selectAll("circle") - .data(nodes) - .enter().append("circle") - .attr("r", NODE_SIZE) - .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") - // Color code the data points by a property (for Poker Hands, - // it is a CLASS property). - .attr("fill", function (d) { - return color(d[COLOR_ATTRIBUTE]); - }) - .on("mouseover", function (d) { - highlightOnHover(d[COLOR_ATTRIBUTE]); - }) - .on("mouseout", function (d) { - div.transition() - .duration(500) - .style("opacity", 0); - node.attr("opacity", 1); - }) - .on("click", function (d) { - if (clickedIndex !== d.index) { - highlightNeighbours(d.index, springForce ? Array.from(simulation.force(forceName).nodeNeighbours(d.index).keys()) : []); - clickedIndex = d.index; - } else { - svg.selectAll("image").remove(); - node.attr("r", NODE_SIZE).attr("stroke-width", 0); - clickedIndex = -1; - } - }); - - // Pass the nodes to the D3 force simulation. - simulation - .nodes(nodes) - .on("tick", ticked) - .on("end", ended); - - function ticked() { - // If rendering is selected, then draw at every iteration. - if (rendering === true) { - node - .attr("cx", function (d) { - return d.x; - }) - .attr("cy", function (d) { - return d.y; - }); - } - } - - function ended() { - if (rendering !== true) { - node - .attr("cx", function (d) { - return d.x; - }) - .attr("cy", function (d) { - return d.y; - }); - } - - if (p1 !== 0) { - // Performance time measurement - p2 = performance.now(); - console.log("Execution time: " + (p2 - p1)); - // Do not calculate stress for data sets bigger than 100 000. - // if (nodes.length <= 100000) { - // console.log("Stress: ", simulation.force(forceName).stress()); - // } - p1 = 0; - p2 = 0; - } - } -}; - - -function brushEnded() { - var s = d3.event.selection, - results = []; - - if (s) { - - var x0 = s[0][0] - width / 2, - y0 = s[0][1] - height / 2, - x1 = s[1][0] - width / 2, - y1 = s[1][1] - height / 2; - - if (nodes) { - var sel = node.filter(function (d) { - if (d.x > x0 && d.x < x1 && d.y > y0 && d.y < y1) { - return true; - } - return false; - }).data(); - - results = sel.map(function (a) { return a.index; }); - } - - intercom.emit("select", { name: fileName, indices: results }); - - d3.select(".brush").call(brush.move, null); - } -} - -/** - * Initialize the Chalmers' 1996 algorithm and start simulation. - */ -function startNeighbourSamplingSimulation() { - springForce = true; - simulation.stop(); - p1 = performance.now(); - - simulation - .alphaDecay(1 - Math.pow(0.001, 1 / ITERATIONS)) - .force(forceName, d3.forceNeighbourSamplingDistance() - // Set the parameters for the algorithm (optional). - .neighbourSize(NEIGHBOUR_SIZE) - .sampleSize(SAMPLE_SIZE) - .multiplier(MULTIPLIER) - // The distance function that will be used to calculate distances - // between nodes. - .distance(function (s, t) { - return distanceFunction(s, t, props, norm); - })); - // Restart the simulation. - console.log(simulation.force(forceName).neighbourSize(), simulation.force(forceName).sampleSize()); - simulation.alpha(1).restart(); -} - -/** - * Initialize the hybrid layout algorithm and start simulation. - */ -function startHybridSimulation() { - springForce = false; - d3.selectAll(".nodes").remove(); - simulation.stop(); - p1 = performance.now(); - - hybridSimulation = d3.hybridSimulation(nodes); - - hybridSimulation - .multiplier(MULTIPLIER) - .sampleIterations(ITERATIONS) - .pivots(PIVOTS) - .numPivots(NUM_PIVOTS) - .fullIterations(FULL_ITERATIONS) - .neighbourSize(NEIGHBOUR_SIZE) - .sampleSize(SAMPLE_SIZE); - - var sample = hybridSimulation.sample(); - var remainder = hybridSimulation.remainder(); - - // Add the nodes to DOM. - node = svg.append("g") - .attr("class", "nodes") - .selectAll("circle") - .data(sample) - .enter().append("circle") - .attr("r", NODE_SIZE) - .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") - // Color code the data points by a property (for Poker Hands, - // it is a CLASS property). - .attr("fill", function (d) { - return color(d[COLOR_ATTRIBUTE]) - }) - .on("mouseover", function (d) { - div.transition() - .duration(200) - .style("opacity", .9); - div.html(formatTooltip(d)) - .style("left", (d3.event.pageX) + "px") - .style("top", (d3.event.pageY - (15 * props.length)) + "px") - .style("width", (6 * tooltipWidth) + "px") - .style("height", (14 * props.length) + "px"); - highlightOnHover(d[COLOR_ATTRIBUTE]); - }) - .on("mouseout", function (d) { - div.transition() - .duration(500) - .style("opacity", 0); - node.attr("opacity", 1); - }); - - if (selectedData) { - unSelectNodes(selectedData); - } - - hybridSimulation - .distance(distanceFunction); - - hybridSimulation - .on("sampleTick", tickedHybrid) - .on("fullTick", tickedHybrid) - .on("startFull", started) - .on("end", endedHybrid); - - - function tickedHybrid() { - if (rendering === true) { - node - .attr("cx", function (d) { - return d.x; - }) - .attr("cy", function (d) { - return d.y; - }); - } - } - - function started() { - d3.selectAll(".nodes").remove(); - // Add the nodes to DOM. - node = svg.append("g") - .attr("class", "nodes") - .selectAll("circle") - .data(nodes) - .enter().append("circle") - .attr("r", NODE_SIZE) - .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") - // Color code the data points by a property (for Poker Hands, - // it is a CLASS property). - .attr("fill", function (d) { - return color(d[COLOR_ATTRIBUTE]) - }) - .on("mouseover", function (d) { - div.transition() - .duration(200) - .style("opacity", .9); - div.html(formatTooltip(d)) - .style("left", (d3.event.pageX) + "px") - .style("top", (d3.event.pageY - (15 * props.length)) + "px") - .style("width", (6 * tooltipWidth) + "px") - .style("height", (14 * props.length) + "px"); - highlightOnHover(d[COLOR_ATTRIBUTE]); - }) - .on("mouseout", function (d) { - div.transition() - .duration(500) - .style("opacity", 0); - node.attr("opacity", 1); - }); - - if (selectedData) { - unSelectNodes(selectedData); - } - - } - - - function endedHybrid() { - if (rendering !== true) { - node - .attr("cx", function (d) { - return d.x; - }) - .attr("cy", function (d) { - return d.y; - }); - } - - // Performance time measurement - p2 = performance.now(); - console.log("Execution time: " + (p2 - p1)); - // Do not calculate stress for data sets bigger than 100 000. - // if (nodes.length <= 100000) { - // console.log("Stress: ", hybridSimulation.stress()); - // } - p1 = 0; - p2 = 0; - } -} - - -/** - * Initialize the t-SNE algorithm and start simulation. - */ -function starttSNE() { - springForce = false; - simulation.stop(); - p1 = performance.now(); - - simulation - .alphaDecay(1 - Math.pow(0.001, 1 / ITERATIONS)) - .force(forceName, d3.tSNE() - // Set the parameter for the algorithm (optional). - .perplexity(PERPLEXITY) - .learningRate(LEARNING_RATE) - // The distance function that will be used to calculate distances - // between nodes. - .distance(function (s, t) { - return distanceFunction(s, t, props, norm) * MULTIPLIER; - })); - // Restart the simulation. - console.log(simulation.force(forceName).perplexity(), simulation.force(forceName).learningRate()); - simulation.alpha(1).restart(); -} - -/** - * Initialize the Barnes-Hut algorithm and start simulation. - */ -function startBarnesHutSimulation() { - springForce = false; - simulation.stop(); - p1 = performance.now(); - - simulation - .alphaDecay(1 - Math.pow(0.001, 1 / ITERATIONS)) - .force(forceName, d3.forceBarnesHut() - // The distance function that will be used to calculate distances - // between nodes. - .distance(function (s, t) { - return distanceFunction(s, t, props, norm) * MULTIPLIER; - })); - // Restart the simulation. - simulation.alpha(1).restart(); -} - -/** - * Initialize the link force algorithm and start simulation. - */ -function startLinkSimulation() { - springForce = false; - simulation.stop(); - p1 = performance.now(); - - // Initialize link array. - nodes = simulation.nodes(); - for (i = 0; i < nodes.length; i++) { - for (j = 0; j < nodes.length; j++) { - if (i !== j) { - links.push({ - source: nodes[i], - target: nodes[j], - }); - } - } - } - - // Add the links to the simulation. - simulation.force(forceName, d3.forceLink().links(links)); - - simulation - .alphaDecay(1 - Math.pow(0.001, 1 / ITERATIONS)) - .force(forceName) - // The distance function that will be used to calculate distances - // between nodes. - .distance(function (n) { - return distanceFunction(n.source, n.target, props, norm) * MULTIPLIER; - }) - // Set the parameter for the algorithm (optional). - .strength(1); - // Restart the simulation. - simulation.alpha(1).restart(); -} - -/** - * Halt the execution. - */ -function stopSimulation() { - simulation.stop(); - if (typeof hybridSimulation !== 'undefined') { - hybridSimulation.stop(); - } -} - -/** - * Calculate the average values of the array. - * @param {array} array - * @return {number} the mean of the array. - */ -function getAverage(array) { - var total = 0; - for (var i = 0; i < array.length; i++) { - total += array[i]; - } - return total / array.length; -} - -/** - * Deselect the nodes to match the selection from other window. - * @param {*} data - */ -function unSelectNodes(data) { - - selectedData = data; - - if (fileName === data.name && nodes) { - node - .classed("notSelected", function (d) { - if (data.indices.indexOf(d.index) < 0) { - return true; - } - return false; - }); - } -} - -/** - * Highlight the neighbours for neighbour and sampling algorithm and show the corresponding MNIST images for each node. - * @param {*} indices - */ -function highlightNeighbours(index, indices) { - var selectedNodes = [nodes[index]]; - indices.forEach(function (i) { - selectedNodes.push(nodes[i]); - }); - - var ratio = NODE_SIZE / 10; - - svg.selectAll("image").remove(); - imgs.data(selectedNodes).enter() - .append("svg:image") - .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") - .attr("xlink:href", function (d) { - return "data/mnist/images/" + d.index + ".png"; - }) - .attr("x", function (d) { - return d.x + (ratio * 20); - }) - .attr("y", function (d) { - return d.y - (ratio * 20); - }) - .attr("width", ratio * 28) - .attr("height", ratio * 28); - - - node - .attr("r", function (d) { - if (indices.indexOf(d.index) >= 0) { - return NODE_SIZE * 2; - } - return NODE_SIZE; - }) - .attr("stroke-width", function (d) { - if (indices.indexOf(d.index) >= 0) { - return NODE_SIZE * 0.2 + "px"; - } - return "0px"; - }) - .attr("stroke", "white"); -} - -/** - * Highlight all the nodes with the same class on hover - * @param {*} highlighValue - */ -function highlightOnHover(highlighValue) { - node.attr("opacity", function (d) { - return (highlighValue === d[COLOR_ATTRIBUTE]) ? 1 : 0.3; - }); -} - -/** - * Color the nodes according to given attribute. - */ -function colorToAttribute() { - node.attr("fill", function (d) { - return color(d[COLOR_ATTRIBUTE]) - }); -} \ No newline at end of file diff --git a/examples/js/src/pivotFinder.js b/examples/js/src/pivotFinder.js deleted file mode 100644 index 6d7d6ea..0000000 --- a/examples/js/src/pivotFinder.js +++ /dev/null @@ -1,109 +0,0 @@ -function findPivots(dataSet, sampleSet, remainderSet) { - var distance = calculateDistancePoker; - // Initialize - - var numBuckets = Math.floor(Math.sqrt(sampleSet.length)), - numPivots = Math.floor(Math.sqrt(sampleSet.length)), - parents = [], - maxDists = [], - bucketWidths = [], - pivotsBuckets = []; - - var pivots = createRandomSample(dataSet, sampleSet.length, numPivots); - - for (var i = 0; i < numPivots; i++) { - pivotsBuckets[i] = []; - for (var j = 0; j < numBuckets; j++) { - pivotsBuckets[i][j] = []; - } - } - - // Pre-processing - var fullDists = [] - for (var i = 0; i < sampleSet.length; i++) { - fullDists[i] = []; - } - - for (var j = 0, maxDist = -1; j < numPivots; j++) { - var c1 = pivots[j]; - for (var i = 0; i < sampleSet.length; i++) { - var c2 = sampleSet[i]; - if (c1 !== c2) { - var dist = distance(c1, c2); - // console.log(dist, c1, c2); - if (dist > maxDist) { - maxDist = dist; - } - fullDists[i][j] = dist; - } else { - fullDists[i][j] = 0.0001; - } - } - maxDists.push(maxDist); - bucketWidths.push(maxDist / numBuckets); - } - - // console.log(fullDists); - - for (var j = 0; j < numPivots; j++) { - var bucketWidth = bucketWidths[j]; - for (var i = 0; i < sampleSet.length; i++) { - var tmp = pivotsBuckets[j][Math.floor((fullDists[i][j] - 0.0001) / bucketWidth)]; - // pivotsBuckets[j][Math.floor((fullDists[i][j] - 0.0001) / bucketWidth)].push(sampleSet[i]); - // console.log(tmp, i, j, bucketWidth, Math.floor((fullDists[i][j] - 0.0001) / bucketWidth)); - tmp.push(sampleSet[i]); - } - } - - // Find parents - for (var r = 0, bNum, minIndex; r < remainderSet.length; r++) { - var node = remainderSet[r]; - var clDist = Number.MAX_VALUE; - for (var p = 0; p < numPivots; p++) { - var comp = pivots[p]; - var bucketWidth = bucketWidths[p]; - if (node !== comp) { - var dist = distance(node, comp); - bNum = Math.floor((dist - 0.0001) / bucketWidth); - if (bNum >= numBuckets) { - bNum = numBuckets - 1; - } else if (bNum < 0) { - bNum = 0; - } - var bucketContents = pivotsBuckets[p][bNum]; - for (var w = 0; w < bucketContents.length; w++) { - var c1 = bucketContents[w]; - if (c1 != node) { - dist = distance(c1, node); - if (dist <= clDist) { - clDist = dist; - minIndex = bucketContents[w]; - } - } - } - } - } - parents.push(minIndex); - } - return parents; -} - -function createRandomSample(nodes, max, size) { - var randElements = []; - - for (var i = 0; i < size; ++i) { - // Stop when no new elements can be found. - if (randElements.size >= nodes.length) { - break; - } - var rand = Math.floor((Math.random() * max)); - // If the rand is already in random list or in exclude list - // ignore it and get a new value. - while (randElements.includes(rand)) { - rand = Math.floor((Math.random() * max)); - } - randElements.push(nodes[rand]); - } - - return randElements; -} diff --git a/examples/nist-images.html b/examples/nist-images.html deleted file mode 100644 index 5ebf8ee..0000000 --- a/examples/nist-images.html +++ /dev/null @@ -1,274 +0,0 @@ - - - - - -
-