Please see the Modelling with RiskAnalytics manual to see which distributions are already implemented.
Most distributions are taken from the SSJ library. SSJ is a Java library for stochastic simulation, developed in the
Département d'Informatique et de Recherche
Opérationnelle (DIRO), at the Université de Montréal.
Step by step example
All classes mentioned below can be found in the org.pillarone.modelling.util package.
We distinguish between random variable and probability
distributions. Both types are derived from DistributionType. Before
starting to implement a new distribution one should have a look at the
following classes in the same package as mentioned above:
ContinuousRandomDistributionType, DiscreteRandomDistributionType and
ContinuousVariateDistributionType, DiscreteVariateDistributionType.
Basically these classes act like an enumeration for the available
distribution.
In order to add a new distribution it is necessary to add a new
public static final variable, it's string representation and the
required parameters in one of the four classes mentioned above.
Furthermore the new variable has to be added to the "all" variable.
Adding a triangular distribution requires us to add the following line to the class ContinuousRandomDistributionType:
public static final ContinuousRandomDistributionType TRIANGULAR
= new ContinuousRandomDistributionType(
"Triangular", ["a": 0d, "b": 1d, "m": 0.5])
The parameters of this distribution ('a', 'b', 'm') will be
displayed on the UI in the same order as they are defined in this Map.
Furthermore we have to add TRIANGULAR to the "all" property in order to display it in the distribution selection lists:
public static final all = [NORMAL, LOGNORMAL, LOGNORMAL_MU_SIGMA, PARETO,
CENSOREDPARETO, TRUNCATEDPARETO, UNIFORM, CONSTANT,
PIECEWISELINEAREMPIRICAL, PIECEWISELINEAR, TRIANGULAR]
In a next step we need to add the distribution to the
RandomNumberGeneratorFactory: First we need a private static getter
method in order to instantiate the generator:
private static IRandomNumberGenerator getTriangularGenerator(
double a, double b, double m) {
TriangularGen generator = new UniformGen(new F2NL607(),
new TriangularGen(a, b, m))
return new RandomNumberGenerator(generator: generator)
}
This function is private as we won't allow direct instantiations.
Instead the getGenerator method should be used. Therefore we need to
add the new case to this function:
static IRandomNumberGenerator getGenerator(DistributionType type,
Map parameters) {
IRandomNumberGenerator generator
switch (type) {
case ContinuousRandomDistributionType.TRIANGULAR:
generator = getTriangularGenerator(parameters["a"],
parameters["b"],
parameters["c"])
break
The described steps are sufficient in order to add another
distribution that is already available in the SSJ library but not yet
wrapped into PillarOne. The newly added distribution is now available
in attritional or single claims generators
(org.pillarone.modelling.domain.generators.claims).
In order to add a more specific distribution an additional step is
required: A new class implementing the
umontreal.iro.lecuyer.probdist.Distribution interface has to be
written. Our PiecewiseLinearDistribution is an example of this
approach.
The implementation is incomplete as we didn't write a test case for
our new distribution. It's necessary to complete at least
RandomNumberGeneratorFactoryTests.testCreateTypedGenerator() and
RandomNumberGeneratorTests.
Caveat: These tests don't test if the generated sample corresponds to the defined distribution.
After completing these steps, the new distribution is part of the
list of distributions which appears in the user interface and the
parameters are displayed if a user selects the distribution. There is
no need to program graphical user interface elements.
Further information
We plan to implement a plugin mechanism to make this process much
simpler. The plugin mechanism will avoid the modification of core
classes and provide a self registration mechanism. This means that the
user may specify a new distribution in one file only. The rest will be
done using the plugin infrastructure.