use of au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase in project constellation by constellation-app.
the class TreeData method addNewNode.
public int addNewNode(final int position, final String name, final double flow, final double teleportWeight) {
final NodeBase node = nodeFactory.createNode(name, flow, teleportWeight);
node.setOriginalIndex(position);
root.addChild(node);
leafNodes.add(node);
return node.getOriginalIndex();
}
use of au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase in project constellation by constellation-app.
the class InfomapBase method processPartitionQueue.
private boolean processPartitionQueue(final PartitionQueue queue, final PartitionQueue nextLevelQueue, final boolean tryIndexing) {
final int numModules = queue.size();
final double[] indexCodelengths = new double[numModules];
final double[] moduleCodelengths = new double[numModules];
final double[] leafCodelengths = new double[numModules];
final PartitionQueue[] subQueues = new PartitionQueue[numModules];
for (int i = 0; i < numModules; i++) {
subQueues[i] = new PartitionQueue();
}
// This loop can be parallelised?
for (int moduleIndex = 0; moduleIndex < numModules; moduleIndex++) {
final NodeBase module = queue.get(moduleIndex);
// Delete former sub-structure if exists.
module.getSubStructure().setSubInfomap(null);
module.setCodelength(calcCodelengthFromFlowWithinOrExit(module));
// If only trivial substructure is to be found, no need to create infomap instance to find sub-module structures.
if (module.getChildDegree() <= 2) {
leafCodelengths[moduleIndex] = module.getCodelength();
continue;
}
final PartitionQueue subQueue = subQueues[moduleIndex];
subQueue.setLevel(queue.getLevel() + 1);
final InfomapBase subInfomap = getNewInfomapInstance(config, rg);
subInfomap.subLevel = subLevel + 1;
subInfomap.initSubNetwork(module, false);
subInfomap.partitionAndQueueNextLevel(subQueue, tryIndexing);
// If non-trivial substructure is found which improves the codelength, store it on the module.
final boolean nonTrivialSubstructure = subInfomap.getNumTopModules() > 1 && subInfomap.getNumTopModules() < subInfomap.getNumLeafNodes();
final boolean improvement = nonTrivialSubstructure && (subInfomap.hierarchicalCodelength < module.getCodelength() - config.getMinimumCodelengthImprovement());
if (improvement) {
indexCodelengths[moduleIndex] = subInfomap.indexCodelength;
moduleCodelengths[moduleIndex] = subInfomap.moduleCodelength;
module.getSubStructure().setSubInfomap(subInfomap);
} else {
leafCodelengths[moduleIndex] = module.getCodelength();
module.getSubStructure().setExploredWithoutImprovement(true);
subQueue.setSkip(true);
// Else use the codelength from the flat substructure
}
}
double sumLeafCodelength = 0.0;
double sumIndexCodelength = 0.0;
double sumModuleCodelengths = 0.0;
int nextLevelSize = 0;
for (int moduleIndex = 0; moduleIndex < numModules; moduleIndex++) {
nextLevelSize += subQueues[moduleIndex].isSkip() ? 0 : subQueues[moduleIndex].size();
sumLeafCodelength += leafCodelengths[moduleIndex];
sumIndexCodelength += indexCodelengths[moduleIndex];
sumModuleCodelengths += moduleCodelengths[moduleIndex];
}
queue.setIndexCodelength(sumIndexCodelength);
queue.setLeafCodelength(sumLeafCodelength);
queue.setModuleCodelength(sumModuleCodelengths);
// Collect the sub-queues and build the next-level queue.
nextLevelQueue.setLevel(queue.getLevel() + 1);
nextLevelQueue.resize(nextLevelSize);
int nextLevelIndex = 0;
for (int moduleIndex = 0; moduleIndex < numModules; moduleIndex++) {
final PartitionQueue subQueue = subQueues[moduleIndex];
if (!subQueue.isSkip()) {
for (int subIndex = 0; subIndex < subQueue.size(); ++subIndex) {
nextLevelQueue.set(nextLevelIndex++, subQueue.get(subIndex));
}
nextLevelQueue.setFlow(nextLevelQueue.getFlow() + subQueue.getFlow());
nextLevelQueue.setNonTrivialFlow(nextLevelQueue.getNonTrivialFlow() + subQueue.getNonTrivialFlow());
nextLevelQueue.setNumNonTrivialModules(nextLevelQueue.getNumNonTrivialModules() + subQueue.getNumNonTrivialModules());
}
}
return nextLevelSize > 0;
}
use of au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase in project constellation by constellation-app.
the class InfomapBase method partitionEachModule.
/**
* For each module, create a new infomap instance and clone the interior
* structure of the module as the new network to partition. Collect the
* results by populating the index member of each leaf node with the
* sub-module structure found by partitioning each module.
*/
private void partitionEachModule(final int recursiveCount, final boolean fast) {
int moduleIndexOffset = 0;
for (final NodeBase module : getRoot().getChildren()) {
// If only one child in the module, no need to create infomap instance to find sub-module structures.
if (module.getChildDegree() == 1) {
for (final NodeBase node : module.getChildren()) {
node.setIndex(moduleIndexOffset);
}
moduleIndexOffset += 1;
continue;
}
if (DEBUG) {
final String log = String.format(">>>>>>>>>>>>>>>>>> RUN SUB_INFOMAP on node n%d with childDegree: %d >>>>>>>>>>>>\n", module.getId(), module.getChildDegree());
LOGGER.log(Level.INFO, log);
}
final InfomapBase subInfomap = getNewInfomapInstance(config, rg);
// To not happen to get back the same network with the same seed.
subInfomap.reseed(NodeBase.uid());
subInfomap.subLevel = subLevel + 1;
subInfomap.initSubNetwork(module, false);
subInfomap.partition(recursiveCount, fast);
if (DEBUG) {
LOGGER.log(Level.INFO, "<<<<<<<<<<<<<<<<<<< BACK FROM SUB_INFOMAP!!!! <<<<<<<<<<<<<<<<<<<%n");
final String log = String.format("Node n%d with %d leaf-nodes gave %d sub-clusters%n", module.getId(), subInfomap.treeData.getNumLeafNodes(), subInfomap.treeData.getRoot().getChildDegree());
LOGGER.log(Level.INFO, log);
}
final Iterator<NodeBase> originalLeafNodeIt = module.getChildren().iterator();
for (final NodeBase node : subInfomap.treeData.getLeaves()) {
originalLeafNodeIt.next().setIndex(node.getParent().getIndex() + moduleIndexOffset);
}
moduleIndexOffset += subInfomap.treeData.getRoot().getChildDegree();
}
}
use of au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase in project constellation by constellation-app.
the class InfomapBase method partition.
private void partition(final int recursiveCount, final boolean fast, final boolean forceConsolidation) {
if (DEBUG) {
final String log = String.format("%s.partition(%d,%s,%s)%n", getClass().getSimpleName(), recursiveCount, fast, forceConsolidation);
LOGGER.log(Level.INFO, log);
}
final boolean verbose = (subLevel == 0 && config.getVerbosity() != 0) || (isSuperLevelOnTopLevel() && config.getVerbosity() == 2);
if (treeData.getFirstLeaf().getParent() != getRoot()) {
final String log = String.format("Already partitioned with codelength %d in %d modules.%n", codelength, getNumTopModules());
LOGGER.log(Level.INFO, log);
return;
}
setActiveNetworkFromChildrenOfRoot();
initConstantInfomapTerms();
initModuleOptimization();
if (verbose) {
if (config.getVerbosity() == 0) {
LOGGER.log(Level.INFO, "Two-level compression: ");
} else {
LOGGER.log(Level.INFO, "Trying to find modular structure...");
final String log = String.format("Initiated to codelength %f + %f = %f in %d modules.%n", indexCodelength, moduleCodelength, codelength, getNumTopModules());
LOGGER.log(Level.INFO, log);
}
}
final double initialCodelength = codelength;
mergeAndConsolidateRepeatedly(forceConsolidation, fast);
if (DEBUG) {
final String log = String.format("[codelength, initialCodelength = %f,%f]%n", codelength, initialCodelength);
LOGGER.log(Level.INFO, log);
}
double oldCodelength = oneLevelCodelength;
double compression = (oldCodelength - codelength) / oldCodelength;
if (verbose && config.getVerbosity() == 0) {
final String log = String.format(FOUR_FORMAT, compression * 100);
LOGGER.log(Level.INFO, log);
}
if (!fast && config.getTuneIterationLimit() != 1 && getNumTopModules() != getNumLeafNodes()) {
int tuneIterationCount = 1;
int coarseTuneLevel = config.getCoarseTuneLevel() - 1;
boolean doFineTune = true;
oldCodelength = codelength;
while (getNumTopModules() > 1) {
if (doFineTune) {
fineTune();
if (codelength > oldCodelength - initialCodelength * config.getMinimumRelativeTuneIterationImprovement() || codelength > oldCodelength - config.getMinimumCodelengthImprovement()) {
break;
}
compression = (oldCodelength - codelength) / oldCodelength;
if (verbose && config.getVerbosity() == 0) {
final String log = String.format(FOUR_FORMAT, compression * 100);
LOGGER.log(Level.INFO, log);
}
oldCodelength = codelength;
} else {
coarseTune(config.isAlternateCoarseTuneLevel() ? (++coarseTuneLevel % config.getCoarseTuneLevel()) : config.getCoarseTuneLevel() - 1);
if (codelength > oldCodelength - initialCodelength * config.getMinimumRelativeTuneIterationImprovement() || codelength > oldCodelength - config.getMinimumCodelengthImprovement()) {
break;
}
compression = (oldCodelength - codelength) / oldCodelength;
if (verbose && config.getVerbosity() == 0) {
final String log = String.format(FOUR_FORMAT, compression * 100);
LOGGER.log(Level.INFO, log);
}
oldCodelength = codelength;
}
++tuneIterationCount;
if (config.getTuneIterationLimit() == tuneIterationCount) {
break;
}
doFineTune = !doFineTune;
}
}
if (verbose) {
if (config.getVerbosity() == 0) {
final String fmt = String.format("%s.%df", "%", config.getVerboseNumberPrecision());
final String cl = String.format(fmt, codelength);
final String log = String.format("to %d modules with codelength %s%n", getNumTopModules(), cl);
LOGGER.log(Level.INFO, log);
} else {
final String log = String.format("Two-level codelength: %f + %f = %f%n", indexCodelength, moduleCodelength, codelength);
LOGGER.log(Level.INFO, log);
}
}
if (!fast && recursiveCount > 0 && getNumTopModules() != 1 && getNumTopModules() != getNumLeafNodes()) {
partitionEachModule(recursiveCount - 1);
// Prepare leaf network to move into the sub-module structure given from partitioning each module.
setActiveNetworkFromLeafs();
int i = 0;
for (final NodeBase leaf : treeData.getLeaves()) {
moveTo.set(i, leaf.getIndex());
assert moveTo.get(i) < activeNetwork.size();
i++;
}
initModuleOptimization();
moveNodesToPredefinedModules();
// Consolidate the sub-modules and store the current module structure in the sub-modules before replacing it.
consolidateModules(true, true);
// Set module indices from a zero-based contiguous set.
int packedModuleIndex = 0;
for (final NodeBase module : getRoot().getChildren()) {
module.setOriginalIndex(packedModuleIndex++);
module.setIndex(module.getOriginalIndex());
}
}
}
use of au.gov.asd.tac.constellation.plugins.algorithms.clustering.infomap.NodeBase in project constellation by constellation-app.
the class InfomapBase method setActiveNetworkFromChildrenOfRoot.
private void setActiveNetworkFromChildrenOfRoot() {
if (DEBUG) {
final String log = String.format("%s.setActiveNetworkFromChildrenOfRoot() with child degree %d...\n", getClass().getSimpleName(), getRoot().getChildDegree());
LOGGER.log(Level.INFO, log);
}
final int numNodes = getRoot().getChildDegree();
activeNetwork = nonLeafActiveNetwork;
Resizer.resize(activeNetwork, numNodes, null);
assert nonLeafActiveNetwork.size() == numNodes;
int i = 0;
for (final NodeBase child : getRoot().getChildren()) {
activeNetwork.set(i, child);
i++;
}
}
Aggregations