Sinalgo - Simulator for Network Algorithms

Tools

This section covers some tools you may use for your project.

Tools.java - a Collection of Useful Methods

The class Tools in the package sinalgo.tools is a collection of static methods that may be useful in several circumstances. It contains
  • Error handling
  • Settings of the framework
  • Information about the current simulation
  • Access to the set of nodes
  • Access to the set of messages currently being sent
  • Stop or exit the simulation
  • GUI related methods
  • And others...

Note: Most of the methods provided in this class are wrapper methods. The Tools class just collects these helpful methods, which are sometimes difficult to find in their original place.

Random Numbers

Many algorithms and models rely on random values to implement randomized decisions. At the same time, it is often desirable to run the exactly same simulation several times, either to understand its behavior, or to find errors. However, when the algorithms take some decisions purely randomly, it is impossible to rerun the exactly same simulation. To circumvent this problem, Sinalgo offers its own instance of a random number generator, which should be used exclusively. To access this instance, write

java.util.Random rand = sinalgo.tools.Tools.getRandomNumberGenerator();

This random number generator instance depends on the configuration file of the project. If the framework entry useFixedSeed is set, the random number generator is initialized with the fixedSeed, also provided in the configuration file. Otherwise, the random number generator is initialized randomly, such that subsequent simulations receive different random numbers.

Random Distributions

The package sinalgo.tools.statistics provides several random number generators that return random numbers according to a certain distribution probability. Available distributions are:

ExponentialDistribution Returns random values exponentially distributed with parameter lambda.
PoissonDistribution Returns random values Poisson distributed with parameter lambda.
GaussianDistribution Returns random values Gaussian distributed according to a given mean and variance.
UniformDistribution Returns random values randomly chosen in a given interval.
ConstantDistribution Returns a always the same constant. (Thus not really a random number.)
Available random number distributions in the package sinalgo.tools.statistics.

All of these distributions extend from sinalgo.tools.statistics.Distribution and implement the method double nextSample(), which returns the next random sample of the distribution. To obtain an instance of the Gaussian distribution, you can write:

GaussianDistribution gauss = new GaussianDistribution(mean, var);
gauss.nextSample(); // returns a random variable, normally distributed with the given mean and var

Alternatively, you can specify the type and settings of the distribution from within the configuration file of the project. The configuration entry needs to specify the name of the distribution as well as the distribution-specific parameters. The key of the tag that contains the attributes holding this information is used to retrieve the information. E.g. add to your configuration file the following entry in the Custom section:

<MyNode>
<speed distribution="Gaussian" mean="10" variance="20"/>
</MyNode>

In order to generate a distribution object from this entry, write

Distribution dist = Distribution.getDistributionFromConfigFile("MyNode/speed");
dist.nextSample(); // Returns a random variable distributed according to the chosen distribution.

Note: These classes base upon the random number generator of the framework and implement the seed-feature described in the Random Numbers section. Thus, a rerun of the exact same simulation is possible.

Sampling Data

The class DataSeries in the package sinalgo.tools.statistics is a statistic tool to determine simple statistic properties such as the mean and standard deviation of a series of measurements.

For each series of data you want to have a statistical analysis on, create a new object of this class and add the samples using the addSample() method. You can retrieve the mean, variance, standard deviance, sum, minimum, maximum, and count of the added samples.

Implementation Note: A DataSeries object does not store the added samples individually. Instead, it processes the samples immediately upon addition. Therefore, you may sample many huge data series without using up a lot of memory.

Export Network Graph to EPS or PDF

Sinalgo can export the current view of the network graph to a vector graphic in EPS or PDF format. To export the current view, click on the Graph menu, and select Export.

Sinalgo itself writes the graphics directly in EPS format. It does not support PDF itself, and calls an external application to convert the EPS file to a PDF file, if you choose to export to PDF. By default, the framework calls the epstopdf application. Change the field epsToPdfCommand in the framework section of the configuration file to specify a different application.

The export is similar to drawing the network graph on the screen: The framework iterates over all nodes and first draws for each node the connections. In a second iteration, it also draws the nodes, such that the nodes are not covered by the lines of the edges. For this purpose, the sinalgo.nodes.Node and sinalgo.nodes.edges.Edge classes implement the drawToPostScript() method. You may overwrite this method in your own node or edge subclasses to customize their appearance.

Logging

Sinalgo provides tools to facilitate logging, i.e. write certain output to files. The logging support is located in sinalgo.tools.logging. The class Logging provides methods to create log-files and add logging statements to an existing log-file.

The creation of a log-file is straight forward: To create a log-file with the name 'myLog.txt', write

Logging myLog = Logging.getLogger("myLog.txt");

By default, the log-files are placed in the logs folder in the root directory of Sinalgo. To put the log-file in a sub-directory, write

Logging myLog = Logging.getLogger("dir1/dir2/myLog.txt");

Then, to add log-statements, use the methods log(String) and logln(String). E.g.

myLog.log("Test"); myLog.logln("Test"); // appends a new-line to the given string

Subsequent calls to Logging.getLogger("myLog.txt") will return the same singleton Logging object. I.e. to access the same log-file from several classes, you need not make the logging object public or accessible, but can access it directly with the Logging.getLogger(String) method.

The framework already provides one global log-file, which may be used for logging, especially logging of errors. The file name of this framework log-file is specified in the project configuration file of each project. For this framework log-file (and only for this log-file), you can specify in the configuration file, whether a file should be created, or whether its content should be printed onto the standard output. You can access this framework log-file by calling Logging.getLogger() or through sinalgo.runtime.Global.log.

Log to Time Directory

By default, the log files are created in a folder logs of the root directory of the Sinalgo installation. I.e. subsequent runs of a simulation will overwrite the log-files. As this overwriting may be undesirable, the log-files may be placed in a unique folder, which gets created for each simulation run. The name of this unique folder is composed of the project-name and the time when the simulation started, these folders are placed in the 'logs' directory. You can turn on this feature in the project configuration file, by setting the entry logToTimeDirectory to true.

Logging with Levels

Logging statements may be used to debug a system. But after debugging, these statements are often not needed anymore. However, removing manually the log statements may be time consuming and often not desirable, as they need to be re-inserted if the problem occurs again. To avoid the removal of log-statements in the code, we support the concept of logging with levels. I.e. each log-statement takes as optional parameter a boolean indicating whether it should be printed or not. Collecting all of these boolean variables in a single file lets you quickly turn on or off different sets of log-statements. Therefore, when adding log-statements for a certain topic, assign to all of them the same boolean flag, such that all of them can be enabled or disabled by this flag (at compile-time).

In theory, this flag can be stored anywhere. We suggest that you collect all of these flags and store them in the class LogL in the root directory of your project. The file LogL.java may look as following:

public class LogL extends sinalgo.tools.logging.LogL {
public static final boolean testLog = false;
public static final boolean nodeSpeed = true;
}

The log-statements now look as following:

Logging myLog = Logging.getLogger("myLog.txt");
myLog.log(LogL.testLog, "Test");
myLog.logln(LogL.nodeSpeed, "Test");

The first log-statement won't be printed, as LogL.testLog is set to false.

Implementation Remark: In order to change the log-levels at runtime, you need to remove the final modifier for the corresponding log-levels in the LogL.java file.

Appending to Log Files

The logging class allows to append to an existing log-file from a previous run. To do so, call the getLogger() method with the second optional parameter set to true. Note that log-files created with the append flag set to true are always placed in the logs folder and ignore the logToTimeDirectory flag.

Logging the Code Position

When a log-file collects log-statements from several code fragments, it is often difficult to remember which piece of code was responsible for a given log statement. Therefore, the logging class provides methods to automatically prefix a log-statement with the class name, method name, and line number of the source-file where the log-statement executed. To prefix a statement with the code position, use either logPos(...) or logPosln(...). For personalized use, you may also consider the method Logging.getCodePosition(), which returns a string representation of the code position where the method is being called.

Performance Issues

Turning off logging by setting the corresponding flag to false still triggers the corresponding log method to be called. Even more costly is often the composition of the string that is passed to the log-method. [The composition of the string is not only costly in terms of time, but also allocates new memory cells, which need to be reclaimed by the garbage collector later on.]
Most of the time, this is no problem. E.g. when the log-statement is placed in a part of the code that executes rarely. But when the log-statement is located in a piece of code that executes very often, e.g. in every step of every round, this may decrease simulation performance noticeably.
A possible work-around for such exposed log-statements is to not use the log-level flag in the method-call, but surround the log-statements with an if() clause, that only executes if the corresponding log-level is set to true:

if(LogL.testLog) {
myLog.log("Test"); //we don't need the log-level anymore
}

Background Map

By default, the deployment area is a rectangular region in 2D, and a cuboid in 3D, whose dimensions are specified in the project specific configuration file. For the 2D case, Sinalgo offers an extension to display a picture on the deployment area. The interpretation of this background map is purely project specific. E.g. colored areas may denote obstacles, where no nodes can be placed.

The usage of the background image can be enabled in the configuration file, which also contains the path of the image file to use. The search path for the image is the root directory of the project. The image formats that Sinalgo can decode depends on your JAVA installation. Most likely, the following formats are supported: GIF, PNG, BMP, JPG.

The background image is scaled along the x and y axis to exactly fit the deployment area. As a result, the provided image may be quite small. In fact, huge images allow to encode more and finer details, but take also more time to display.

The instance of sinalgo.io.mapIO.Map, which may be accessed through Tools.getBackgroundMap(), provides methods to determine the color of any position on the deployment area.



© Distributed Computing Group
GitHub.com Mark GitHub.com Logo SourceForge.net Logo Valid CSS! Valid HTML 4.01 Transitional