/** * Compare two Boxes for order. * * @return -1 if box1 has lower lo bound of function value than box2, 1 otherwise, 0 is returned * ONLY IF BOX ARE EQUALS!! otherwise TreeSet will treat all such boxes as equal items and * will keep only one of them!!!!!!!!!! */ @Override public int compare(Box b1, Box b2) { assert (b1.getDimension() == b2.getDimension()); if (b1 == b2) return 0; double lo1 = b1.getFunctionValue().lo(); double lo2 = b2.getFunctionValue().lo(); if (lo1 == lo2) { if (b1.equals(b2)) return 0; double hi1 = b1.getFunctionValue().hi(); double hi2 = b2.getFunctionValue().hi(); if (hi1 == hi2) { double sumWid1 = 0, sumWid2 = 0; for (int i = b1.getDimension() - 1; i >= 0; i--) { sumWid1 += b1.getInterval(i).wid(); sumWid2 += b2.getInterval(i).wid(); } if (sumWid1 == sumWid2) { // ok. everything is absolutely equals, but these boxes are different. // lets distinguish them somehow for (int i = b1.getDimension() - 1; i >= 0; i--) { if (b1.getInterval(i).lo() < b2.getInterval(i).lo() || b1.getInterval(i).hi() < b2.getInterval(i).hi()) return -1; if (b1.getInterval(i).lo() > b2.getInterval(i).lo() || b1.getInterval(i).hi() > b2.getInterval(i).hi()) return 1; } } else return sumWid1 > sumWid2 ? -1 : 1; // wider boxes goes first } else return hi1 > hi2 ? -1 : 1; // offer boxes with wider function estimation first } return (lo1 < lo2) ? -1 : 1; }
@Override public boolean equals(Object thata) { // check for self-comparison if (this == thata) return true; // use instanceof instead of getClass here for two reasons // 1. if need be, it can match any supertype, and not just one class; // 2. it renders an explicit check for "that == null" redundant, since // it does the check for null already - "null instanceof [type]" always // returns false. (See Effective Java by Joshua Bloch.) if (!(thata instanceof Box)) return false; // Alternative to the above line : // if ( aThat == null || aThat.getClass() != this.getClass() ) return false; // cast to native object is now safe Box that = (Box) thata; // now a proper field-by-field evaluation can be made if (this.getDimension() != that.getDimension()) return false; if (!this.functionValue.equals(that.functionValue)) return false; for (int i = getDimension() - 1; i >= 0; i--) { if (!getInterval(i).equals(that.getInterval(i))) return false; } return true; }
/* * returns true if this box has at least one common edge point * with @box@. Used in screening by derivative in @Screener@ */ public boolean hasAtLeastOneCommonSide(Box box) { final int dim = getDimension(); assert (dim == box.getDimension()); for (int i = 0; i < dim; i++) { RealInterval a = this.getInterval(i); RealInterval b = box.getInterval(i); if (a.isIntersects(b)) return true; } return false; }
/** * FIRST derivative A point could be a minimum or a maximum if and only if the derivative is equal * to zero in this point. Therefore interval extensions of all partial derivatives have to contain * zero. The only exception are border points. Consider the following case: f(x) = x, * min_{0<x<1}(f) = f(0), but f'(x) != 0. BUT instead of performing such checks each time we just * have to add all ages to the working list from the very beginning! Much simple and less code: ) * Because of this it doesn't screen out boxes with at least one side width = 0 */ protected boolean check1Derivative(Box box) { Function function = FunctionFactory.getTargetFunction(); for (int i = box.getDimension() - 1; i >= 0; --i) { // A workaround for edges. Worklist adds zero-width // edges for initial search area. // See Worklist.addAreaAndAllEges() if (box.getInterval(i).wid() == 0) { return true; } RealInterval f1d = function.calculate1Derivative(box, i); if (f1d == null) break; if (!f1d.contains(0)) return false; } return true; // check passed }