Commit 3e0ceac5 authored by Dennis Hendriks's avatar Dennis Hendriks
Browse files

#344 DSM/bitset related Java improvements addressing review comments.

parent 62713fce
...@@ -23,7 +23,7 @@ public class DsmBusDetectionAlgorithmOption extends EnumOption<BusDetectionAlgor ...@@ -23,7 +23,7 @@ public class DsmBusDetectionAlgorithmOption extends EnumOption<BusDetectionAlgor
private static final String NAME = "Bus detection algorithm"; private static final String NAME = "Bus detection algorithm";
/** Description of the option. */ /** Description of the option. */
private static final String DESCRIPTION = "Which bus detection algorithm to use. Use 'no-bus' to skip bus detection, 'fix-point' for using the fix-point algorithm, and 'top-k' for selecting the K top-nodes. [DEFAULT=no-bus]."; private static final String DESCRIPTION = "Which bus detection algorithm to use. Use 'no-bus' to skip bus detection, 'fix-point' for using the fixed-point algorithm, and 'top-k' for selecting the K top-nodes. [DEFAULT=no-bus].";
/** Short option name. */ /** Short option name. */
private static final Character CMD_SHORT = null; private static final Character CMD_SHORT = null;
...@@ -54,7 +54,7 @@ public class DsmBusDetectionAlgorithmOption extends EnumOption<BusDetectionAlgor ...@@ -54,7 +54,7 @@ public class DsmBusDetectionAlgorithmOption extends EnumOption<BusDetectionAlgor
case NO_BUS: case NO_BUS:
return "No bus"; return "No bus";
case FIX_POINT: case FIX_POINT:
return "Fix point"; return "Fixed point";
case TOP_K: case TOP_K:
return "Top k nodes"; return "Top k nodes";
} }
......
...@@ -26,7 +26,14 @@ import org.apache.commons.math3.linear.RealMatrix; ...@@ -26,7 +26,14 @@ import org.apache.commons.math3.linear.RealMatrix;
import org.eclipse.escet.common.java.Assert; import org.eclipse.escet.common.java.Assert;
import org.eclipse.escet.common.java.Pair; import org.eclipse.escet.common.java.Pair;
/** Functions for computing buses. */ /**
* Functions for computing buses.
*
* <p>
* PhD thesis, referred to as [Wilschut 2018]: Wilschut T. System specification and design structuring methods for a
* lock product platform. Eindhoven: Technische Universiteit Eindhoven, 2018. 178 p.
* </p>
*/
public class BusComputing { public class BusComputing {
/** Constructor of the static {@link BusComputing} class. */ /** Constructor of the static {@link BusComputing} class. */
private BusComputing() { private BusComputing() {
...@@ -34,7 +41,7 @@ public class BusComputing { ...@@ -34,7 +41,7 @@ public class BusComputing {
} }
/** /**
* Compute which nodes of the matrix should be considered a bus node using the top-k method. * Compute which nodes of the matrix should be considered a bus node using the top-k algorithm.
* *
* <p> * <p>
* Implements the bus-detection algorithm where the top gamma nodes are selected with the highest connection degree. * Implements the bus-detection algorithm where the top gamma nodes are selected with the highest connection degree.
...@@ -52,7 +59,7 @@ public class BusComputing { ...@@ -52,7 +59,7 @@ public class BusComputing {
} }
/** /**
* Compute which nodes of the matrix should be considered a bus node using the top-k method. * Compute which nodes of the matrix should be considered a bus node using the top-k algorithm.
* *
* <p> * <p>
* Implements the bus-detection algorithm where the top gamma nodes are selected with the highest connection degree. * Implements the bus-detection algorithm where the top gamma nodes are selected with the highest connection degree.
...@@ -71,7 +78,7 @@ public class BusComputing { ...@@ -71,7 +78,7 @@ public class BusComputing {
} }
/** /**
* Compute which nodes of the matrix should be considered a bus node using the top-k method. * Compute which nodes of the matrix should be considered a bus node using the top-k algorithm.
* *
* <p> * <p>
* Implements the bus-detection algorithm where the top gamma nodes are selected with the highest connection degree. * Implements the bus-detection algorithm where the top gamma nodes are selected with the highest connection degree.
...@@ -89,7 +96,7 @@ public class BusComputing { ...@@ -89,7 +96,7 @@ public class BusComputing {
} }
/** /**
* Compute which nodes of the matrix should be considered a bus node using the top-k method. * Compute which nodes of the matrix should be considered a bus node using the top-k algorithm.
* *
* <p> * <p>
* Implements the bus-detection algorithm where the top gamma nodes are selected with the highest connection degree. * Implements the bus-detection algorithm where the top gamma nodes are selected with the highest connection degree.
...@@ -108,7 +115,7 @@ public class BusComputing { ...@@ -108,7 +115,7 @@ public class BusComputing {
} }
/** /**
* Compute which nodes of the matrix should be considered a bus node using the top-k method. * Compute which nodes of the matrix should be considered a bus node using the top-k algorithm.
* *
* <p> * <p>
* Implements the bus-detection algorithm where the top gamma nodes are selected with the highest connection degree. * Implements the bus-detection algorithm where the top gamma nodes are selected with the highest connection degree.
...@@ -152,8 +159,7 @@ public class BusComputing { ...@@ -152,8 +159,7 @@ public class BusComputing {
} }
// Sort the array of pairs in descending order of the original array values. // Sort the array of pairs in descending order of the original array values.
Arrays.sort(pairs, Arrays.sort(pairs, (p1, p2) -> Integer.compare(p2.right, p1.right));
(Pair<Integer, Integer> p1, Pair<Integer, Integer> p2) -> Integer.compare(p2.right, p1.right));
// Extract the original indices, which are located in the left-hand side of each pairs. // Extract the original indices, which are located in the left-hand side of each pairs.
int[] result = new int[k]; int[] result = new int[k];
...@@ -165,7 +171,7 @@ public class BusComputing { ...@@ -165,7 +171,7 @@ public class BusComputing {
} }
/** /**
* Compute which nodes of the matrix should be considered a bus node using the fixed point algorithm. * Compute which nodes of the matrix should be considered a bus node using the fixed-point algorithm.
* *
* <p> * <p>
* Implements the bus-detection as described in [Wilschut 2018], Section 2.2.4, Page 21. * Implements the bus-detection as described in [Wilschut 2018], Section 2.2.4, Page 21.
...@@ -181,7 +187,7 @@ public class BusComputing { ...@@ -181,7 +187,7 @@ public class BusComputing {
} }
/** /**
* Compute which nodes of the matrix should be considered a bus node using the fixed point algorithm. * Compute which nodes of the matrix should be considered a bus node using the fixed-point algorithm.
* *
* <p> * <p>
* Implements the bus-detection as described in [Wilschut 2018], Section 2.2.4, Page 21. * Implements the bus-detection as described in [Wilschut 2018], Section 2.2.4, Page 21.
...@@ -197,7 +203,7 @@ public class BusComputing { ...@@ -197,7 +203,7 @@ public class BusComputing {
} }
/** /**
* Compute which nodes of the matrix should be considered a bus node using the fixed-point method. * Compute which nodes of the matrix should be considered a bus node using the fixed-point algorithm.
* *
* <p> * <p>
* Implements the bus-detection as described in [Wilschut 2018], Section 2.2.4, Page 21. * Implements the bus-detection as described in [Wilschut 2018], Section 2.2.4, Page 21.
......
...@@ -160,7 +160,7 @@ public class DsmClustering { ...@@ -160,7 +160,7 @@ public class DsmClustering {
int[] nodeShuffle = computeShuffle(rootGroup); int[] nodeShuffle = computeShuffle(rootGroup);
if (OutputProvider.dodbg()) { if (OutputProvider.dodbg()) {
OutputProvider.dbg(); OutputProvider.dbg();
OutputProvider.dbg("Node mapping new <- original: "); OutputProvider.dbg("Node mapping new <- original:");
for (int i = 0; i < nodeShuffle.length; i++) { for (int i = 0; i < nodeShuffle.length; i++) {
OutputProvider.dbg(" %d <- %d", i, nodeShuffle[i]); OutputProvider.dbg(" %d <- %d", i, nodeShuffle[i]);
} }
...@@ -204,7 +204,7 @@ public class DsmClustering { ...@@ -204,7 +204,7 @@ public class DsmClustering {
group.setShuffledBase(base); group.setShuffledBase(base);
Collections.sort(group.childGroups, GroupComparator.COMPARATOR); Collections.sort(group.childGroups, GroupComparator.COMPARATOR);
// Assign child groups // Assign child groups.
for (Group child: group.childGroups) { for (Group child: group.childGroups) {
int nextFree = assignGroups(nodeShuffle, base, child); int nextFree = assignGroups(nodeShuffle, base, child);
Assert.check(base + child.members.cardinality() == nextFree); Assert.check(base + child.members.cardinality() == nextFree);
...@@ -212,7 +212,6 @@ public class DsmClustering { ...@@ -212,7 +212,6 @@ public class DsmClustering {
} }
if (group.localNodes != null) { if (group.localNodes != null) {
// Assign local nodes. // Assign local nodes.
for (int i: iterateTrueBits(group.localNodes)) { for (int i: iterateTrueBits(group.localNodes)) {
nodeShuffle[base] = i; nodeShuffle[base] = i;
base++; base++;
......
...@@ -59,7 +59,7 @@ public class MarkovClustering { ...@@ -59,7 +59,7 @@ public class MarkovClustering {
final int size = m.getRowDimension(); final int size = m.getRowDimension();
OutputProvider.dbg(); OutputProvider.dbg();
OutputProvider.dbg("Input to Markov: "); OutputProvider.dbg("Input to Markov:");
OutputProvider.dbg(m.toString()); OutputProvider.dbg(m.toString());
// Iterate to stable probabilities. // Iterate to stable probabilities.
...@@ -78,7 +78,7 @@ public class MarkovClustering { ...@@ -78,7 +78,7 @@ public class MarkovClustering {
prune(m, pruningLimit); prune(m, pruningLimit);
} }
OutputProvider.dbg("Output from Markov: "); OutputProvider.dbg("Output from Markov:");
OutputProvider.dbg(m.toString()); OutputProvider.dbg(m.toString());
OutputProvider.dbg(); OutputProvider.dbg();
......
...@@ -178,7 +178,7 @@ public class MatrixHelper { ...@@ -178,7 +178,7 @@ public class MatrixHelper {
} }
/** /**
* Returns the result of exponentiating each entry of the supplied matrix by {code d}. * Returns the result of exponentiating each entry of the supplied matrix by {@code d}.
* *
* @param m Matrix to exponentiate entries for. * @param m Matrix to exponentiate entries for.
* @param d Value to exponentiate all entries by. * @param d Value to exponentiate all entries by.
......
...@@ -17,7 +17,6 @@ import static org.eclipse.escet.common.java.Lists.list; ...@@ -17,7 +17,6 @@ import static org.eclipse.escet.common.java.Lists.list;
import static org.eclipse.escet.common.java.Strings.fmt; import static org.eclipse.escet.common.java.Strings.fmt;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
...@@ -44,7 +43,7 @@ public class ReadMatrix { ...@@ -44,7 +43,7 @@ public class ReadMatrix {
* @return {@code null} if match failed, else a match result with various relevant indices. * @return {@code null} if match failed, else a match result with various relevant indices.
*/ */
private static MatchResult matchWord(String line, int start) { private static MatchResult matchWord(String line, int start) {
Assert.check(start >= 0 || start < line.length()); Assert.check(start >= 0 && start < line.length());
// Find first non-space at or after 'start'. // Find first non-space at or after 'start'.
int index = start; int index = start;
...@@ -87,7 +86,7 @@ public class ReadMatrix { ...@@ -87,7 +86,7 @@ public class ReadMatrix {
* @return {@code null} if match failed, else a match result with various relevant indices. * @return {@code null} if match failed, else a match result with various relevant indices.
*/ */
private static MatchResult matchSep(String line, int start) { private static MatchResult matchSep(String line, int start) {
Assert.check(start >= 0 || start < line.length()); Assert.check(start >= 0 && start < line.length());
int index = start; int index = start;
while (index < line.length() && Character.isWhitespace(line.charAt(index))) { while (index < line.length() && Character.isWhitespace(line.charAt(index))) {
...@@ -150,7 +149,7 @@ public class ReadMatrix { ...@@ -150,7 +149,7 @@ public class ReadMatrix {
*/ */
private static ClusterInputData convertToMatrix(List<List<String>> matrixLines) { private static ClusterInputData convertToMatrix(List<List<String>> matrixLines) {
// Decide on the size of the matrix. // Decide on the size of the matrix.
// Note that rows are expected to be one bigger, since the first column is labels. // Note that rows are expected to be one longer than columns, since the first column is labels.
// //
int matRowCount = matrixLines.size(); int matRowCount = matrixLines.size();
int matColcount = 0; int matColcount = 0;
...@@ -203,8 +202,8 @@ public class ReadMatrix { ...@@ -203,8 +202,8 @@ public class ReadMatrix {
* Read the matrix elements as rows and columns of texts. * Read the matrix elements as rows and columns of texts.
* *
* @param inp Input stream. * @param inp Input stream.
* @return Rows of columns of texts. Note that the number of columns at each line may be different. * @return Rows of columns of texts. Note that the number of columns at each line may be different. Also, no
* Also, no checking is performed whether the number of lines and columns match. * checking is performed whether the number of lines and columns match.
* @throws InputOutputException When a line of text could not be read. * @throws InputOutputException When a line of text could not be read.
*/ */
private static List<List<String>> readMatrixLines(BufferedReader inp) { private static List<List<String>> readMatrixLines(BufferedReader inp) {
...@@ -229,37 +228,31 @@ public class ReadMatrix { ...@@ -229,37 +228,31 @@ public class ReadMatrix {
/** /**
* Read the CSV-like adjacency and label data from the file with the provided name. * Read the CSV-like adjacency and label data from the file with the provided name.
* *
* <p>True CSV is a complicated format, so this code only does a subset.</p> * <p>
* <p>It assumes NxN numeric (real) values, as N lines of N comma or pipe separated numbers at a line. * True CSV is a complicated format, so this code only does a subset.
* Before the first number at each row should be a label designating the name of the element of that row. * </p>
* Optionally, above the first line of data may be a line of labels as well.</p> * <p>
* <p>Example: * It assumes NxN numeric (real) values, as N lines of N comma separated numbers at a line. Before the first number
* <pre> * at each row should be a label designating the name of the element of that row. Optionally, above the first line
* of data may be a line of labels as well.
* </p>
* <p>
* Example: <pre>
* "", "A", "B" * "", "A", "B"
* "A", 1, 0 * "A", 1, 0
* "B", 0.5, 0.1 * "B", 0.5, 0.1
* </pre>shows a 2x2 adjacency matrix of elements A and B with an additional first line of labels.</p> * </pre>shows a 2x2 adjacency matrix of elements A and B with an additional first line of labels.
* </p>
* *
* @param filename Name of the file to read. * @param filepath Path of the file to read.
* @return The read data. * @return The read data.
*/ */
public static ClusterInputData readMatrixFile(String filename) { public static ClusterInputData readMatrixFile(String filepath) {
BufferedReader handle = null; try (BufferedReader reader = new BufferedReader(new FileReader(filepath))) {
try { List<List<String>> matrixLines = readMatrixLines(reader);
handle = new BufferedReader(new FileReader(filename));
} catch (FileNotFoundException ex) {
throw new InputOutputException(fmt("Failed to open input file \"%s\".", filename), ex);
}
try {
List<List<String>> matrixLines = readMatrixLines(handle);
return convertToMatrix(matrixLines); return convertToMatrix(matrixLines);
} finally { } catch (IOException ex) {
try { throw new InputOutputException(fmt("Failed to read input file \"%s\".", filepath), ex);
handle.close();
} catch (IOException ex) {
throw new InputOutputException(fmt("Failed to close file \"%s\".", filename), ex);
}
} }
} }
} }
...@@ -25,7 +25,7 @@ import org.eclipse.escet.common.box.MemoryCodeBox; ...@@ -25,7 +25,7 @@ import org.eclipse.escet.common.box.MemoryCodeBox;
import org.eclipse.escet.common.dsm.Dsm; import org.eclipse.escet.common.dsm.Dsm;
import org.eclipse.escet.common.dsm.Group; import org.eclipse.escet.common.dsm.Group;
/** Generate a LaTeX tikz figure showing the DSM and write it. */ /** Generate a LaTeX TikZ figure showing the DSM and write it. */
public class WriteLatexFigure { public class WriteLatexFigure {
/** Constructor of the {@link WriteLatexFigure} class. */ /** Constructor of the {@link WriteLatexFigure} class. */
private WriteLatexFigure() { private WriteLatexFigure() {
...@@ -33,10 +33,10 @@ public class WriteLatexFigure { ...@@ -33,10 +33,10 @@ public class WriteLatexFigure {
} }
/** /**
* Write the clustered dsm and labels to the file in LaTeX tikz format. * Write the clustered DSM and labels to the file in LaTeX TikZ format.
* *
* @param outHandle Handle to the output file. * @param outHandle Handle to the output file.
* @param dsm Dsm with adjacency information. * @param dsm DSM with adjacency information.
*/ */
public static void writeMatrixLatexFigureToStream(AppStream outHandle, Dsm dsm) { public static void writeMatrixLatexFigureToStream(AppStream outHandle, Dsm dsm) {
CodeBox codeBox = createMatrixLatexFigure(dsm); CodeBox codeBox = createMatrixLatexFigure(dsm);
...@@ -44,9 +44,9 @@ public class WriteLatexFigure { ...@@ -44,9 +44,9 @@ public class WriteLatexFigure {
} }
/** /**
* Creates LaTeX code of a tikz figure of the clustered dsm and labels. * Creates LaTeX code of a TikZ figure of the clustered DSM and labels.
* *
* @param dsm Dsm with adjacency information. * @param dsm DSM with adjacency information.
* @return The generated text. * @return The generated text.
*/ */
public static CodeBox createMatrixLatexFigure(Dsm dsm) { public static CodeBox createMatrixLatexFigure(Dsm dsm) {
...@@ -55,7 +55,7 @@ public class WriteLatexFigure { ...@@ -55,7 +55,7 @@ public class WriteLatexFigure {
// Construct a line of text for each row. // Construct a line of text for each row.
int size = dsm.adjacencies.getRowDimension(); int size = dsm.adjacencies.getRowDimension();
// Begin tikz environment. // Begin TikZ environment.
codeBox.add("\\begin{tikzpicture}[every node/.style={font=\\huge}, scale=0.3, transform shape]"); codeBox.add("\\begin{tikzpicture}[every node/.style={font=\\huge}, scale=0.3, transform shape]");
// Draw the grid. // Draw the grid.
...@@ -78,22 +78,22 @@ public class WriteLatexFigure { ...@@ -78,22 +78,22 @@ public class WriteLatexFigure {
codeBox.add(); codeBox.add();
} }
// End tikz environment. // End TikZ environment.
codeBox.dedent(); codeBox.dedent();
codeBox.add("\\end{tikzpicture}"); codeBox.add("\\end{tikzpicture}");
return codeBox; return codeBox;
} }
/** /**
* Write the cluster outlines to the file in Latex tikz format. * Write the cluster outlines to the file in LaTeX TikZ format.
* *
* @param dsm The dsm to write the clusters for. * @param dsm The DSM to write the clusters for.
* @param codeBox The codebox to write to. * @param codeBox The codebox to write to.
*/ */
private static void writeClustersLatex(Dsm dsm, CodeBox codeBox) { private static void writeClustersLatex(Dsm dsm, CodeBox codeBox) {
int size = dsm.adjacencies.getColumnDimension(); int size = dsm.adjacencies.getColumnDimension();
// Print tikz line that defines the cluster lines properties. // Print TikZ line that defines the cluster lines properties.
codeBox.add("% Cluster lines."); codeBox.add("% Cluster lines.");
codeBox.add("\\draw[line width=1pt, line cap=rect]"); codeBox.add("\\draw[line width=1pt, line cap=rect]");
...@@ -105,13 +105,13 @@ public class WriteLatexFigure { ...@@ -105,13 +105,13 @@ public class WriteLatexFigure {
writeGroupLatex(gr, size, codeBox); writeGroupLatex(gr, size, codeBox);
} }
// Print closing semicolon for the tikz \draw. // Print closing semicolon for the TikZ \draw.
codeBox.dedent(); codeBox.dedent();
codeBox.add(";"); codeBox.add(";");
} }
/** /**
* Write the outline of the group and its children to the file in Latex tikz format. * Write the outline of the group and its children to the file in LaTeX TikZ format.
* *
* @param group Group to write (recursively). * @param group Group to write (recursively).
* @param sizeDsm The size of the matrix. * @param sizeDsm The size of the matrix.
...@@ -136,7 +136,7 @@ public class WriteLatexFigure { ...@@ -136,7 +136,7 @@ public class WriteLatexFigure {
} }
/** /**
* Write the specified label in the row or the column of a dsm to the file in the LaTeX tikz format. * Write the specified label in the row or the column of a DSM to the file in the LaTeX TikZ format.
* *
* @param label The label to print. * @param label The label to print.
* @param index The destination row / column index. * @param index The destination row / column index.
...@@ -146,7 +146,7 @@ public class WriteLatexFigure { ...@@ -146,7 +146,7 @@ public class WriteLatexFigure {
* @param codeBox The codebox to write to. * @param codeBox The codebox to write to.
*/ */
private static void writeLabelLatex(String label, int index, boolean labelsOnRow, int size, CodeBox codeBox) { private static void writeLabelLatex(String label, int index, boolean labelsOnRow, int size, CodeBox codeBox) {
// In Latex the _ needs to be escaped in text. // In LaTeX the '_' needs to be escaped in text.
label = label.replace("_", "\\_"); label = label.replace("_", "\\_");
String labelRow = labelsOnRow ? fmt(label + " - %s", index + 1) : fmt("%s", index + 1); String labelRow = labelsOnRow ? fmt(label + " - %s", index + 1) : fmt("%s", index + 1);
String labelColumn = !labelsOnRow ? fmt("%s - " + label, index + 1) : fmt("%s", index + 1); String labelColumn = !labelsOnRow ? fmt("%s - " + label, index + 1) : fmt("%s", index + 1);
...@@ -165,9 +165,9 @@ public class WriteLatexFigure { ...@@ -165,9 +165,9 @@ public class WriteLatexFigure {
} }
/** /**
* Write the specified row of a dsm to the file in the LaTeX tikz format. * Write the specified row of a DSM to the file in the LaTeX TikZ format.
* *
* @param dsm Dsm with adjacency information. * @param dsm DSM with adjacency information.
* @param row The index of the row to print. * @param row The index of the row to print.
* @param codeBox The codebox to write to. * @param codeBox The codebox to write to.
*/ */
......
...@@ -91,7 +91,7 @@ public class WriteMatrix { ...@@ -91,7 +91,7 @@ public class WriteMatrix {
* Append a left-aligned column of texts to the lines. * Append a left-aligned column of texts to the lines.
* *
* @param texts Text to add to each row. * @param texts Text to add to each row.
* @param lines Lines created so far. They are assumed to have equal length, and are modified in-place * @param lines Lines created so far. They are assumed to have equal length, and are modified in-place.
*/ */
private static void appendLeftAlignedColumn(String[] texts, StringBuilder[] lines) { private static void appendLeftAlignedColumn(String[] texts, StringBuilder[] lines) {
if (texts.length == 0) { if (texts.length == 0) {
...@@ -108,7 +108,7 @@ public class WriteMatrix { ...@@ -108,7 +108,7 @@ public class WriteMatrix {
* Append a right-aligned column of texts to the lines. * Append a right-aligned column of texts to the lines.
* *
* @param texts Text to add to each row. * @param texts Text to add to each row.
* @param lines Lines created so far. They are assumed to have equal length, and are modified in-place * @param lines Lines created so far. They are assumed to have equal length, and are modified in-place.
*/