7 Commits

Author SHA1 Message Date
Pitchaya Boonsarngsuk
6182a5fc26 Change logging 2018-02-13 18:42:29 +00:00
Pitchaya Boonsarngsuk
adf8126d86 Add perf matrix, esp for hybrid 2018-02-12 08:53:54 +00:00
Pitchaya Boonsarngsuk
0d148b555f Merge remote-tracking branch 'origin/master' into withConsoleLog 2018-02-12 08:27:41 +00:00
Pitchaya Boonsarngsuk
5ee568b1cb Add extra end condition for hybrid phase 3 2018-02-12 08:27:09 +00:00
Pitchaya Boonsarngsuk
054ff7312e Merge remote-tracking branch 'origin/master' into withConsoleLog 2018-02-12 08:07:05 +00:00
Pitchaya Boonsarngsuk
6813be06df Velo changes scale per node instead 2018-02-12 08:06:53 +00:00
Pitchaya Boonsarngsuk
b88d3c9bfa Remove from "TO WRITE" readme 2018-02-10 16:27:58 +00:00
8 changed files with 42 additions and 56 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 - TO WRITE ### Hybrid Layout Simulation
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* 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* 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 be absent, null, or undefined to skip the final refinement. *forceFull* may also 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. 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. 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.
<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,7 +200,11 @@ 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());
@@ -214,7 +218,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;
@@ -222,7 +226,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
@@ -236,6 +240,9 @@ 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,12 +16,13 @@ function startHybridSimulation() {
let forceSample = d3.forceNeighbourSampling() let forceSample = d3.forceNeighbourSampling()
.neighbourSize(NEIGHBOUR_SIZE) .neighbourSize(NEIGHBOUR_SIZE)
.sampleSize(SAMPLE_SIZE) .sampleSize(SAMPLE_SIZE)
.stableVelocity(0) .stableVelocity(0.43)
.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.000001) //TODO .stableVelocity(0) //TODO
.onStableVelo(ended); .onStableVelo(ended);
} }
else { else {

View File

@@ -40,7 +40,8 @@ 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();
@@ -63,6 +64,10 @@ 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')
@@ -96,14 +101,25 @@ export default function (sim, forceS, forceF) {
function fullTick() { function fullTick() {
event.call("fullTick"); event.call("fullTick");
if(++alreadyRanIterations >= FULL_ITERATIONS){ if(++alreadyRanIterations >= FULL_ITERATIONS){
simulation.stop(); fullEnded();
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
@@ -118,6 +134,7 @@ 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,7 +30,6 @@ 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++) {
@@ -131,45 +130,6 @@ 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*(n-1); velocityDiff /= n;
latestVelocityDiff = velocityDiff; latestVelocityDiff = velocityDiff;
if(velocityDiff<stableVelocity){ if(velocityDiff<stableVelocity){

View File

@@ -60,12 +60,13 @@ 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*(neighbourSize+sampleSize); velocityDiff /= n;
latestVelocityDiff = velocityDiff; latestVelocityDiff = velocityDiff;
if(velocityDiff<stableVelocity){ if(velocityDiff<stableVelocity){
stableVeloHandler(); stableVeloHandler();
} }
else console.log(velocityDiff);
} }
} }