BaseMultivariateOptimizer.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) 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 ASF 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.  *      http://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.apache.commons.math4.legacy.optim;

  18. import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
  19. import org.apache.commons.math4.legacy.exception.NumberIsTooLargeException;
  20. import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;

  21. /**
  22.  * Base class for implementing optimizers for multivariate functions.
  23.  * It contains the boiler-plate code for initial guess and bounds
  24.  * specifications.
  25.  * <em>It is not a "user" class.</em>
  26.  *
  27.  * @param <PAIR> Type of the point/value pair returned by the optimization
  28.  * algorithm.
  29.  *
  30.  * @since 3.1
  31.  */
  32. public abstract class BaseMultivariateOptimizer<PAIR>
  33.     extends BaseOptimizer<PAIR> {
  34.     /** Initial guess. */
  35.     private double[] start;
  36.     /** Lower bounds. */
  37.     private double[] lowerBound;
  38.     /** Upper bounds. */
  39.     private double[] upperBound;

  40.     /**
  41.      * @param checker Convergence checker.
  42.      */
  43.     protected BaseMultivariateOptimizer(ConvergenceChecker<PAIR> checker) {
  44.         super(checker);
  45.     }

  46.     /**
  47.      * {@inheritDoc}
  48.      *
  49.      * @param optData Optimization data. In addition to those documented in
  50.      * {@link BaseOptimizer#parseOptimizationData(OptimizationData[]) BaseOptimizer},
  51.      * this method will register the following data:
  52.      * <ul>
  53.      *  <li>{@link InitialGuess}</li>
  54.      *  <li>{@link SimpleBounds}</li>
  55.      * </ul>
  56.      * @return {@inheritDoc}
  57.      */
  58.     @Override
  59.     public PAIR optimize(OptimizationData... optData) {
  60.         // Perform optimization.
  61.         return super.optimize(optData);
  62.     }

  63.     /**
  64.      * Scans the list of (required and optional) optimization data that
  65.      * characterize the problem.
  66.      *
  67.      * @param optData Optimization data. The following data will be looked for:
  68.      * <ul>
  69.      *  <li>{@link InitialGuess}</li>
  70.      *  <li>{@link SimpleBounds}</li>
  71.      * </ul>
  72.      */
  73.     @Override
  74.     protected void parseOptimizationData(OptimizationData... optData) {
  75.         // Allow base class to register its own data.
  76.         super.parseOptimizationData(optData);

  77.         // The existing values (as set by the previous call) are reused if
  78.         // not provided in the argument list.
  79.         for (OptimizationData data : optData) {
  80.             if (data instanceof InitialGuess) {
  81.                 start = ((InitialGuess) data).getInitialGuess();
  82.                 continue;
  83.             }
  84.             if (data instanceof SimpleBounds) {
  85.                 final SimpleBounds bounds = (SimpleBounds) data;
  86.                 lowerBound = bounds.getLower();
  87.                 upperBound = bounds.getUpper();
  88.                 continue;
  89.             }
  90.         }

  91.         // Check input consistency.
  92.         checkParameters();
  93.     }

  94.     /**
  95.      * Gets the initial guess.
  96.      *
  97.      * @return the initial guess, or {@code null} if not set.
  98.      */
  99.     public double[] getStartPoint() {
  100.         return start == null ? null : start.clone();
  101.     }
  102.     /**
  103.      * @return the lower bounds, or {@code null} if not set.
  104.      */
  105.     public double[] getLowerBound() {
  106.         return lowerBound == null ? null : lowerBound.clone();
  107.     }
  108.     /**
  109.      * @return the upper bounds, or {@code null} if not set.
  110.      */
  111.     public double[] getUpperBound() {
  112.         return upperBound == null ? null : upperBound.clone();
  113.     }

  114.     /**
  115.      * Check parameters consistency.
  116.      */
  117.     private void checkParameters() {
  118.         if (start != null) {
  119.             final int dim = start.length;
  120.             if (lowerBound != null) {
  121.                 if (lowerBound.length != dim) {
  122.                     throw new DimensionMismatchException(lowerBound.length, dim);
  123.                 }
  124.                 for (int i = 0; i < dim; i++) {
  125.                     final double v = start[i];
  126.                     final double lo = lowerBound[i];
  127.                     if (v < lo) {
  128.                         throw new NumberIsTooSmallException(v, lo, true);
  129.                     }
  130.                 }
  131.             }
  132.             if (upperBound != null) {
  133.                 if (upperBound.length != dim) {
  134.                     throw new DimensionMismatchException(upperBound.length, dim);
  135.                 }
  136.                 for (int i = 0; i < dim; i++) {
  137.                     final double v = start[i];
  138.                     final double hi = upperBound[i];
  139.                     if (v > hi) {
  140.                         throw new NumberIsTooLargeException(v, hi, true);
  141.                     }
  142.                 }
  143.             }
  144.         }
  145.     }
  146. }