List of usage examples for org.apache.commons.math3.distribution LogNormalDistribution sample
public double[] sample(int sampleSize)
From source file:jeplus.data.ParameterItem.java
/** * Sampling function for probabilistic distributions * @param funcstr Function string/*from w w w . ja v a 2s . com*/ * @return List of sampled values in a string array */ private String[] sampleDistribution(String funcstr) { ArrayList<String> list = new ArrayList<>(); String[] params = funcstr.split("\\s*[,;]\\s*"); // For integer/double types, returns randomized N samples conforming // a specified distribution, currently 'gaussian'/'normal'/'n', // 'uniform'/'u', 'triangular'/'tr', or 'discrete'/'d' // for examples: @sample(gaussian, 0, 1.5, 20), with mean, sd and N // or @sample(uniform, -10, 10, 20), with lb, ub and N // of @sample(triangular, -1.0, 0.3, 1.0, 20), with lb, mode, ub and N // of @sample(discrete, option_A, 0.3, option_B, 0.5, option_C, 0.2, 20), with op1, weight1, op2, weight2..., and N String distribution = params[0].toLowerCase(); switch (distribution) { case "uniform": case "u": { // requires lb, ub, n double lb = Double.parseDouble(params[1]); double ub = Double.parseDouble(params[2]); int n = Integer.parseInt(params[3]); if (this.Type == DISCRETE) { // list.add(params[1]); // list.add(params[2]); list = null; } else { for (int i = 0; i < n; i++) { if (this.Type == DOUBLE) { list.add(Double.toString(RandomSource.getRandomGenerator().nextDouble() * (ub - lb) + lb)); } else if (this.Type == INTEGER) { list.add(Long.toString( Math.round(RandomSource.getRandomGenerator().nextDouble() * (ub - lb) + lb))); } } } break; } case "gaussian": case "normal": case "n": { // requires mean, sd, n double mean = Double.parseDouble(params[1]); double sd = Double.parseDouble(params[2]); int n = Integer.parseInt(params[3]); if (this.Type == DISCRETE) { // list.add(params[1]); list = null; } else { for (int i = 0; i < n; i++) { if (this.Type == DOUBLE) { list.add(Double.toString(RandomSource.getRandomGenerator().nextGaussian() * sd + mean)); } else if (this.Type == INTEGER) { list.add(Long.toString( Math.round(RandomSource.getRandomGenerator().nextGaussian() * sd + mean))); } } } break; } case "lognormal": case "ln": { // requires mean, sd, n double mean = Double.parseDouble(params[1]); double sd = Double.parseDouble(params[2]); int n = Integer.parseInt(params[3]); if (this.Type == DISCRETE) { // list.add(params[1]); list = null; } else { LogNormalDistribution lndist = new LogNormalDistribution(mean, sd); // Which RNG is used?? double[] sample = lndist.sample(n); for (int i = 0; i < n; i++) { if (this.Type == DOUBLE) { list.add(Double.toString(sample[i])); } else if (this.Type == INTEGER) { list.add(Long.toString(Math.round(sample[i]))); } } } break; } case "exponential": case "e": { // requires mean, n double mean = Double.parseDouble(params[1]); int n = Integer.parseInt(params[2]); if (this.Type == DISCRETE) { // list.add(params[1]); list = null; } else { ExponentialDistribution lndist = new ExponentialDistribution(mean); // Which RNG is used?? double[] sample = lndist.sample(n); for (int i = 0; i < n; i++) { if (this.Type == DOUBLE) { list.add(Double.toString(sample[i])); } else if (this.Type == INTEGER) { list.add(Long.toString(Math.round(sample[i]))); } } } break; } case "triangular": case "tr": { // requires a(lb), c(tip), b(ub), n double a = Double.parseDouble(params[1]); double c = Double.parseDouble(params[2]); double b = Double.parseDouble(params[3]); // sort a, b, c, so a < c < b // ... int n = Integer.parseInt(params[4]); if (this.Type == DISCRETE || !(a < c && c < b)) { // list.add(params[1]); // list.add(params[2]); // list.add(params[3]); list = null; } else { for (int i = 0; i < n; i++) { double x = RandomSource.getRandomGenerator().nextDouble(); double y = 0; if (x <= (c - a) / (b - a)) { y = Math.sqrt((c - a) * (b - a) * x) + a; } else { y = b - Math.sqrt((1 - x) * (b - a) * (b - c)); } if (this.Type == DOUBLE) { list.add(Double.toString(y)); } else if (this.Type == INTEGER) { list.add(Long.toString(Math.round(y))); } } } break; } case "discrete": case "d": { // requires op1, prob1, op2, prob2, ..., n int nOptions = params.length / 2 - 1; String[] options = new String[nOptions]; double[] probabilities = new double[nOptions]; double[] accProb = new double[nOptions]; for (int i = 0; i < nOptions; i++) { options[i] = params[2 * i + 1]; try { probabilities[i] = Double.parseDouble(params[2 * i + 2]); } catch (NumberFormatException nfe) { probabilities[i] = 0.1; } if (i == 0) accProb[i] = probabilities[i]; else accProb[i] = accProb[i - 1] + probabilities[i]; } int n = Integer.parseInt(params[params.length - 1]); for (int i = 0; i < n; i++) { double x = RandomSource.getRandomGenerator().nextDouble() * accProb[nOptions - 1]; int sel = 0; for (int j = 0; j < nOptions; j++) { if (x < accProb[j]) { sel = j; break; } } list.add(options[sel]); } break; } case "custom": // to be implemented list = null; break; } return (list == null) ? null : list.toArray(new String[0]); }