1 Commits

Author SHA1 Message Date
Pitchaya Boonsarngsuk
dd32d7b38c Add pivot hitrate console logs 2018-02-09 11:32:51 +00:00
8 changed files with 56 additions and 42 deletions

View File

@@ -143,7 +143,7 @@ If *threshold* is specified, sets a threshold and returns this force. When the a
If *handler* is specified, sets a handler function which will be called at the end of each iteration if the average velocity changes of the system goes below the [threshold](#neighbourSampling_stableVelocity), and returns this force. To remove the handler, change it to null. If *threshold* is not specified, returns the current value, which defaults to null. If *handler* is specified, sets a handler function which will be called at the end of each iteration if the average velocity changes of the system goes below the [threshold](#neighbourSampling_stableVelocity), and returns this force. To remove the handler, change it to null. If *threshold* is not specified, returns the current value, which defaults to null.
### Hybrid Layout Simulation ### Hybrid Layout Simulation - TO WRITE
The hybrid layout algorithm reduces the computation power usage even further by performing neighbour and sampling algorithm on only $\sqrt{n}$ sample subset of the data, and interpolating the rest in. Neighbour and sampling algorithm may also be ran again over the full dataset after the interpolation to refine the layout. This algorithm is only recommended for visualizing larger dataset. The hybrid layout algorithm reduces the computation power usage even further by performing neighbour and sampling algorithm on only $\sqrt{n}$ sample subset of the data, and interpolating the rest in. Neighbour and sampling algorithm may also be ran again over the full dataset after the interpolation to refine the layout. This algorithm is only recommended for visualizing larger dataset.
@@ -151,9 +151,9 @@ The hybrid layout algorithm reduces the computation power usage even further by
Creates a new hybrid layout simulation default parameters. The simulation will takeover control of [d3.forceSimulation](https://github.com/d3/d3-force#forceSimulation) provided (*simulation* parameter). *forceSample* and *forceFull* are pre-configured [d3.forceNeighbourSampling](#forceNeighbourSampling) forces to be run over the $\sqrt{n}$ samples and full dataset respectively. While unsupported, other D3 forces such as [d3.forceLinkFullyConnected](forceLinkFullyConnected) may also work. Creates a new hybrid layout simulation default parameters. The simulation will takeover control of [d3.forceSimulation](https://github.com/d3/d3-force#forceSimulation) provided (*simulation* parameter). *forceSample* and *forceFull* are pre-configured [d3.forceNeighbourSampling](#forceNeighbourSampling) forces to be run over the $\sqrt{n}$ samples and full dataset respectively. While unsupported, other D3 forces such as [d3.forceLinkFullyConnected](forceLinkFullyConnected) may also work.
*forceSample* and *forceFull* may have [stableVelocity](neighbourSampling_stableVelocity) configured to end the simulation and begin the interpolation phase early, but any [handler](neighbourSampling_onStableVelo) functions will be replaced be hybridSimulation's own internal function. *forceSample* may have [stableVelocity](neighbourSampling_stableVelocity) configured to end the simulation and begin the interpolation phase early, but any [handler](neighbourSampling_onStableVelo) functions will be replaced be hybridSimulation's own internal function.
*forceFull* may also be absent, null, or undefined to skip the final refinement. *forceSample* may be absent, null, or undefined to skip the final refinement.
*simulation* should have already been loaded with nodes. If there are any changes in the list of nodes, the simulation have to be re-set using the [.simulation](#hybrid_simulation) method. *simulation* should have already been loaded with nodes. If there are any changes in the list of nodes, the simulation have to be re-set using the [.simulation](#hybrid_simulation) method.
@@ -175,7 +175,7 @@ If *force* is specified, sets the neighbour and sampling force to run on the $\s
<a name="hybrid_forceFull" href="#hybrid_forceFull">#</a> *hybrid*.**forceFull**([*force*]) <a name="hybrid_forceFull" href="#hybrid_forceFull">#</a> *hybrid*.**forceFull**([*force*])
If *force* is specified, sets the neighbour and sampling force to run on the whole dataset after interpolation and returns this layout simulation. The same limitation applies: [stableVelocity](neighbourSampling_stableVelocity) may be configured to end the simulation and begin the interpolation phase early, but any [handler](neighbourSampling_onStableVelo) functions will be replaced be hybridSimulation's own internal function. If set to null, the process will be skipped. If *force* is not specified, returns the current force object. If *force* is specified, sets the neighbour and sampling force to run on the whole dataset after interpolation and returns this layout simulation. If set to null, the process will be skipped. If *force* is not specified, returns the current force object.
<a name="hybrid_sampleIterations" href="#hybrid_sampleIterations">#</a> *hybrid*.**sampleIterations**([*iterations*]) <a name="hybrid_sampleIterations" href="#hybrid_sampleIterations">#</a> *hybrid*.**sampleIterations**([*iterations*])

View File

@@ -200,11 +200,7 @@ function ticked() {
.attr("cy", function (d) { .attr("cy", function (d) {
return d.y*MULTIPLIER; return d.y*MULTIPLIER;
}); });
}/* }
if(alreadyRanIterations%10 != 1) stresses.push("");
else stresses.push(d3.calculateStress(nodes, function (n, m) {
return distanceFunction(n, m, props, norm);
}));*/
// Emit the distribution data to allow the drawing of the bar graph // Emit the distribution data to allow the drawing of the bar graph
if (springForce) { if (springForce) {
intercom.emit("passedData", simulation.force(forceName).distributionData()); intercom.emit("passedData", simulation.force(forceName).distributionData());
@@ -218,7 +214,7 @@ function ended() {
simulation.stop(); simulation.stop();
simulation.force(forceName, null); simulation.force(forceName, null);
console.log("ended"); console.log("ended");
//if (rendering !== true) { // Never drawn anything before? Now it's time. if (rendering !== true) { // Never drawn anything before? Now it's time.
node node
.attr("cx", function (d) { .attr("cx", function (d) {
return d.x*MULTIPLIER; return d.x*MULTIPLIER;
@@ -226,7 +222,7 @@ function ended() {
.attr("cy", function (d) { .attr("cy", function (d) {
return d.y*MULTIPLIER; return d.y*MULTIPLIER;
}); });
//} }
if (p1 !== 0) { if (p1 !== 0) {
// Performance time measurement // Performance time measurement
@@ -240,9 +236,6 @@ function ended() {
p1 = 0; p1 = 0;
p2 = 0; p2 = 0;
} }
console.log("Post stress", d3.calculateStress(nodes, function (n, m) {
return distanceFunction(n, m, props, norm);
}));
} }
function brushEnded() { function brushEnded() {

View File

@@ -16,13 +16,12 @@ function startHybridSimulation() {
let forceSample = d3.forceNeighbourSampling() let forceSample = d3.forceNeighbourSampling()
.neighbourSize(NEIGHBOUR_SIZE) .neighbourSize(NEIGHBOUR_SIZE)
.sampleSize(SAMPLE_SIZE) .sampleSize(SAMPLE_SIZE)
.stableVelocity(0.43) .stableVelocity(0)
.distance(distance) .distance(distance)
let forceFull = d3.forceNeighbourSampling() let forceFull = d3.forceNeighbourSampling()
.neighbourSize(FULL_NEIGHBOUR_SIZE) .neighbourSize(FULL_NEIGHBOUR_SIZE)
.sampleSize(FULL_SAMPLE_SIZE) .sampleSize(FULL_SAMPLE_SIZE)
.stableVelocity(0.6)
.distance(distance) .distance(distance)
let hybridSimulation = d3.hybridSimulation(simulation, forceSample, forceFull) let hybridSimulation = d3.hybridSimulation(simulation, forceSample, forceFull)

View File

@@ -15,7 +15,7 @@ function startLinkSimulation() {
.distance(function (n, m) { .distance(function (n, m) {
return distanceFunction(n, m, props, norm); return distanceFunction(n, m, props, norm);
}) })
.stableVelocity(0) //TODO .stableVelocity(0.000001) //TODO
.onStableVelo(ended); .onStableVelo(ended);
} }
else { else {

View File

@@ -40,8 +40,7 @@ export default function (sim, forceS, forceF) {
initAlready = false, initAlready = false,
nodes, nodes,
alreadyRanIterations, alreadyRanIterations,
hybrid, hybrid;
p0 = performance.now(), p1, p2, p3;
if(simulation != undefined) initSimulation(); if(simulation != undefined) initSimulation();
if(forceS != undefined || forceF != undefined) initForces(); if(forceS != undefined || forceF != undefined) initForces();
@@ -64,10 +63,6 @@ export default function (sim, forceS, forceF) {
forceSample.onStableVelo(sampleEnded); forceSample.onStableVelo(sampleEnded);
} }
if (forceFull.onStableVelo) {
forceFull.onStableVelo(fullEnded);
}
// Set default value for interpDistanceFn if not been specified yet // Set default value for interpDistanceFn if not been specified yet
if(interpDistanceFn === undefined) { if(interpDistanceFn === undefined) {
if(forceFull.distance == 'function') if(forceFull.distance == 'function')
@@ -101,25 +96,14 @@ export default function (sim, forceS, forceF) {
function fullTick() { function fullTick() {
event.call("fullTick"); event.call("fullTick");
if(++alreadyRanIterations >= FULL_ITERATIONS){ if(++alreadyRanIterations >= FULL_ITERATIONS){
fullEnded(); simulation.stop();
initAlready = false;
simulation.force("Full force", null);
event.call("end");
} }
} }
function fullEnded() {
p3 = performance.now();
simulation.stop();
initAlready = false;
simulation.force("Full force", null);
console.log("Phase 1 takes", p1-p0);
console.log("Phase 2 takes", p2-p1);
console.log("Phase 3 takes", p3-p2);
console.log("Total", p3-p0);
console.log("Phase 3 iterations", alreadyRanIterations);
event.call("end");
}
function sampleEnded() { function sampleEnded() {
p1 = performance.now();
simulation.stop(); simulation.stop();
simulation.force("Sample force", null); simulation.force("Sample force", null);
// Reset velocity of all nodes // Reset velocity of all nodes
@@ -134,7 +118,6 @@ export default function (sim, forceS, forceF) {
} else { } else {
interpBruteForce(sample, remainder, interpDistanceFn, INTERP_FINE_ITS); interpBruteForce(sample, remainder, interpDistanceFn, INTERP_FINE_ITS);
} }
p2 = performance.now();
event.call("fullTick"); event.call("fullTick");
alreadyRanIterations = 0; alreadyRanIterations = 0;

View File

@@ -30,6 +30,7 @@ export default function(sampleSet, remainderSet, numPivots, distanceFn, endingIt
let sets = takeSampleFrom(sampleSet, numPivots); let sets = takeSampleFrom(sampleSet, numPivots);
let pivots = sets.sample; let pivots = sets.sample;
let nonPivotSamples = sets.remainder; let nonPivotSamples = sets.remainder;
let correct = 0, wrong = 0, percentsOff = [];
let pivotsBuckets = []; // [ For each Pivot:[For each bucket:[each point in bucket]] ] let pivotsBuckets = []; // [ For each Pivot:[For each bucket:[each point in bucket]] ]
for (let i = 0; i < numPivots; i++) { for (let i = 0; i < numPivots; i++) {
@@ -130,6 +131,45 @@ export default function(sampleSet, remainderSet, numPivots, distanceFn, endingIt
if (sampleSubsetDistanceCache[k] === undefined) if (sampleSubsetDistanceCache[k] === undefined)
sampleSubsetDistanceCache[k] = distanceFn(node, sampleSubset[k]); sampleSubsetDistanceCache[k] = distanceFn(node, sampleSubset[k]);
} }
let nearestSample, nearestMinDist, sample, dist;
for (let j = sampleSet.length-1; j>=0; j--) {
sample = sampleSet[j];
dist = distanceFn(node, sample);
if (nearestSample === undefined || dist < nearestMinDist) {
nearestMinDist = dist;
nearestSample = sample;
}
}
if(minDist-nearestMinDist == 0) correct++;
else {
wrong++;
if(nearestMinDist!=0)percentsOff.push(minDist/nearestMinDist)
}
placeNearToNearestNeighbour(node, nearSample, minDist, sampleSubset, sampleSubsetDistanceCache, endingIts); placeNearToNearestNeighbour(node, nearSample, minDist, sampleSubset, sampleSubsetDistanceCache, endingIts);
} }
console.log("Correct", correct);
console.log("Wrong", wrong);
console.log("Correct percent", 100*correct/(correct+wrong));
StandardDeviation(percentsOff)
}
function StandardDeviation(numbersArr) {
//--CALCULATE AVAREGE--
var total = 0;
for(var key in numbersArr)
total += numbersArr[key];
var meanVal = total / numbersArr.length;
console.log("Average percent off", meanVal);
//--CALCULATE AVAREGE--
//--CALCULATE STANDARD DEVIATION--
var SDprep = 0;
for(var key in numbersArr)
SDprep += Math.pow((parseFloat(numbersArr[key]) - meanVal),2);
var SDresult = Math.sqrt(SDprep/numbersArr.length);
//--CALCULATE STANDARD DEVIATION--
console.log("SD percent off", SDresult);
} }

View File

@@ -54,7 +54,7 @@ export default function() {
node = nodes[i]; node = nodes[i];
velocityDiff += Math.abs(Math.hypot(node.vx-node.oldvx, node.vy-node.oldvy)); velocityDiff += Math.abs(Math.hypot(node.vx-node.oldvx, node.vy-node.oldvy));
} }
velocityDiff /= n; velocityDiff /= n*(n-1);
latestVelocityDiff = velocityDiff; latestVelocityDiff = velocityDiff;
if(velocityDiff<stableVelocity){ if(velocityDiff<stableVelocity){

View File

@@ -60,13 +60,12 @@ export default function () {
node = nodes[i]; node = nodes[i];
velocityDiff += Math.abs(Math.hypot(node.vx-node.oldvx, node.vy-node.oldvy)); velocityDiff += Math.abs(Math.hypot(node.vx-node.oldvx, node.vy-node.oldvy));
} }
velocityDiff /= n; velocityDiff /= n*(neighbourSize+sampleSize);
latestVelocityDiff = velocityDiff; latestVelocityDiff = velocityDiff;
if(velocityDiff<stableVelocity){ if(velocityDiff<stableVelocity){
stableVeloHandler(); stableVeloHandler();
} }
else console.log(velocityDiff);
} }
} }