View Javadoc
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.numbers.examples.jmh.arrays;
18  
19  /**
20   * Defines a transformer for {@code double[]} arrays.
21   *
22   * <p>This interface is not intended for a public API. It provides a consistent method
23   * to handle partial sorting of {@code double[]} data.
24   *
25   * <p>The transformer allows pre-processing data before applying a sort algorithm.
26   * This is required to handle {@code NaN} and signed-zeros {@code -0.0}.
27   *
28   * <p>Note: The {@code <} relation does not provide a total order on all double
29   * values: {@code -0.0 == 0.0} is {@code true} and a {@code NaN}
30   * value compares neither less than, greater than, nor equal to any value,
31   * even itself.
32   *
33   * <p>The {@link java.util.Arrays#sort(double[])} method respects the order imposed by
34   * {@link Double#compare(double, double)}: {@code -0.0} is treated as less than value
35   * {@code 0.0} and {@code Double.NaN} is considered greater than any
36   * other value and all {@code Double.NaN} values are considered equal.
37   *
38   * <p>This interface allows implementations to respect the behaviour
39   * {@link Double#compare(double, double)}, or implement different behaviour.
40   *
41   * @see java.util.Arrays#sort(double[])
42   * @since 1.2
43   */
44  interface DoubleDataTransformer {
45      /**
46       * Pre-process the data for partitioning.
47       *
48       * <p>This method will scan all the data and apply
49       * processing to {@code NaN} and signed-zeros {@code -0.0}.
50       *
51       * <p>A method matching {@link java.util.Arrays#sort(double[])} would move
52       * all {@code NaN} to the end of the array and order zeros. However ordering
53       * zeros is not useful if the data is to be fully or partially reordered
54       * by the caller. Possible solutions are to count signed zeros, or ignore them since
55       * they will not interfere with comparison operators {@code <, ==, >}.
56       *
57       * <p>The length of the data that must be processed by partitioning can be
58       * accessed using {@link #length()}. For example if {@code NaN} values are moved
59       * to the end of the data they are already partitioned. A partition algorithm
60       * can then avoid processing {@code NaN} during partitioning.
61       *
62       * @param data Data.
63       * @return pre-processed data (may be a copy)
64       */
65      double[] preProcess(double[] data);
66  
67      /**
68       * Get the size of the data.
69       *
70       * <p>Note: Although the pre-processed data array may be longer than this length some
71       * values may have been excluded from the data (e.g. removal of NaNs). This is the
72       * effective size of the data.
73       *
74       * @return the size
75       */
76      int size();
77  
78      /**
79       * Get the length of the pre-processed data that must be partitioned.
80       *
81       * <p>Note: Although the pre-processed data array may be longer than this length it is
82       * only required to partition indices below this length. For example the end of the
83       * array may contain values to ignore from partitioning such as {@code NaN}.
84       *
85       * @return the length
86       */
87      int length();
88  
89      /**
90       * Post-process the data after partitioning. This method can restore values that
91       * may have been removed from the pre-processed data, for example signed zeros
92       * or revert any special {@code NaN} value processing.
93       *
94       * <p>If no partition indices are available use {@code null} and {@code n = 0}.
95       *
96       * @param data Data.
97       * @param k Partition indices.
98       * @param n Count of partition indices.
99       */
100     void postProcess(double[] data, int[] k, int n);
101 
102     /**
103      * Post-process the data after sorting. This method can restore values that
104      * may have been removed from the pre-processed data, for example signed zeros
105      * or revert any special {@code NaN} value processing.
106      *
107      * <p>Warning: Assumes data is fully sorted in {@code [0, length)} (see {@link #length()}).
108      *
109      * @param data Data.
110      */
111     void postProcess(double[] data);
112 }