/* * Copyright 2015-2016 OpenCB * * Licensed 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.opencb.opencga.core.common; import java.lang.reflect.Array; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Random; public class ArrayUtils { /* * * GETTING THE MAX OF A INTEGER ARRAY * */ public static int max(int[] values) { return values[max(values, 0, values.length)]; } public static int max(int[] values, int begin, int end) { int index = maxIndex(values, begin, end); if (index >= 0 && index < values.length) { return values[index]; } else { return Integer.MIN_VALUE; } } public static int maxIndex(int[] values) { return maxIndex(values, 0, values.length); } public static int maxIndex(int[] values, int begin, int end) { int max = Integer.MIN_VALUE; int index = -1; if (checkArguments(values, begin, end)) { max = values[begin]; index = begin; for (int i = begin; i < end; i++) { if (values[i] > max) { max = values[i]; index = i; } } } return index; } /* * MAX - DOUBLE ARRAY */ public static double max(double[] values) { return max(values, 0, values.length); } public static double max(double[] values, int begin, int end) { int index = maxIndex(values, begin, end); if (index >= 0 && index < values.length) { return values[index]; } else { return Double.NaN; } } public static int maxIndex(double[] values) { return maxIndex(values, 0, values.length); } public static int maxIndex(double[] values, int begin, int end) { double max = Double.NaN; int index = -1; if (checkArguments(values, begin, end)) { max = values[begin]; index = begin; for (int i = begin; i < end; i++) { if (!Double.isNaN(values[i])) { if (values[i] > max) { max = values[i]; index = i; } } } } return index; } /* * * GETTING THE MIN OF A VECTOR * */ public static int min(int[] values) { return min(values, 0, values.length); } public static int min(int[] values, int begin, int end) { int index = minIndex(values, begin, end); if (index >= 0 && index < values.length) { return values[index]; } else { return Integer.MAX_VALUE; } } public static int minIndex(int[] values) { return minIndex(values, 0, values.length); } public static int minIndex(int[] values, int begin, int end) { int min = Integer.MAX_VALUE; int index = -1; if (checkArguments(values, begin, end)) { min = values[begin]; index = begin; for (int i = begin; i < end; i++) { if (values[i] < min) { min = values[i]; index = i; } } } return index; } public static double min(double[] values) { return min(values, 0, values.length); } public static double min(double[] values, int begin, int end) { int index = minIndex(values, begin, end); if (index >= 0 && index < values.length) { return values[index]; } else { return Double.NaN; } } public static int minIndex(double[] values) { return minIndex(values, 0, values.length); } public static int minIndex(double[] values, int begin, int end) { double min = Double.NaN; int index = -1; if (checkArguments(values, begin, end)) { min = values[begin]; index = begin; for (int i = begin; i < end; i++) { if (!Double.isNaN(values[i])) { if (values[i] < min) { min = values[i]; index = i; } } } } return index; } public static double[] abs(double[] in) { if (in != null && in.length > 0) { double[] out = new double[in.length]; for (int i = 0; i < in.length; i++) { out[i] = Math.abs(in[i]); } return out; } else { return null; } } /* * * SEQUENCE METHODS * */ public static int[] sequence(int start, int end) { return sequence(start, end, 1); } public static int[] sequence(int start, int end, int increment) { int[] data = new int[(end - start) / increment + 1]; for (int i = start, index = 0; i <= end; i += increment, index++) { data[index] = i; } return data; } public static double[] sequence(double start, double end, double increment) { double[] data = new double[(int) (Math.round((end - start) / increment + 1))]; int index = 0; DecimalFormat format = new DecimalFormat("#.####"); for (double i = start; i <= end; i += increment) { i = Double.parseDouble(format.format(i)); data[index] = i; index++; } return data; } /* * * SORT AND ORDER METHODS * */ public static int[] sort(final int[] data) { return sort(data, true); } public static int[] sort(final int[] data, boolean ascending) { int[] sortedData = data.clone(); Arrays.sort(sortedData); if (!ascending) { sortedData = reverse(sortedData); } return sortedData; } public static double[] sort(final double[] data) { return sort(data, true); } public static double[] sort(final double[] data, boolean ascending) { double[] sortedData = data.clone(); Arrays.sort(sortedData); if (!ascending) { sortedData = reverse(sortedData); } return sortedData; } public static int[] reverse(final int[] data) { int[] reverseData = new int[data.length]; for (int i = 0, j = data.length - 1; i < data.length; i++, j--) { reverseData[i] = data[j]; } return reverseData; } public static double[] reverse(final double[] data) { double[] reverseData = new double[data.length]; for (int i = 0, j = data.length - 1; i < data.length; i++, j--) { reverseData[i] = data[j]; } return reverseData; } public static int[] order(final int[] data) { return order(toDoubleArray(data), false); } public static int[] order(final int[] data, boolean decreasing) { return order(toDoubleArray(data), decreasing); } public static int[] order(final double[] data) { return order(data, false); } public static int[] order(final double[] data, boolean decreasing) { int[] order = new int[data.length]; double[] clonedData = data.clone(); if (decreasing) { double min = nonInfinityAndMinValueMin(clonedData); // to avoid the NaN missorder for (int i = 0; i < clonedData.length; i++) { if (Double.isNaN(clonedData[i])) { clonedData[i] = min - 3; } if (clonedData[i] == Double.NEGATIVE_INFINITY) { clonedData[i] = min - 2; } if (clonedData[i] == Double.MIN_VALUE) { clonedData[i] = min - 1; } } // get the order for (int i = 0; i < clonedData.length; i++) { order[i] = maxIndex(clonedData); clonedData[order[i]] = Double.NEGATIVE_INFINITY; } } else { double max = nonInfinityAndMaxValueMax(clonedData); // to avoid the NaN missorder for (int i = 0; i < clonedData.length; i++) { if (Double.isNaN(clonedData[i])) { clonedData[i] = max + 3; } if (clonedData[i] == Double.POSITIVE_INFINITY) { clonedData[i] = max + 2; } if (clonedData[i] == Double.MAX_VALUE) { clonedData[i] = max + 1; } } // get the order for (int i = 0; i < clonedData.length; i++) { order[i] = minIndex(clonedData); clonedData[order[i]] = Double.POSITIVE_INFINITY; } } return order; } public static double nonInfinityAndMinValueMin(double[] data) { double min = Double.POSITIVE_INFINITY; for (int i = 0; i < data.length; i++) { if (data[i] < min && data[i] != Double.NEGATIVE_INFINITY && data[i] != Double.MIN_VALUE) { min = data[i]; } } return min; } public static double nonInfinityAndMaxValueMax(double[] data) { double max = Double.NEGATIVE_INFINITY; for (int i = 0; i < data.length; i++) { if (data[i] > max && data[i] != Double.POSITIVE_INFINITY && data[i] != Double.MAX_VALUE) { max = data[i]; } } return max; } public static int[] ordered(final int[] data, int[] positions) { int[] ordered = null; if (data.length == positions.length) { ordered = new int[data.length]; for (int i = 0; i < positions.length; i++) { ordered[i] = data[positions[i]]; } } return ordered; } public static double[] ordered(final double[] data, int[] positions) { double[] ordered = null; if (data.length == positions.length) { ordered = new double[data.length]; for (int i = 0; i < positions.length; i++) { ordered[i] = data[positions[i]]; } } return ordered; } public static double[] initialize(int numElements, double elem) { double[] array = new double[numElements]; for (int i = 0; i < numElements; i++) { array[i] = elem; } return array; } @SuppressWarnings("unchecked") public static <E> E[] initialize(int numElements, E elem) { E[] array = (E[]) Array.newInstance(elem.getClass(), numElements); for (int i = 0; i < numElements; i++) { array[i] = elem; } return array; } public static <E> String[] initialize(int numElements, E prefix, int startNumber) { String[] array = new String[numElements]; for (int i = 0; i < numElements; i++) { array[i] = (prefix.toString() + startNumber++); } return array; } public static double[] random(int numElements) { return random(numElements, 1.0); } public static double[] random(int numElements, double scaleFactor) { try { Thread.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } Random r = new Random(System.currentTimeMillis()); double[] randomList = new double[numElements]; for (int i = 0; i < numElements; i++) { randomList[i] = r.nextDouble() * scaleFactor; } return randomList; } public static double[] randomGaussian(int numElements) { return randomGaussian(numElements, 1.0); } public static double[] randomGaussian(int numElements, double scaleFactor) { Random r = new Random(System.currentTimeMillis()); double[] randomList = new double[numElements]; for (int i = 0; i < numElements; i++) { randomList[i] = r.nextGaussian() * scaleFactor; } return randomList; } /* * * Converters from Array to the same type of List, signature: toList() * */ public static List<Double> toList(final double[] array) { List<Double> list = new ArrayList<Double>(array.length); for (int i = 0; i < array.length; i++) { list.add(array[i]); } return list; } public static List<Integer> toList(final int[] array) { List<Integer> list = new ArrayList<Integer>(array.length); for (int i = 0; i < array.length; i++) { list.add(array[i]); } return list; } public static List<String> toList(final String[] array) { List<String> list = new ArrayList<String>(array.length); for (String s : array) { list.add(s); } return list; } public static <E> List<E> toList(final E[] array) { List<E> list = new ArrayList<E>(array.length); for (E e : array) { list.add(e); } return list; } /* * * Converters from Array to different TYPE of Arrays or List, signature: toTYPEArray() or toTYPEList() * */ public static <E> String[] toStringArray(final E[] array) { String[] stringList = null; if (array != null) { stringList = new String[array.length]; for (int i = 0; i < array.length; i++) { if (array[i] != null) { stringList[i] = array[i].toString(); } else { stringList[i] = null; } } } return stringList; } public static List<String> toStringList(final double[] array) { List<String> list = new ArrayList<String>(array.length); for (int i = 0; i < array.length; i++) { list.add(String.valueOf(array[i])); } return list; } public static List<String> toStringList(final int[] array) { List<String> list = new ArrayList<String>(array.length); for (int i = 0; i < array.length; i++) { list.add(String.valueOf(array[i])); } return list; } public static <E> List<String> toStringList(final E[] array) { List<String> stringList = null; if (array != null) { stringList = new ArrayList<String>(array.length); for (E e : array) { if (e != null) { stringList.add(e.toString()); } else { stringList.add(null); } } } return stringList; } public static double[] toDoubleArray(final int[] intArray) { double[] array = null; if (intArray != null) { array = new double[intArray.length]; for (int i = 0; i < intArray.length; i++) { array[i] = (double) intArray[i]; } } return array; } public static double[] toDoubleArray(final String[] array) { double[] doubleArray = null; if (array != null) { doubleArray = new double[array.length]; for (int i = 0; i < array.length; i++) { try { doubleArray[i] = Double.parseDouble(array[i]); } catch (NumberFormatException e) { doubleArray[i] = Double.NaN; } } } return doubleArray; } public static <E> double[] toDoubleArray(final E[] array) { double[] stringList = null; if (array != null) { stringList = new double[array.length]; for (int i = 0; i < array.length; i++) { if (array[i] != null) { try { stringList[i] = Double.parseDouble(array[i].toString()); } catch (NumberFormatException nfe) { stringList[i] = Double.NaN; } } else { stringList[i] = Double.NaN; } } } return stringList; } public static <E> List<Double> toDoubleList(final E[] array) { List<Double> doubleList = null; if (array != null) { doubleList = new ArrayList<Double>(array.length); for (E e : array) { if (e != null) { try { doubleList.add(Double.parseDouble(e.toString())); } catch (NumberFormatException nfe) { doubleList.add(null); } } else { doubleList.add(null); } } } return doubleList; } public static int[] toIntArray(final double[] doubleArray) { int[] dataToInt = null; if (doubleArray != null) { dataToInt = new int[doubleArray.length]; for (int i = 0; i < doubleArray.length; i++) { dataToInt[i] = (int) Math.round(doubleArray[i]); } } return dataToInt; } public static int[] toIntArray(final String[] array, int defaultValue) { int[] intArray = null; if (array != null) { intArray = new int[array.length]; for (int i = 0; i < array.length; i++) { if (array[i] != null) { try { intArray[i] = Integer.parseInt(array[i].toString()); } catch (NumberFormatException nfe) { intArray[i] = defaultValue; } } else { intArray[i] = defaultValue; } } } return intArray; } public static <E> int[] toIntArray(final E[] array, int defaultValue) { int[] stringList = null; if (array != null) { stringList = new int[array.length]; for (int i = 0; i < array.length; i++) { if (array[i] != null) { try { stringList[i] = Integer.parseInt(array[i].toString()); } catch (NumberFormatException nfe) { stringList[i] = defaultValue; } } else { stringList[i] = defaultValue; } } } return stringList; } public static <E> List<Integer> toIntegerList(final E[] array) { List<Integer> integerList = null; if (array != null) { integerList = new ArrayList<Integer>(array.length); for (E e : array) { if (e != null) { try { integerList.add(Integer.parseInt(e.toString())); } catch (NumberFormatException nfe) { integerList.add(null); } } else { integerList.add(null); } } } return integerList; } public static <E> boolean[] toBooleanArray(final E[] array) { boolean[] stringList = null; if (array != null) { stringList = new boolean[array.length]; for (int i = 0; i < array.length; i++) { if (array[i] != null) { try { stringList[i] = "true".equalsIgnoreCase(array[i].toString().trim()) || "1".equals(array[i].toString().trim()); } catch (NumberFormatException nfe) { stringList[i] = false; } } else { stringList[i] = false; } } } return stringList; } public static <E> List<Boolean> toBooleanList(final E[] array) { List<Boolean> booleanList = null; if (array != null) { booleanList = new ArrayList<Boolean>(array.length); for (E e : array) { if (e != null) { booleanList.add("true".equalsIgnoreCase(e.toString().trim()) || "1".equals(e.toString().trim())); } else { booleanList.add(false); } } } return booleanList; } /* * * toString methods * */ public static <E> String toString(final int[] list) { return toString(list, "\t"); } public static <E> String toString(final int[] list, String separator) { StringBuilder sb = new StringBuilder(); if (list != null && list.length > 0) { for (int i = 0; i < list.length - 1; i++) { sb.append(list[i]).append(separator); } sb.append(list[list.length - 1]); } return sb.toString(); } public static <E> String toString(final double[] list) { return toString(list, "\t"); } public static <E> String toString(final double[] list, String separator) { StringBuilder sb = new StringBuilder(); if (list != null && list.length > 0) { for (int i = 0; i < list.length - 1; i++) { sb.append(list[i]).append(separator); } sb.append(list[list.length - 1]); } return sb.toString(); } public static <E> String toString(final E[] list) { return toString(list, "\t"); } public static <E> String toString(final E[] list, String separator) { StringBuilder sb = new StringBuilder(); if (list != null && list.length > 0) { for (int i = 0; i < list.length - 1; i++) { if (list[i] != null) { sb.append(list[i].toString()).append(separator); } else { sb.append("null"); } } if (list[list.length - 1] != null) { sb.append(list[list.length - 1].toString()); } else { sb.append("null"); } } return sb.toString(); } /* * * private methods * */ private static boolean checkArguments(final int[] values, final int begin, final int end) { if (values == null || values.length == 0) { return false; } if (begin < 0 || end >= values.length) { return false; } return true; } private static boolean checkArguments(final double[] values, final int begin, final int end) { if (values == null || values.length == 0) { return false; } if (begin < 0 || end > values.length) { return false; } return true; } /* * * deprecated * */ @Deprecated public static <E> String[] toStringArray(final List<E> list) { String[] array = new String[list.size()]; for (int i = 0; i < list.size(); i++) { array[i] = list.get(i).toString(); } return array; } @Deprecated public static int[] toIntegerArray(final List<Integer> list) { int[] array = new int[list.size()]; for (int i = 0; i < list.size(); i++) { array[i] = list.get(i); } return array; } @Deprecated public static double[] toDoubleArray(final List<Double> list) { double[] array = new double[list.size()]; for (int i = 0; i < list.size(); i++) { array[i] = list.get(i); } return array; } }