BoundedConstraint.java

  1. /*
  2.  * Licensed to the Hipparchus project under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The Hipparchus project licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.hipparchus.optim.nonlinear.vector.constrained;

  18. import org.hipparchus.linear.MatrixUtils;
  19. import org.hipparchus.linear.RealVector;
  20. import org.hipparchus.util.FastMath;
  21. import org.hipparchus.util.MathUtils;

  22. /** Constraint with lower and upper bounds: \(l \le f(x) \le u\).
  23.  * @since 3.1
  24.  */
  25. public abstract class BoundedConstraint implements Constraint {

  26.     /** Lower bound. */
  27.     private final RealVector lower;

  28.     /** Upper bound. */
  29.     private final RealVector upper;


  30.     /** Simple constructor.
  31.      * <p>
  32.      * At least one of the bounds must be non-null.
  33.      * </p>
  34.      * @param lower lower bound (null if no lower bound)
  35.      * @param upper upper bound (null if no upper bound)
  36.      */
  37.     protected BoundedConstraint(final RealVector lower, final RealVector upper) {

  38.          // ensure lower is always properly set, even when there are no lower bounds
  39.          if (lower == null) {
  40.              MathUtils.checkNotNull(upper);
  41.              this.lower = MatrixUtils.createRealVector(upper.getDimension());
  42.              this.lower.set(Double.NEGATIVE_INFINITY);
  43.          } else {
  44.              this.lower = lower;
  45.          }

  46.          // ensure upper is always properly set, even when there are no upper bounds
  47.          if (upper == null) {
  48.              this.upper = MatrixUtils.createRealVector(lower.getDimension());
  49.              this.upper.set(Double.POSITIVE_INFINITY);
  50.          } else {
  51.              this.upper = upper;
  52.          }

  53.          // safety check on dimensions
  54.          MathUtils.checkDimension(this.lower.getDimension(), this.upper.getDimension());

  55.      }

  56.      /** {@inheritDoc} */
  57.      @Override
  58.      public int dimY() {
  59.          return lower.getDimension();
  60.      }

  61.      /** {@inheritDoc} */
  62.      @Override
  63.      public RealVector getLowerBound() {
  64.          return lower;
  65.      }

  66.      /** {@inheritDoc} */
  67.      @Override
  68.      public RealVector getUpperBound() {
  69.          return upper;
  70.      }

  71.      /** {@inheritDoc} */
  72.      @Override
  73.      public double overshoot(final RealVector y) {

  74.          double overshoot = 0;
  75.          for (int i = 0; i < y.getDimension(); ++i) {
  76.              overshoot += FastMath.max(0, lower.getEntry(i) - y.getEntry(i));
  77.              overshoot += FastMath.max(0, y.getEntry(i) - upper.getEntry(i));
  78.          }

  79.          return overshoot;

  80.      }

  81. }