private Map<Triple<DendrogramNode, RowKey, RowKey>, Number> visit( final DendrogramNode root, final Map<Triple<DendrogramNode, RowKey, RowKey>, Number> m, final Map<RowKey, DistanceVectorDataValue> d, final int allLeaves, final ExecutionContext exec) throws CanceledExecutionException { if (root.isLeaf()) { final RowKey key = RowKeyHelper.getKey(root); return Collections.singletonMap(Triple.apply(root, key, key), (Number) Double.valueOf(0)); } final DendrogramNode w = root.getFirstSubnode(); final Map<Triple<DendrogramNode, RowKey, RowKey>, Number> leftM = visit(w, m, d, allLeaves, exec); final DendrogramNode x = root.getSecondSubnode(); final Map<Triple<DendrogramNode, RowKey, RowKey>, Number> rightM = visit(x, m, d, allLeaves, exec); final Map<Triple<DendrogramNode, RowKey, RowKey>, Number> ret = new HashMap<Triple<DendrogramNode, RowKey, RowKey>, Number>(leftM); ret.putAll(rightM); final Set<RowKey> leftKeys = computeLeaves(w); final Set<RowKey> rightKeys = computeLeaves(x); computeM(root, d, w, x, rightM, ret, leftKeys, rightKeys); exec.checkCanceled(); computeM(root, d, x, w, leftM, ret, rightKeys, leftKeys); exec.setProgress(((double) leftKeys.size() + rightKeys.size()) / allLeaves); return ret; }
private void computeLeaves(final DendrogramNode root, final Set<RowKey> ret) { if (root.isLeaf()) { ret.add(RowKeyHelper.getKey(root)); } else { computeLeaves(root.getFirstSubnode(), ret); computeLeaves(root.getSecondSubnode(), ret); } }
/** * Make a tree (with root: {@code root}) to {@link DistanceVectorDataValue} s. * * @param root A {@link DendrogramNode} tree's root element. * @param ret The result list. * @param d The distance matrix. */ public static void flatten( final DendrogramNode root, final List<DistanceVectorDataValue> ret, final Map<RowKey, DistanceVectorDataValue> d) { if (root.isLeaf()) { ret.add(d.get(RowKeyHelper.getKey(root))); return; } flatten(root.getFirstSubnode(), ret, d); flatten(root.getSecondSubnode(), ret, d); }
private static Triple<ClusterViewNode, RowKey, RowKey> buildNewTree( final Map<DendrogramNode, Map<Pair<RowKey, RowKey>, Number>> m, final DendrogramNode root, final Map<RowKey, Pair<DataRow, Integer>> rows, ExecutionContext exec) throws CanceledExecutionException { if (root.isLeaf()) { final Pair<DataRow, Integer> leafRow = rows.get(RowKeyHelper.getKey(root)); return Triple.apply( new ClusterViewNode(leafRow.getFirst().getKey()), leafRow.getFirst().getKey(), leafRow.getFirst().getKey()); } final Triple<ClusterViewNode, RowKey, RowKey> firstTree = buildNewTree(m, root.getFirstSubnode(), rows, exec); exec.checkCanceled(); final Triple<ClusterViewNode, RowKey, RowKey> secondTree = buildNewTree(m, root.getSecondSubnode(), rows, exec); final Map<Pair<RowKey, RowKey>, Number> map = m.get(root); Pair<RowKey, RowKey> pairNoChange = Pair.create(firstTree.getO3(), secondTree.getO2()); if (!map.containsKey(pairNoChange)) { pairNoChange = flip(pairNoChange); } Pair<RowKey, RowKey> pairChange = Pair.create(secondTree.getO3(), firstTree.getO2()); if (!map.containsKey(pairChange)) { pairChange = flip(pairChange); } assert map.containsKey(pairNoChange); assert map.containsKey(pairChange); final double noChangeValue = map.get(pairNoChange).doubleValue(); final double changeValue = map.get(pairChange).doubleValue(); if (noChangeValue > changeValue) { return Triple.apply( new ClusterViewNode(firstTree.getO1(), secondTree.getO1(), root.getDist()), firstTree.getO2(), secondTree.getO3()); } return Triple.apply( new ClusterViewNode(secondTree.getO1(), firstTree.getO1(), root.getDist()), secondTree.getO2(), firstTree.getO3()); }