diff --git a/src/main/java/ch/idsia/crema/preprocess/creators/CreateCPT.java b/src/main/java/ch/idsia/crema/preprocess/creators/CreateCPT.java index 6c0a3109..837e4e51 100644 --- a/src/main/java/ch/idsia/crema/preprocess/creators/CreateCPT.java +++ b/src/main/java/ch/idsia/crema/preprocess/creators/CreateCPT.java @@ -5,6 +5,7 @@ import ch.idsia.crema.factor.credal.linear.interval.IntervalFactorFactory; import ch.idsia.crema.utility.IndexIterator; +import java.util.ArrayList; import java.util.Arrays; public class CreateCPT { @@ -19,21 +20,29 @@ public class CreateCPT { */ public double[] borders(double[] lower, double[] upper, Op operation) { - //shortcut in case the function is strictly monotone growing - //double[] extremes= new double[]{operation.execute(lower[0], upper[1]), operation.execute(upper[0], lower[1])}; - //return Arrays.stream(extremes).sorted().toArray(); + int DIM = (int) Math.pow(2, lower.length); + double[] results = new double[DIM]; - double[] results = new double[2 * lower.length]; - results[0] = operation.execute(lower[0], lower[1]); - results[1] = operation.execute(lower[0], upper[1]); - results[2] = operation.execute(upper[0], lower[1]); - results[3] = operation.execute(upper[0], upper[1]); - - Arrays.sort(results); - double firstElement = results[0]; - double lastElement = results[results.length - 1]; + for (int i = 0; i < DIM; i++) { + StringBuilder binary = new StringBuilder(Integer.toBinaryString(i)); + for(int j = binary.length(); j < lower.length; j++) { + binary.insert( 0, '0' ); + } + ArrayList paramList = new ArrayList<>(); + + for(int j = 0; j < binary.length(); j++) { + if(binary.charAt(j) == '0') { + paramList.add(lower[j]); + } else { + paramList.add(upper[j]); + } + } + results[i] = operation.execute(paramList.stream().mapToDouble(Double::doubleValue).toArray()); + } - return new double[]{firstElement, lastElement}; + return new double[]{ + Arrays.stream(results).min().isPresent()? Arrays.stream(results).min().getAsDouble(): 0.0, + Arrays.stream(results).max().isPresent()? Arrays.stream(results).max().getAsDouble(): 0.0}; } /** @@ -51,7 +60,7 @@ public IntervalFactor create(int childVar, int[] parentsVars, double[] childCuts // root nodes creation // add child node - int dimChild = childCuts.length + 1; + int dimChild = childCuts.length-1; Strides stridesChild = Strides.var(childVar, dimChild); // create domain @@ -80,8 +89,12 @@ public IntervalFactor create(int childVar, int[] parentsVars, double[] childCuts //map the integers of the position of the childCuts int[] intervalNumber = Arrays.stream(intervalBorders).mapToInt(val -> whichPosition(childCuts, val)).toArray(); - // the lower is set to an array of zeroes the upper is set to 1 in the position of the interval number - factory.set(new double[dimChild], createUpper(intervalNumber, dimChild), comb); + boolean allEqual = intervalNumber.length == 1 || Arrays.stream(intervalNumber).allMatch(t -> t == intervalNumber[0]); + if(allEqual){ + factory.set(createArrayWithOneAtIndex(intervalNumber, dimChild), createArrayWithOneAtIndex(intervalNumber, dimChild), comb); + }else{ + factory.set(new double[dimChild], createArrayWithOneAtIndex(intervalNumber, dimChild), comb); + } iterator.next(); } return factory.get(); @@ -92,7 +105,7 @@ public IntervalFactor create(int childVar, int[] parentsVars, double[] childCuts * @param dim dimension of the array to be generated * @return double array with 1.0 set for every interval value */ - public double[] createUpper(int[] interval, int dim) { + public double[] createArrayWithOneAtIndex(int[] interval, int dim) { double[] upper = new double[dim]; // we set to 1.0 all the element relative to the interval diff --git a/src/main/java/ch/idsia/crema/preprocess/creators/Op.java b/src/main/java/ch/idsia/crema/preprocess/creators/Op.java index 6c7bfef4..41f23b58 100644 --- a/src/main/java/ch/idsia/crema/preprocess/creators/Op.java +++ b/src/main/java/ch/idsia/crema/preprocess/creators/Op.java @@ -2,5 +2,5 @@ @FunctionalInterface public interface Op { - double execute(double a, double b); + double execute(double... params); } diff --git a/src/test/java/ch/idsia/crema/preprocess/creators/CreateCPTTest.java b/src/test/java/ch/idsia/crema/preprocess/creators/CreateCPTTest.java index abe46e2e..2e5fecfe 100644 --- a/src/test/java/ch/idsia/crema/preprocess/creators/CreateCPTTest.java +++ b/src/test/java/ch/idsia/crema/preprocess/creators/CreateCPTTest.java @@ -19,26 +19,26 @@ public void testCreate() { double[] cutsBMI = new double[]{0.0, 15.0, 16, 18.5, 25.0, 30.0, 35.0, 40.0, 100.0}; double[][] parents = new double[][]{cutsW, cutsH}; - Op bmi = (w, h) -> w / h / h; + Op bmi = (double... num) -> num[0] / num[1] / num[1]; IntervalFactor cpt = creator.create(2, new int[]{0, 1}, cutsBMI, parents, bmi); //System.out.println(cpt); // w1 and h1 - assertArrayEquals(cpt.getLower(0, 0), new double[10]); - assertArrayEquals(cpt.getUpper(0, 0), creator.createUpper(new int[]{4}, 10)); + assertArrayEquals(cpt.getLower(0, 0), creator.createArrayWithOneAtIndex(new int[]{4}, 8)); + assertArrayEquals(cpt.getUpper(0, 0), creator.createArrayWithOneAtIndex(new int[]{4}, 8)); // w2 and h1 - assertArrayEquals(cpt.getLower(1, 0), new double[10]); - assertArrayEquals(cpt.getUpper(1, 0), creator.createUpper(new int[]{4, 5}, 10)); + assertArrayEquals(cpt.getLower(1, 0), new double[8]); + assertArrayEquals(cpt.getUpper(1, 0), creator.createArrayWithOneAtIndex(new int[]{4, 5}, 8)); // w5 and h6 - assertArrayEquals(cpt.getLower(4, 5), new double[10]); - assertArrayEquals(cpt.getUpper(4, 5), creator.createUpper(new int[]{4}, 10)); + assertArrayEquals(cpt.getLower(4, 5), creator.createArrayWithOneAtIndex(new int[]{4}, 8)); + assertArrayEquals(cpt.getUpper(4, 5), creator.createArrayWithOneAtIndex(new int[]{4}, 8)); // w12 and h9 - assertArrayEquals(cpt.getLower(11, 8), new double[10]); - assertArrayEquals(cpt.getUpper(11, 8), creator.createUpper(new int[]{5, 6}, 10)); + assertArrayEquals(cpt.getLower(11, 8), new double[8]); + assertArrayEquals(cpt.getUpper(11, 8), creator.createArrayWithOneAtIndex(new int[]{5, 6}, 8)); } @Test @@ -46,7 +46,7 @@ public void testBorders() { double[] parentIntervalLower = new double[]{55.0, 1.55}; double[] parentIntervalUpper = new double[]{60.0, 1.60}; //example of the BMI - Op bmi = (w, h) -> w / h / h; + Op bmi = (double... num) -> num[0] / num[1] / num[1]; //bmi low = 21.48 //bmi high = 24.97 @@ -69,9 +69,9 @@ public void testWhichPosition() { } @Test - public void testCreateUpper() { + public void testCreateArrayWithOneAtIndex() { int[] interval = new int[]{3, 4}; - double[] result = creator.createUpper(interval, 4); + double[] result = creator.createArrayWithOneAtIndex(interval, 4); double[] expected = new double[]{.0, .0, 1.0, 1.0}; assertArrayEquals(result, expected);