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.  *      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. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus.optim;

  22. import org.hipparchus.exception.LocalizedCoreFormats;
  23. import org.hipparchus.exception.MathIllegalArgumentException;

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

  42.     /** Simple constructor.
  43.      * @param checker Convergence checker.
  44.      */
  45.     protected BaseMultivariateOptimizer(ConvergenceChecker<P> checker) {
  46.         super(checker);
  47.     }

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

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

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

  93.         // Check input consistency.
  94.         checkParameters();
  95.     }

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

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