RegionalSensitivityAnalyzer.java [src/java/m/sensitivity/model/methods] Revision: default Date:
package m.sensitivity.model.methods;
import m.sensitivity.model.util.MathUtil;
import m.sensitivity.model.util.SortUtil;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class RegionalSensitivityAnalyzer implements SensitivityAnalyzer {
@Override
public String getName() {
return "rsa";
}
@Override
public Map<String, Double> compute(Map<String, List<Double>> parameters, List<Double> metric, boolean isPositiveBest) {
int numberOfParameters = parameters.size();
if (numberOfParameters < 1) {
return new HashMap<>();
}
int sampleSize = parameters.values().iterator().next().size();
List<Double> likelihood = isPositiveBest ? likelihoodPositiveBest(metric) : likelihoodZeroBest(metric);
List<Integer> sortedLikelihoodIndices = SortUtil.indicesOfSortedOrder(likelihood);
List<Integer> mostLikely = new ArrayList<>();
List<Integer> leastLikely = new ArrayList<>();
int splitIndex = (sampleSize & 0x1) == 0x0
? sampleSize / 2
: (sampleSize + 1) / 2;
for (int i = 0; i < splitIndex; ++i) {
leastLikely.add(sortedLikelihoodIndices.get(i));
}
for (int i = splitIndex; i < sampleSize; ++i) {
mostLikely.add(sortedLikelihoodIndices.get(i));
}
Map<String, Double> sensitivity = new LinkedHashMap<>();
for (Map.Entry<String, List<Double>> parameter : parameters.entrySet()) {
final String currentName = parameter.getKey();
final List<Double> currentValues = parameter.getValue();
Comparator<Integer> comparator = Comparator.comparingDouble(currentValues::get);
mostLikely.sort(comparator);
leastLikely.sort(comparator);
sensitivity.put(currentName, 0.0);
for (int mostLikelyIndex = 0, leastLikelyIndex = 0; mostLikelyIndex < mostLikely.size(); ++mostLikelyIndex) {
double mostLikelyValue = currentValues.get(mostLikely.get(mostLikelyIndex));
while (leastLikelyIndex < leastLikely.size()) {
double leastLikelyValue = currentValues.get(leastLikely.get(leastLikelyIndex));
if (leastLikelyValue >= mostLikelyValue) {
break;
}
++leastLikelyIndex;
}
double mostLikelyDistribution = ((double) (mostLikelyIndex + 1)) / mostLikely.size();
double leastLikelyDistribution = ((double) (leastLikelyIndex + 1)) / leastLikely.size();
double s = Math.abs(mostLikelyDistribution - leastLikelyDistribution);
if (s > sensitivity.get(currentName)) {
sensitivity.put(currentName, s);
}
}
}
MathUtil.normalize(sensitivity);
return sensitivity;
}
private static List<Double> likelihoodPositiveBest(List<Double> values) {
double min = MathUtil.findMin(values);
List<Double> likelihood = new ArrayList<>();
for (double value : values) {
likelihood.add(value - min);
}
MathUtil.normalize(likelihood);
return likelihood;
}
private static List<Double> likelihoodZeroBest(List<Double> values) {
List<Double> positiveBest = new ArrayList<>();
for (double value : values) {
if (value == 0.0) {
positiveBest.add(Double.MAX_VALUE);
} else {
positiveBest.add(1.0 / Math.abs(value));
}
}
return likelihoodPositiveBest(positiveBest);
}
}