SortInPlace.java
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.apache.commons.numbers.arrays;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.Comparator;
- import java.util.List;
- /**
- * Sort an array and perform the same reordering of entries on other arrays.
- * For example, if
- * <ul>
- * <li>{@code x = [3, 1, 2]}</li>
- * <li>{@code y = [1, 2, 3]}</li>
- * <li>{@code z = [0, 5, 7]}</li>
- * </ul>
- * then {@code Sort.ASCENDING.apply(x, y, z)} will update those arrays:
- * <ul>
- * <li>{@code x = [1, 2, 3]}</li>
- * <li>{@code y = [2, 3, 1]}</li>
- * <li>{@code z = [5, 7, 0]}</li>
- * </ul>
- */
- public enum SortInPlace {
- /** Sort in ascending order. */
- ASCENDING((o1, o2) -> Double.compare(o1.key(), o2.key())),
- /** Sort in descending order. */
- DESCENDING((o1, o2) -> Double.compare(o2.key(), o1.key()));
- /** Comparator. */
- private final Comparator<PairDoubleInteger> comparator;
- /**
- * @param comparator Comparator.
- */
- SortInPlace(Comparator<PairDoubleInteger> comparator) {
- this.comparator = comparator;
- }
- /**
- * Sorts in place.
- *
- * @param x Array to be sorted and used as a pattern for permutation of
- * the other arrays.
- * @param yList Set of arrays whose permutations of entries will follow
- * those performed on {@code x}.
- * @throws IllegalArgumentException if not all arrays have the same size.
- */
- public void apply(double[] x,
- double[]... yList) {
- final int yListLen = yList.length;
- final int len = x.length;
- for (int j = 0; j < yListLen; j++) {
- final double[] y = yList[j];
- if (y.length != len) {
- throw new IllegalArgumentException("Size mismatch: " +
- y.length + " != " + len);
- }
- }
- // Associate each abscissa "x[i]" with its index "i".
- final List<PairDoubleInteger> list = new ArrayList<>(len);
- for (int i = 0; i < len; i++) {
- list.add(new PairDoubleInteger(x[i], i));
- }
- // Sort.
- Collections.sort(list, comparator);
- // Modify the original array so that its elements are in the prescribed order.
- // Retrieve indices of original locations.
- final int[] indices = new int[len];
- for (int i = 0; i < len; i++) {
- final PairDoubleInteger e = list.get(i);
- x[i] = e.key();
- indices[i] = e.value();
- }
- // In every associated array, move the elements to their new location.
- for (int j = 0; j < yListLen; j++) {
- // Input array will be modified in place.
- final double[] yInPlace = yList[j];
- final double[] yOrig = Arrays.copyOf(yInPlace, len);
- for (int i = 0; i < len; i++) {
- yInPlace[i] = yOrig[indices[i]];
- }
- }
- }
- /**
- * Helper data structure holding a (double, integer) pair.
- */
- private static class PairDoubleInteger {
- /** Key. */
- private final double key;
- /** Value. */
- private final int value;
- /**
- * @param key Key.
- * @param value Value.
- */
- PairDoubleInteger(double key,
- int value) {
- this.key = key;
- this.value = value;
- }
- /** @return the key. */
- double key() {
- return key;
- }
- /** @return the value. */
- int value() {
- return value;
- }
- }
- }