@ScalarOperator(SATURATED_FLOOR_CAST) @SqlType(StandardTypes.INTEGER) public static long saturatedFloorCastToInteger(@SqlType(StandardTypes.DOUBLE) double value) { if (value <= MIN_INT_AS_DOUBLE) { return Integer.MIN_VALUE; } if (MAX_INT_AS_DOUBLE - value <= 1) { return Integer.MAX_VALUE; } return DoubleMath.roundToInt(value, FLOOR); }
@Override public ExperimentResults compute(Builder builder, Set<SimArgs> inputs) { final IdMap<MASConfiguration> configMap = new IdMap<>("c", MASConfiguration.class); final IdMap<ScenarioProvider> scenarioMap = new IdMap<>("s", ScenarioProvider.class); final IdMap<ObjectiveFunction> objFuncMap = new IdMap<>("o", ObjectiveFunction.class); final List<ResultListener> listeners = newArrayList(builder.resultListeners); @SuppressWarnings({"rawtypes", "unchecked"}) final IdMap<PostProcessor<?>> ppMap = new IdMap("p", PostProcessor.class); final Map<String, Scenario> scenariosMap = newLinkedHashMap(); // create tasks final List<SimulationTask> tasks = newArrayList(); constructTasks(inputs, tasks, configMap, scenarioMap, objFuncMap, ppMap, scenariosMap); // this sorts tasks using this chain: scenario, configuration, objective // function, postprocessor, seed Collections.sort(tasks); // determine size of batches final int numBatches = Math.min(tasks.size(), builder.numBatches); final int batchSize = DoubleMath.roundToInt(tasks.size() / (double) numBatches, RoundingMode.CEILING); final Map<Task<?>, JPPFJob> taskJobMap = newLinkedHashMap(); final ResultsCollector res = new ResultsCollector(tasks.size(), scenariosMap, taskJobMap, listeners); final List<JPPFJob> jobs = newArrayList(); for (int i = 0; i < numBatches; i++) { final JPPFJob job = new JPPFJob(new MemoryMapDataProvider(), res); job.setName(Joiner.on("").join(JOB_NAME, " ", i + 1, "/", numBatches)); jobs.add(job); for (final SimulationTask t : tasks.subList(i * batchSize, (i + 1) * batchSize)) { try { final MASConfiguration config = configMap.getValue(t.getConfigurationId()); final ScenarioProvider scenario = scenarioMap.getValue(t.getScenarioId()); final ObjectiveFunction objFunc = objFuncMap.getValue(t.getObjectiveFunctionId()); job.getDataProvider() .setParameter(t.getPostProcessorId(), ppMap.getValue(t.getPostProcessorId())); job.getDataProvider().setParameter(t.getConfigurationId(), config); job.getDataProvider().setParameter(t.getScenarioId(), scenario); job.getDataProvider().setParameter(t.getObjectiveFunctionId(), objFunc); job.add(t); } catch (final JPPFException e) { throw new IllegalStateException(e); } taskJobMap.put(t, job); } } for (final ResultListener l : listeners) { l.startComputing(tasks.size()); } checkState(!getJPPFClient().isClosed()); try { for (final JPPFJob job : jobs) { getJPPFClient().submitJob(job); } } catch (final Exception e) { throw new IllegalStateException(e); } res.awaitResults(); for (final ResultListener l : listeners) { l.doneComputing(); } return ExperimentResults.create(builder, res.buildResults()); }
/** * Erzeugt einen neuen Pixel an der Stelle (x,y). Die doubles werden entsprechend auf die * Integerpositionen des Pixels gerundet. * * @param x die x-Koordinate des Pixels * @param y die y-Koordinate des Pixels */ public Pixel(double x, double y) { this.x = DoubleMath.roundToInt(x, RoundingMode.HALF_DOWN); this.y = DoubleMath.roundToInt(y, RoundingMode.HALF_DOWN); }
public double findMinPerim(int leftIndex, int rightIndex, List<PointInt> listPointsSortedY) { int numberOfPoints = rightIndex - leftIndex + 1; Preconditions.checkArgument(listPointsSortedY.size() == numberOfPoints); if (numberOfPoints < 3) { return Double.MAX_VALUE; } int leftHalfEndIndex = leftIndex + numberOfPoints / 2 - 1; int rightHalfStartIndex = leftHalfEndIndex + 1; Preconditions.checkState(rightHalfStartIndex <= rightIndex); double min = Double.MAX_VALUE; /* * In order to avoid having to do another sort by y, (taking n log n), we just split using the sortedY list */ List<PointInt> leftList = new ArrayList<>(leftHalfEndIndex - leftIndex + 1); List<PointInt> rightList = new ArrayList<>(rightIndex - rightHalfStartIndex + 1); // We must compare x and y because though we are partitioning by a vertical line, we must also // be able to partition if all points have the same x // Because the partition is strictly less and due to rounding error from longs, // we use this as the division point PointInt midPoint = list.get(rightHalfStartIndex); for (PointInt pl : listPointsSortedY) { // Verify the points are still between left and right index Preconditions.checkState(list.get(leftIndex).getX() <= pl.getX()); Preconditions.checkState(list.get(rightIndex).getX() >= pl.getX()); if (compX.compare(pl, midPoint) < 0) { leftList.add(pl); } else { rightList.add(pl); } } Preconditions.checkState(leftList.size() == numberOfPoints / 2); Preconditions.checkState(leftList.size() > 0); Preconditions.checkState(rightList.size() > 0); Preconditions.checkState(leftHalfEndIndex != rightIndex); Preconditions.checkState(rightHalfStartIndex != leftIndex); Preconditions.checkState(numberOfPoints == leftList.size() + rightList.size()); // Divide double minLeft = findMinPerim(leftIndex, leftHalfEndIndex, leftList); double minRight = findMinPerim(rightHalfStartIndex, rightIndex, rightList); min = Math.min(minLeft, minRight); /* * For the combine, we make a box. * Left bound is min / 2 from vertical line, right bound is min / 2. * * Reason being that any triangle covering the vertical line and with a * point greater than min / 2 would have a perimeter > min. */ int boxMargin = DoubleMath.roundToInt( (min > Double.MAX_VALUE / 2 ? Integer.MAX_VALUE : min) / 2d, RoundingMode.UP); Preconditions.checkState(min > Integer.MAX_VALUE || boxMargin < min); Preconditions.checkState(min > Integer.MAX_VALUE || boxMargin * 2 >= min); List<PointInt> boxPoints = new ArrayList<>(); int startBox = 0; for (int i = 0; i < listPointsSortedY.size(); ++i) { PointInt point = listPointsSortedY.get(i); if (Math.abs(point.getX() - midPoint.getX()) > boxMargin) { continue; } // Calculate start of the box to consider. Should be at most // boxMargin away from currenty point. End of box is the last point added while (startBox < boxPoints.size() && point.getY() - boxPoints.get(startBox).getY() > boxMargin) { startBox++; } /** * To explain this, the box goes from -minP / 2 to + minP / 2 from the dividing vertical line. * Its height is also minP / 2. * * <p>Because we have the minimum with respect to the left and right sides, all triangles to * the left and right have max perimiter <= minP. * * <p>The only way to cram 16 points is to have 2 points on each corner and in the middle * * <p>PP-------PP--------PP * * <p>PP PP * * <p>PP-------PP--------PP * * <p>The perim of any triangle is >= minP. Any other point would be a triangle of perim < * minP. */ Preconditions.checkState(boxPoints.size() - startBox <= 16); // Consider all points in box (can be proved <= 16...Similar to most 6 for closest 2 points // algorithm for (int bi = startBox; bi < boxPoints.size(); ++bi) { for (int j = bi + 1; j < boxPoints.size(); ++j) { double perim = point.distance(boxPoints.get(bi)) + point.distance(boxPoints.get(j)) + boxPoints.get(bi).distance(boxPoints.get(j)); min = Math.min(min, perim); } } boxPoints.add(point); } return min; }