PivotingStrategy.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.util;

  22. import org.hipparchus.exception.MathIllegalArgumentException;

  23. /**
  24.  * A strategy to pick a pivoting index of an array for doing partitioning.
  25.  */
  26. public enum PivotingStrategy {

  27.     /**
  28.      * A mid point strategy based on the average of begin and end indices.
  29.      */
  30.     CENTRAL {
  31.         /**
  32.          * {@inheritDoc}
  33.          * This in particular picks a average of begin and end indices
  34.          * @return The index corresponding to a simple average of
  35.          * the first and the last element indices of the array slice
  36.          * @throws MathIllegalArgumentException when indices exceeds range
  37.          */
  38.         @Override
  39.         public int pivotIndex(final double[] work, final int begin, final int end)
  40.             throws MathIllegalArgumentException {
  41.             MathArrays.verifyValues(work, begin, end-begin);
  42.             return begin + (end - begin)/2;
  43.         }
  44.     },

  45.     /**
  46.      * Classic median of 3 strategy given begin and end indices.
  47.      */
  48.     MEDIAN_OF_3 {
  49.         /**
  50.          * {@inheritDoc}
  51.          * This in specific makes use of median of 3 pivoting.
  52.          * @return The index corresponding to a pivot chosen between the
  53.          * first, middle and the last indices of the array slice
  54.          * @throws MathIllegalArgumentException when indices exceeds range
  55.          */
  56.         @Override
  57.         public int pivotIndex(final double[] work, final int begin, final int end)
  58.             throws MathIllegalArgumentException {
  59.             MathArrays.verifyValues(work, begin, end-begin);
  60.             final int inclusiveEnd = end - 1;
  61.             final int middle = begin + (inclusiveEnd - begin) / 2;
  62.             final double wBegin = work[begin];
  63.             final double wMiddle = work[middle];
  64.             final double wEnd = work[inclusiveEnd];

  65.             if (wBegin < wMiddle) {
  66.                 if (wMiddle < wEnd) {
  67.                     return middle;
  68.                 } else {
  69.                     return wBegin < wEnd ? inclusiveEnd : begin;
  70.                 }
  71.             } else {
  72.                 if (wBegin < wEnd) {
  73.                     return begin;
  74.                 } else {
  75.                     return wMiddle < wEnd ? inclusiveEnd : middle;
  76.                 }
  77.             }
  78.         }
  79.     };

  80.     /**
  81.      * Find pivot index of the array so that partition and K<sup>th</sup>
  82.      * element selection can be made
  83.      * @param work data array
  84.      * @param begin index of the first element of the slice
  85.      * @param end index after the last element of the slice
  86.      * @return the index of the pivot element chosen between the
  87.      * first and the last element of the array slice
  88.      * @throws MathIllegalArgumentException when indices exceeds range
  89.      */
  90.     public abstract int pivotIndex(double[] work, int begin, int end)
  91.         throws MathIllegalArgumentException;

  92. }