Пример #1
0
  @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;
  }
Пример #2
0
 /*
  * 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;
 }
Пример #3
0
  @Override
  public Box clone() {
    int dim = this.getDimension();
    Box b = new Box(dim);

    for (int i = 0; i < dim; i++) {
      b.intervals[i] = (RealInterval) intervals[i].clone();
    }

    b.functionValue = (RealInterval) functionValue.clone();

    return b;
  }
  /**
   * 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
  }
Пример #5
0
  private Box[] splitSideByPoint(int sideNum, double cutPoint) {
    RealInterval side = getInterval(sideNum);
    assert (side.contains(cutPoint));

    Box one = this.clone();
    Box two = this.clone();
    one.setFunctionValue(unset); // Flush function values.
    two.setFunctionValue(unset); // On new sub-boxes it is not calculated yet.

    RealInterval left = new RealInterval(side.lo(), cutPoint);
    RealInterval right = new RealInterval(cutPoint, side.hi());

    one.setInterval(sideNum, left);
    two.setInterval(sideNum, right);

    Box result[] = {one, two};
    return result;
  }
Пример #6
0
  /*
   * in some cases we could suspect that some point inside the box is an optimum
   * that we are looking for. (For example when a point algorithm found it).
   * Than we want to check this. To do this we cut the box on a small box
   * around this point and everything else
   */
  public Box[] cutOutBoxAroundThisPoint(double[] potentialOptPoint) {
    final double epsilon = 5e-4;

    final int dim = getDimension();
    assert (potentialOptPoint.length == dim);
    if (!this.contains(potentialOptPoint)) {
      // probably it is due to rounding error and it is close
      // save original point for diagnostic
      double[] origPoint = potentialOptPoint.clone();
      if (setToClosestAreaPoint(potentialOptPoint) < epsilon * dim) {
        // let it be "close enough"
        // continue
      } else {
        Box arr[] = new Box[1];
        arr[0] = this;
        // possible bug. Lets fail in debug. See origPoint[].
        assert (false);
        return arr;
      }
    }
    ArrayList<Box> parts = new ArrayList<>();
    Box boxOfInterest = this;
    Box boxes[] = null;
    for (int i = 0; i < dim; i++) {
      double cutPoint = potentialOptPoint[i] - epsilon;
      if (boxOfInterest.getInterval(i).contains(cutPoint)) {
        boxes = boxOfInterest.splitSideByPoint(i, cutPoint);
        assert (boxes[1].contains(potentialOptPoint)); // "our" box is right
        parts.add(boxes[0]);
        boxOfInterest = boxes[1];
      }
      cutPoint = potentialOptPoint[i] + epsilon; // <
      if (boxOfInterest.getInterval(i).contains(cutPoint)) {
        boxes = boxOfInterest.splitSideByPoint(i, cutPoint);
        assert (boxes[0].contains(potentialOptPoint)); // "our" box is left now
        parts.add(boxes[1]);
        boxOfInterest = boxes[0];
      }
    }
    assert (boxOfInterest.contains(potentialOptPoint));
    parts.add(boxOfInterest);
    return parts.toArray(new Box[parts.size()]);
  }
Пример #7
0
 /**
  * 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;
 }