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 /* 19 * This is not the original file distributed by the Apache Software Foundation 20 * It has been modified by the Hipparchus project 21 */ 22 package org.hipparchus.util; 23 24 import org.hipparchus.exception.MathIllegalArgumentException; 25 26 /** 27 * A strategy to pick a pivoting index of an array for doing partitioning. 28 */ 29 public enum PivotingStrategy { 30 31 /** 32 * A mid point strategy based on the average of begin and end indices. 33 */ 34 CENTRAL { 35 /** 36 * {@inheritDoc} 37 * This in particular picks a average of begin and end indices 38 * @return The index corresponding to a simple average of 39 * the first and the last element indices of the array slice 40 * @throws MathIllegalArgumentException when indices exceeds range 41 */ 42 @Override 43 public int pivotIndex(final double[] work, final int begin, final int end) 44 throws MathIllegalArgumentException { 45 MathArrays.verifyValues(work, begin, end-begin); 46 return begin + (end - begin)/2; 47 } 48 }, 49 50 /** 51 * Classic median of 3 strategy given begin and end indices. 52 */ 53 MEDIAN_OF_3 { 54 /** 55 * {@inheritDoc} 56 * This in specific makes use of median of 3 pivoting. 57 * @return The index corresponding to a pivot chosen between the 58 * first, middle and the last indices of the array slice 59 * @throws MathIllegalArgumentException when indices exceeds range 60 */ 61 @Override 62 public int pivotIndex(final double[] work, final int begin, final int end) 63 throws MathIllegalArgumentException { 64 MathArrays.verifyValues(work, begin, end-begin); 65 final int inclusiveEnd = end - 1; 66 final int middle = begin + (inclusiveEnd - begin) / 2; 67 final double wBegin = work[begin]; 68 final double wMiddle = work[middle]; 69 final double wEnd = work[inclusiveEnd]; 70 71 if (wBegin < wMiddle) { 72 if (wMiddle < wEnd) { 73 return middle; 74 } else { 75 return wBegin < wEnd ? inclusiveEnd : begin; 76 } 77 } else { 78 if (wBegin < wEnd) { 79 return begin; 80 } else { 81 return wMiddle < wEnd ? inclusiveEnd : middle; 82 } 83 } 84 } 85 }; 86 87 /** 88 * Find pivot index of the array so that partition and K<sup>th</sup> 89 * element selection can be made 90 * @param work data array 91 * @param begin index of the first element of the slice 92 * @param end index after the last element of the slice 93 * @return the index of the pivot element chosen between the 94 * first and the last element of the array slice 95 * @throws MathIllegalArgumentException when indices exceeds range 96 */ 97 public abstract int pivotIndex(double[] work, int begin, int end) 98 throws MathIllegalArgumentException; 99 100 }