/* * Copyright 2010-2015 Institut Pasteur. * * This file is part of Icy. * * Icy is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Icy is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Icy. If not, see <http://www.gnu.org/licenses/>. */ package icy.math; import icy.type.TypeUtil; import icy.type.collection.array.Array1DUtil; import icy.type.collection.array.ArrayUtil; /** * Class defining basic arithmetic and statistic operations on 1D double arrays. * * @author Alexandre Dufour & Stephane */ public class ArrayMath { /** * Element-wise addition of two arrays * * @param out * the array receiving the result */ public static Object add(Object a1, Object a2, Object out) { switch (ArrayUtil.getDataType(a1)) { case BYTE: return add((byte[]) a1, (byte[]) a2, (byte[]) out); case SHORT: return add((short[]) a1, (short[]) a2, (short[]) out); case INT: return add((int[]) a1, (int[]) a2, (int[]) out); case LONG: return add((long[]) a1, (long[]) a2, (long[]) out); case FLOAT: return add((float[]) a1, (float[]) a2, (float[]) out); case DOUBLE: return add((double[]) a1, (double[]) a2, (double[]) out); default: return null; } } /** * Element-wise addition of two arrays */ public static Object add(Object a1, Object a2) { return add(a1, a2, null); } /** * Element-wise addition of two double arrays (result in output if defined) * * @param out * the array receiving the result */ public static double[] add(double[] a1, double[] a2, double[] out) { final double[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] + a2[i]; return result; } /** * Element-wise addition of two double arrays */ public static double[] add(double[] a1, double[] a2) { return add(a1, a2, null); } /** * Element-wise addition of two float arrays (result in output if defined) * * @param out * the array receiving the result */ public static float[] add(float[] a1, float[] a2, float[] out) { final float[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] + a2[i]; return result; } /** * Element-wise addition of two float arrays */ public static float[] add(float[] a1, float[] a2) { return add(a1, a2, null); } /** * Element-wise addition of two long arrays (result in output if defined) * * @param out * the array receiving the result */ public static long[] add(long[] a1, long[] a2, long[] out) { final long[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] + a2[i]; return result; } /** * Element-wise addition of two long arrays */ public static long[] add(long[] a1, long[] a2) { return add(a1, a2, null); } /** * Element-wise addition of two int arrays (result in output if defined) * * @param out * the array receiving the result */ public static int[] add(int[] a1, int[] a2, int[] out) { final int[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] + a2[i]; return result; } /** * Element-wise addition of two int arrays */ public static int[] add(int[] a1, int[] a2) { return add(a1, a2, null); } /** * Element-wise addition of two short arrays (result in output if defined) * * @param out * the array receiving the result */ public static short[] add(short[] a1, short[] a2, short[] out) { final short[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = (short) (a1[i] + a2[i]); return result; } /** * Element-wise addition of two short arrays */ public static short[] add(short[] a1, short[] a2) { return add(a1, a2, null); } /** * Element-wise addition of two byte arrays (result in output if defined) * * @param out * the array receiving the result */ public static byte[] add(byte[] a1, byte[] a2, byte[] out) { final byte[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = (byte) (a1[i] + a2[i]); return result; } /** * Element-wise addition of two byte arrays */ public static byte[] add(byte[] a1, byte[] a2) { return add(a1, a2, null); } /** * Adds a value to all elements of the given array * * @param out * the array receiving the result */ public static Object add(Object array, Number value, Object out) { switch (ArrayUtil.getDataType(array)) { case BYTE: return add((byte[]) array, value.byteValue(), (byte[]) out); case SHORT: return add((short[]) array, value.shortValue(), (short[]) out); case INT: return add((int[]) array, value.intValue(), (int[]) out); case LONG: return add((long[]) array, value.longValue(), (long[]) out); case FLOAT: return add((float[]) array, value.floatValue(), (float[]) out); case DOUBLE: return add((double[]) array, value.doubleValue(), (double[]) out); default: return null; } } /** * Adds a value to all elements of the given array */ public static Object add(Object array, Number value) { return add(array, value, null); } /** * Adds a value to all elements of the given double array * * @param out * the array receiving the result */ public static double[] add(double[] array, double value, double[] out) { final double[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] + value; return result; } /** * @deprecated use {@link #add(double[] , double , double[])} instead */ @Deprecated public static double[] add(double value, double[] array, double[] out) { return add(array, value, out); } /** * Adds a value to all elements of the given double array */ public static double[] add(double[] array, double value) { return add(array, value, null); } /** * Adds a value to all elements of the given float array * * @param out * the array receiving the result */ public static float[] add(float[] array, float value, float[] out) { final float[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] + value; return result; } /** * Adds a value to all elements of the float given array */ public static float[] add(float[] array, float value) { return add(array, value, null); } /** * Adds a value to all elements of the given long array * * @param out * the array receiving the result */ public static long[] add(long[] array, long value, long[] out) { final long[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] + value; return result; } /** * Adds a value to all elements of the given long array */ public static long[] add(long[] array, long value) { return add(array, value, null); } /** * Adds a value to all elements of the given int array * * @param out * the array receiving the result */ public static int[] add(int[] array, int value, int[] out) { final int[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] + value; return result; } /** * Adds a value to all elements of the given int array */ public static int[] add(int[] array, int value) { return add(array, value, null); } /** * Adds a value to all elements of the given short array * * @param out * the array receiving the result */ public static short[] add(short[] array, short value, short[] out) { final short[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = (short) (array[i] + value); return result; } /** * Adds a value to all elements of the given short array */ public static short[] add(short[] array, short value) { return add(array, value, null); } /** * Adds a value to all elements of the given byte array * * @param out * the array receiving the result */ public static byte[] add(byte[] array, byte value, byte[] out) { final byte[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = (byte) (array[i] + value); return result; } /** * Adds a value to all elements of the given byte array */ public static byte[] add(byte[] array, byte value) { return add(array, value, null); } /** * Element-wise subtraction of two arrays * * @param out * the array receiving the result */ public static Object subtract(Object a1, Object a2, Object out) { switch (ArrayUtil.getDataType(a1)) { case BYTE: return subtract((byte[]) a1, (byte[]) a2, (byte[]) out); case SHORT: return subtract((short[]) a1, (short[]) a2, (short[]) out); case INT: return subtract((int[]) a1, (int[]) a2, (int[]) out); case LONG: return subtract((long[]) a1, (long[]) a2, (long[]) out); case FLOAT: return subtract((float[]) a1, (float[]) a2, (float[]) out); case DOUBLE: return subtract((double[]) a1, (double[]) a2, (double[]) out); default: return null; } } /** * Element-wise subtraction of two arrays */ public static Object subtract(Object a1, Object a2) { return subtract(a1, a2, null); } /** * Element-wise subtraction of two double arrays (result in output if defined) * * @param out * the array receiving the result */ public static double[] subtract(double[] a1, double[] a2, double[] out) { final double[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] - a2[i]; return result; } /** * Element-wise subtraction of two double arrays */ public static double[] subtract(double[] a1, double[] a2) { return subtract(a1, a2, null); } /** * Element-wise subtraction of two float arrays (result in output if defined) * * @param out * the array receiving the result */ public static float[] subtract(float[] a1, float[] a2, float[] out) { final float[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] - a2[i]; return result; } /** * Element-wise subtraction of two float arrays */ public static float[] subtract(float[] a1, float[] a2) { return subtract(a1, a2, null); } /** * Element-wise subtraction of two long arrays (result in output if defined) * * @param out * the array receiving the result */ public static long[] subtract(long[] a1, long[] a2, long[] out) { final long[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] - a2[i]; return result; } /** * Element-wise subtraction of two long arrays */ public static long[] subtract(long[] a1, long[] a2) { return subtract(a1, a2, null); } /** * Element-wise subtraction of two int arrays (result in output if defined) * * @param out * the array receiving the result */ public static int[] subtract(int[] a1, int[] a2, int[] out) { final int[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] - a2[i]; return result; } /** * Element-wise subtraction of two int arrays */ public static int[] subtract(int[] a1, int[] a2) { return subtract(a1, a2, null); } /** * Element-wise subtraction of two short arrays (result in output if defined) * * @param out * the array receiving the result */ public static short[] subtract(short[] a1, short[] a2, short[] out) { final short[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = (short) (a1[i] - a2[i]); return result; } /** * Element-wise subtraction of two short arrays */ public static short[] subtract(short[] a1, short[] a2) { return subtract(a1, a2, null); } /** * Element-wise subtraction of two byte arrays (result in output if defined) * * @param out * the array receiving the result */ public static byte[] subtract(byte[] a1, byte[] a2, byte[] out) { final byte[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = (byte) (a1[i] - a2[i]); return result; } /** * Element-wise subtraction of two byte arrays */ public static byte[] subtract(byte[] a1, byte[] a2) { return subtract(a1, a2, null); } /** * Subtracts a value to all elements of the given array * * @param out * the array receiving the result */ public static Object subtract(Object array, Number value, Object out) { switch (ArrayUtil.getDataType(array)) { case BYTE: return subtract((byte[]) array, value.byteValue(), (byte[]) out); case SHORT: return subtract((short[]) array, value.shortValue(), (short[]) out); case INT: return subtract((int[]) array, value.intValue(), (int[]) out); case LONG: return subtract((long[]) array, value.longValue(), (long[]) out); case FLOAT: return subtract((float[]) array, value.floatValue(), (float[]) out); case DOUBLE: return subtract((double[]) array, value.doubleValue(), (double[]) out); default: return null; } } /** * Subtracts a value to all elements of the given array */ public static Object subtract(Object array, Number value) { return subtract(array, value, null); } /** * Subtracts a value to all elements of the given double array * * @param out * the array receiving the result */ public static double[] subtract(double[] array, double value, double[] out) { final double[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] - value; return result; } /** * Subtracts a value to all elements of the given double array */ public static double[] subtract(double[] array, double value) { return subtract(array, value, null); } /** * Subtracts a value to all elements of the given float array * * @param out * the array receiving the result */ public static float[] subtract(float[] array, float value, float[] out) { final float[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] - value; return result; } /** * Subtracts a value to all elements of the float given array */ public static float[] subtract(float[] array, float value) { return subtract(array, value, null); } /** * Subtracts a value to all elements of the given long array * * @param out * the array receiving the result */ public static long[] subtract(long[] array, long value, long[] out) { final long[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] - value; return result; } /** * Subtracts a value to all elements of the given long array */ public static long[] subtract(long[] array, long value) { return subtract(array, value, null); } /** * Subtracts a value to all elements of the given int array * * @param out * the array receiving the result */ public static int[] subtract(int[] array, int value, int[] out) { final int[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] - value; return result; } /** * Subtracts a value to all elements of the given int array */ public static int[] subtract(int[] array, int value) { return subtract(array, value, null); } /** * Subtracts a value to all elements of the given short array * * @param out * the array receiving the result */ public static short[] subtract(short[] array, short value, short[] out) { final short[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = (short) (array[i] - value); return result; } /** * Subtracts a value to all elements of the given short array */ public static short[] subtract(short[] array, short value) { return subtract(array, value, null); } /** * Subtracts a value to all elements of the given byte array * * @param out * the array receiving the result */ public static byte[] subtract(byte[] array, byte value, byte[] out) { final byte[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = (byte) (array[i] - value); return result; } /** * Subtracts a value to all elements of the given byte array */ public static byte[] subtract(byte[] array, byte value) { return subtract(array, value, null); } /** * Subtracts a value by all elements of the given array * * @param out * the array receiving the result */ public static Object subtract(Number value, Object array, Object out) { switch (ArrayUtil.getDataType(array)) { case BYTE: return subtract(value.byteValue(), (byte[]) array, (byte[]) out); case SHORT: return subtract(value.shortValue(), (short[]) array, (short[]) out); case INT: return subtract(value.intValue(), (int[]) array, (int[]) out); case LONG: return subtract(value.longValue(), (long[]) array, (long[]) out); case FLOAT: return subtract(value.floatValue(), (float[]) array, (float[]) out); case DOUBLE: return subtract(value.doubleValue(), (double[]) array, (double[]) out); default: return null; } } /** * Subtracts a value by all elements of the given array */ public static Object subtract(Number value, Object array) { return subtract(value, array, null); } /** * Subtracts a value by all elements of the given double array * * @param out * the array receiving the result */ public static double[] subtract(double value, double[] array, double[] out) { final double[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = value - array[i]; return result; } /** * Subtracts a value by all elements of the given double array */ public static double[] subtract(double value, double[] array) { return subtract(array, value, null); } /** * Subtracts a value by all elements of the given float array * * @param out * the array receiving the result */ public static float[] subtract(float value, float[] array, float[] out) { final float[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = value - array[i]; return result; } /** * Subtracts a value by all elements of the float given array */ public static float[] subtract(float value, float[] array) { return subtract(array, value, null); } /** * Subtracts a value by all elements of the given long array * * @param out * the array receiving the result */ public static long[] subtract(long value, long[] array, long[] out) { final long[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = value - array[i]; return result; } /** * Subtracts a value by all elements of the given long array */ public static long[] subtract(long value, long[] array) { return subtract(array, value, null); } /** * Subtracts a value by all elements of the given int array * * @param out * the array receiving the result */ public static int[] subtract(int value, int[] array, int[] out) { final int[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = value - array[i]; return result; } /** * Subtracts a value by all elements of the given int array */ public static int[] subtract(int value, int[] array) { return subtract(array, value, null); } /** * Subtracts a value by all elements of the given short array * * @param out * the array receiving the result */ public static short[] subtract(short value, short[] array, short[] out) { final short[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = (short) (value - array[i]); return result; } /** * Subtracts a value by all elements of the given short array */ public static short[] subtract(short value, short[] array) { return subtract(array, value, null); } /** * Subtracts a value by all elements of the given byte array * * @param out * the array receiving the result */ public static byte[] subtract(byte value, byte[] array, byte[] out) { final byte[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = (byte) (value - array[i]); return result; } /** * Subtracts a value by all elements of the given byte array */ public static byte[] subtract(byte value, byte[] array) { return subtract(array, value, null); } /** * Element-wise multiplication of two arrays * * @param out * the array receiving the result */ public static Object multiply(Object a1, Object a2, Object out) { switch (ArrayUtil.getDataType(a1)) { case BYTE: return multiply((byte[]) a1, (byte[]) a2, (byte[]) out); case SHORT: return multiply((short[]) a1, (short[]) a2, (short[]) out); case INT: return multiply((int[]) a1, (int[]) a2, (int[]) out); case LONG: return multiply((long[]) a1, (long[]) a2, (long[]) out); case FLOAT: return multiply((float[]) a1, (float[]) a2, (float[]) out); case DOUBLE: return multiply((double[]) a1, (double[]) a2, (double[]) out); default: return null; } } /** * Element-wise multiplication of two arrays */ public static Object multiply(Object a1, Object a2) { return multiply(a1, a2, null); } /** * Element-wise multiplication of two double arrays (result in output if defined) * * @param out * the array receiving the result */ public static double[] multiply(double[] a1, double[] a2, double[] out) { final double[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] * a2[i]; return result; } /** * Element-wise multiplication of two double arrays */ public static double[] multiply(double[] a1, double[] a2) { return multiply(a1, a2, null); } /** * Element-wise multiplication of two float arrays (result in output if defined) * * @param out * the array receiving the result */ public static float[] multiply(float[] a1, float[] a2, float[] out) { final float[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] * a2[i]; return result; } /** * Element-wise multiplication of two float arrays */ public static float[] multiply(float[] a1, float[] a2) { return multiply(a1, a2, null); } /** * Element-wise multiplication of two long arrays (result in output if defined) * * @param out * the array receiving the result */ public static long[] multiply(long[] a1, long[] a2, long[] out) { final long[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] * a2[i]; return result; } /** * Element-wise multiplication of two long arrays */ public static long[] multiply(long[] a1, long[] a2) { return multiply(a1, a2, null); } /** * Element-wise multiplication of two int arrays (result in output if defined) * * @param out * the array receiving the result */ public static int[] multiply(int[] a1, int[] a2, int[] out) { final int[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] * a2[i]; return result; } /** * Element-wise multiplication of two int arrays */ public static int[] multiply(int[] a1, int[] a2) { return multiply(a1, a2, null); } /** * Element-wise multiplication of two short arrays (result in output if defined) * * @param out * the array receiving the result */ public static short[] multiply(short[] a1, short[] a2, short[] out) { final short[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = (short) (a1[i] * a2[i]); return result; } /** * Element-wise multiplication of two short arrays */ public static short[] multiply(short[] a1, short[] a2) { return multiply(a1, a2, null); } /** * Element-wise multiplication of two byte arrays (result in output if defined) * * @param out * the array receiving the result */ public static byte[] multiply(byte[] a1, byte[] a2, byte[] out) { final byte[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = (byte) (a1[i] * a2[i]); return result; } /** * Element-wise multiplication of two byte arrays */ public static byte[] multiply(byte[] a1, byte[] a2) { return multiply(a1, a2, null); } /** * Multiplies a value to all elements of the given array * * @param out * the array receiving the result */ public static Object multiply(Object array, Number value, Object out) { switch (ArrayUtil.getDataType(array)) { case BYTE: return multiply((byte[]) array, value.byteValue(), (byte[]) out); case SHORT: return multiply((short[]) array, value.shortValue(), (short[]) out); case INT: return multiply((int[]) array, value.intValue(), (int[]) out); case LONG: return multiply((long[]) array, value.longValue(), (long[]) out); case FLOAT: return multiply((float[]) array, value.floatValue(), (float[]) out); case DOUBLE: return multiply((double[]) array, value.doubleValue(), (double[]) out); default: return null; } } /** * Multiplies a value to all elements of the given array */ public static Object multiply(Object array, Number value) { return multiply(array, value, null); } /** * Multiplies a value to all elements of the given double array * * @param out * the array receiving the result */ public static double[] multiply(double[] array, double value, double[] out) { final double[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] * value; return result; } /** * @deprecated use {@link #multiply(double[] , double , double[])} instead */ @Deprecated public static double[] multiply(double value, double[] array, double[] out) { return multiply(array, value, out); } /** * Multiplies a value to all elements of the given double array */ public static double[] multiply(double[] array, double value) { return multiply(array, value, null); } /** * Multiplies a value to all elements of the given float array * * @param out * the array receiving the result */ public static float[] multiply(float[] array, float value, float[] out) { final float[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] * value; return result; } /** * Multiplies a value to all elements of the float given array */ public static float[] multiply(float[] array, float value) { return multiply(array, value, null); } /** * Multiplies a value to all elements of the given long array * * @param out * the array receiving the result */ public static long[] multiply(long[] array, long value, long[] out) { final long[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] * value; return result; } /** * Multiplies a value to all elements of the given long array */ public static long[] multiply(long[] array, long value) { return multiply(array, value, null); } /** * Multiplies a value to all elements of the given int array * * @param out * the array receiving the result */ public static int[] multiply(int[] array, int value, int[] out) { final int[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] * value; return result; } /** * Multiplies a value to all elements of the given int array */ public static int[] multiply(int[] array, int value) { return multiply(array, value, null); } /** * Multiplies a value to all elements of the given short array * * @param out * the array receiving the result */ public static short[] multiply(short[] array, short value, short[] out) { final short[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = (short) (array[i] * value); return result; } /** * Multiplies a value to all elements of the given short array */ public static short[] multiply(short[] array, short value) { return multiply(array, value, null); } /** * Multiplies a value to all elements of the given byte array * * @param out * the array receiving the result */ public static byte[] multiply(byte[] array, byte value, byte[] out) { final byte[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = (byte) (array[i] * value); return result; } /** * Multiplies a value to all elements of the given byte array */ public static byte[] multiply(byte[] array, byte value) { return multiply(array, value, null); } /** * Element-wise division of two arrays * * @param out * the array receiving the result */ public static Object divide(Object a1, Object a2, Object out) { switch (ArrayUtil.getDataType(a1)) { case BYTE: return divide((byte[]) a1, (byte[]) a2, (byte[]) out); case SHORT: return divide((short[]) a1, (short[]) a2, (short[]) out); case INT: return divide((int[]) a1, (int[]) a2, (int[]) out); case LONG: return divide((long[]) a1, (long[]) a2, (long[]) out); case FLOAT: return divide((float[]) a1, (float[]) a2, (float[]) out); case DOUBLE: return divide((double[]) a1, (double[]) a2, (double[]) out); default: return null; } } /** * Element-wise division of two arrays */ public static Object divide(Object a1, Object a2) { return divide(a1, a2, null); } /** * Element-wise division of two double arrays (result in output if defined) * * @param out * the array receiving the result */ public static double[] divide(double[] a1, double[] a2, double[] out) { final double[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] / a2[i]; return result; } /** * Element-wise division of two double arrays */ public static double[] divide(double[] a1, double[] a2) { return divide(a1, a2, null); } /** * Element-wise division of two float arrays (result in output if defined) * * @param out * the array receiving the result */ public static float[] divide(float[] a1, float[] a2, float[] out) { final float[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] / a2[i]; return result; } /** * Element-wise division of two float arrays */ public static float[] divide(float[] a1, float[] a2) { return divide(a1, a2, null); } /** * Element-wise division of two long arrays (result in output if defined) * * @param out * the array receiving the result */ public static long[] divide(long[] a1, long[] a2, long[] out) { final long[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] / a2[i]; return result; } /** * Element-wise division of two long arrays */ public static long[] divide(long[] a1, long[] a2) { return divide(a1, a2, null); } /** * Element-wise division of two int arrays (result in output if defined) * * @param out * the array receiving the result */ public static int[] divide(int[] a1, int[] a2, int[] out) { final int[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = a1[i] / a2[i]; return result; } /** * Element-wise division of two int arrays */ public static int[] divide(int[] a1, int[] a2) { return divide(a1, a2, null); } /** * Element-wise division of two short arrays (result in output if defined) * * @param out * the array receiving the result */ public static short[] divide(short[] a1, short[] a2, short[] out) { final short[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = (short) (a1[i] / a2[i]); return result; } /** * Element-wise division of two short arrays */ public static short[] divide(short[] a1, short[] a2) { return divide(a1, a2, null); } /** * Element-wise division of two byte arrays (result in output if defined) * * @param out * the array receiving the result */ public static byte[] divide(byte[] a1, byte[] a2, byte[] out) { final byte[] result = Array1DUtil.allocIfNull(out, a1.length); for (int i = 0; i < a1.length; i++) result[i] = (byte) (a1[i] / a2[i]); return result; } /** * Element-wise division of two byte arrays */ public static byte[] divide(byte[] a1, byte[] a2) { return divide(a1, a2, null); } /** * Divides a value to all elements of the given array * * @param out * the array receiving the result */ public static Object divide(Object array, Number value, Object out) { switch (ArrayUtil.getDataType(array)) { case BYTE: return divide((byte[]) array, value.byteValue(), (byte[]) out); case SHORT: return divide((short[]) array, value.shortValue(), (short[]) out); case INT: return divide((int[]) array, value.intValue(), (int[]) out); case LONG: return divide((long[]) array, value.longValue(), (long[]) out); case FLOAT: return divide((float[]) array, value.floatValue(), (float[]) out); case DOUBLE: return divide((double[]) array, value.doubleValue(), (double[]) out); default: return null; } } /** * Divides a value to all elements of the given array */ public static Object divide(Object array, Number value) { return divide(array, value, null); } /** * Divides a value to all elements of the given double array * * @param out * the array receiving the result */ public static double[] divide(double[] array, double value, double[] out) { final double[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] / value; return result; } /** * Divides a value to all elements of the given double array */ public static double[] divide(double[] array, double value) { return divide(array, value, null); } /** * Divides a value to all elements of the given float array * * @param out * the array receiving the result */ public static float[] divide(float[] array, float value, float[] out) { final float[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] / value; return result; } /** * Divides a value to all elements of the float given array */ public static float[] divide(float[] array, float value) { return divide(array, value, null); } /** * Divides a value to all elements of the given long array * * @param out * the array receiving the result */ public static long[] divide(long[] array, long value, long[] out) { final long[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] / value; return result; } /** * Divides a value to all elements of the given long array */ public static long[] divide(long[] array, long value) { return divide(array, value, null); } /** * Divides a value to all elements of the given int array * * @param out * the array receiving the result */ public static int[] divide(int[] array, int value, int[] out) { final int[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = array[i] / value; return result; } /** * Divides a value to all elements of the given int array */ public static int[] divide(int[] array, int value) { return divide(array, value, null); } /** * Divides a value to all elements of the given short array * * @param out * the array receiving the result */ public static short[] divide(short[] array, short value, short[] out) { final short[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = (short) (array[i] / value); return result; } /** * Divides a value to all elements of the given short array */ public static short[] divide(short[] array, short value) { return divide(array, value, null); } /** * Divides a value to all elements of the given byte array * * @param out * the array receiving the result */ public static byte[] divide(byte[] array, byte value, byte[] out) { final byte[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = (byte) (array[i] / value); return result; } /** * Divides a value to all elements of the given byte array */ public static byte[] divide(byte[] array, byte value) { return divide(array, value, null); } /** * Divides a value by all elements of the given array * * @param out * the array receiving the result */ public static Object divide(Number value, Object array, Object out) { switch (ArrayUtil.getDataType(array)) { case BYTE: return divide(value.byteValue(), (byte[]) array, (byte[]) out); case SHORT: return divide(value.shortValue(), (short[]) array, (short[]) out); case INT: return divide(value.intValue(), (int[]) array, (int[]) out); case LONG: return divide(value.longValue(), (long[]) array, (long[]) out); case FLOAT: return divide(value.floatValue(), (float[]) array, (float[]) out); case DOUBLE: return divide(value.doubleValue(), (double[]) array, (double[]) out); default: return null; } } /** * Divides a value by all elements of the given array */ public static Object divide(Number value, Object array) { return divide(value, array, null); } /** * Subtracts a value by all elements of the given double array * * @param out * the array receiving the result */ public static double[] divide(double value, double[] array, double[] out) { final double[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = value / array[i]; return result; } /** * Divides a value by all elements of the given double array */ public static double[] divide(double value, double[] array) { return divide(array, value, null); } /** * Divides a value by all elements of the given float array * * @param out * the array receiving the result */ public static float[] divide(float value, float[] array, float[] out) { final float[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = value / array[i]; return result; } /** * Divides a value by all elements of the float given array */ public static float[] divide(float value, float[] array) { return divide(array, value, null); } /** * Divides a value by all elements of the given long array * * @param out * the array receiving the result */ public static long[] divide(long value, long[] array, long[] out) { final long[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = value / array[i]; return result; } /** * Divides a value by all elements of the given long array */ public static long[] divide(long value, long[] array) { return divide(array, value, null); } /** * Divides a value by all elements of the given int array * * @param out * the array receiving the result */ public static int[] divide(int value, int[] array, int[] out) { final int[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = value / array[i]; return result; } /** * Divides a value by all elements of the given int array */ public static int[] divide(int value, int[] array) { return divide(array, value, null); } /** * Divides a value by all elements of the given short array * * @param out * the array receiving the result */ public static short[] divide(short value, short[] array, short[] out) { final short[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = (short) (value / array[i]); return result; } /** * Divides a value by all elements of the given short array */ public static short[] divide(short value, short[] array) { return divide(array, value, null); } /** * Divides a value by all elements of the given byte array * * @param out * the array receiving the result */ public static byte[] divide(byte value, byte[] array, byte[] out) { final byte[] result = Array1DUtil.allocIfNull(out, array.length); for (int i = 0; i < array.length; i++) result[i] = (byte) (value / array[i]); return result; } /** * Divides a value by all elements of the given byte array */ public static byte[] divide(byte value, byte[] array) { return divide(array, value, null); } /** * Computes the absolute value of each value of the given array * * @param overwrite * true : overwrites the input data<br> * false: returns the result in a new array */ public static Object abs(Object array, boolean overwrite) { switch (ArrayUtil.getDataType(array)) { case BYTE: return abs((byte[]) array, overwrite); case SHORT: return abs((short[]) array, overwrite); case INT: return abs((int[]) array, overwrite); case LONG: return abs((long[]) array, overwrite); case FLOAT: return abs((float[]) array, overwrite); case DOUBLE: return abs((double[]) array, overwrite); default: return null; } } /** * Computes the absolute value of each value of the given double array * * @param overwrite * true overwrites the input data, false returns the result in a new structure */ public static double[] abs(double[] input, boolean overwrite) { final double[] result = overwrite ? input : new double[input.length]; for (int i = 0; i < input.length; i++) result[i] = Math.abs(input[i]); return result; } /** * Computes the absolute value of each value of the given float array * * @param overwrite * true overwrites the input data, false returns the result in a new structure */ public static float[] abs(float[] input, boolean overwrite) { final float[] result = overwrite ? input : new float[input.length]; for (int i = 0; i < input.length; i++) result[i] = Math.abs(input[i]); return result; } /** * Computes the absolute value of each value of the given long array * * @param overwrite * true overwrites the input data, false returns the result in a new structure */ public static long[] abs(long[] input, boolean overwrite) { final long[] result = overwrite ? input : new long[input.length]; for (int i = 0; i < input.length; i++) result[i] = Math.abs(input[i]); return result; } /** * Computes the absolute value of each value of the given int array * * @param overwrite * true overwrites the input data, false returns the result in a new structure */ public static int[] abs(int[] input, boolean overwrite) { final int[] result = overwrite ? input : new int[input.length]; for (int i = 0; i < input.length; i++) result[i] = Math.abs(input[i]); return result; } /** * Computes the absolute value of each value of the given short array * * @param overwrite * true overwrites the input data, false returns the result in a new structure */ public static short[] abs(short[] input, boolean overwrite) { final short[] result = overwrite ? input : new short[input.length]; for (int i = 0; i < input.length; i++) result[i] = (short) Math.abs(input[i]); return result; } /** * Computes the absolute value of each value of the given byte array * * @param overwrite * true overwrites the input data, false returns the result in a new structure */ public static byte[] abs(byte[] input, boolean overwrite) { final byte[] result = overwrite ? input : new byte[input.length]; for (int i = 0; i < input.length; i++) result[i] = (byte) Math.abs(input[i]); return result; } /** * Find the minimum value of a generic array * * @param array * an array * @param signed * signed / unsigned flag * @return the min value of the array */ public static double min(Object array, boolean signed) { switch (ArrayUtil.getDataType(array)) { case BYTE: return min((byte[]) array, signed); case SHORT: return min((short[]) array, signed); case INT: return min((int[]) array, signed); case LONG: return min((long[]) array, signed); case FLOAT: return min((float[]) array); case DOUBLE: return min((double[]) array); default: return 0; } } /** * Find the minimum value of an array * * @param array * an array * @param signed * signed / unsigned flag * @return the min value of the array */ public static int min(byte[] array, boolean signed) { if (signed) { byte min = Byte.MAX_VALUE; for (byte v : array) if (v < min) min = v; return min; } int min = Integer.MAX_VALUE; for (int i = 0; i < array.length; i++) { final int v = TypeUtil.unsign(array[i]); if (v < min) min = v; } return min; } /** * Find the minimum value of an array * * @param array * an array * @param signed * signed / unsigned flag * @return the min value of the array */ public static int min(short[] array, boolean signed) { if (signed) { short min = Short.MAX_VALUE; for (short v : array) if (v < min) min = v; return min; } int min = Integer.MAX_VALUE; for (int i = 0; i < array.length; i++) { final int v = TypeUtil.unsign(array[i]); if (v < min) min = v; } return min; } /** * Find the minimum value of an array * * @param array * an array * @param signed * signed / unsigned flag * @return the min value of the array */ public static long min(int[] array, boolean signed) { if (signed) { int min = Integer.MAX_VALUE; for (int v : array) if (v < min) min = v; return min; } long min = Long.MAX_VALUE; for (int i = 0; i < array.length; i++) { final long v = TypeUtil.unsign(array[i]); if (v < min) min = v; } return min; } /** * Find the minimum value of an array * * @param array * an array * @param signed * signed / unsigned flag * @return the min value of the array */ public static long min(long[] array, boolean signed) { if (signed) { long min = Integer.MAX_VALUE; for (long v : array) if (v < min) min = v; return min; } double min = Long.MAX_VALUE; for (int i = 0; i < array.length; i++) { final double v = TypeUtil.unsign(array[i]); // need to compare in double if (v < min) min = v; } // convert back to long (need to be interpreted as unsigned) return TypeUtil.toLong(min); } /** * Find the minimum value of an array * * @param array * an array * @return the min value of the array */ public static float min(float[] array) { float min = Float.MAX_VALUE; for (float v : array) if (v < min) min = v; return min; } /** * Find the minimum value of an array * * @param array * an array * @return the min value of the array */ public static double min(double[] array) { double min = Double.MAX_VALUE; for (double v : array) if (v < min) min = v; return min; } /** * Find the maximum value of a generic array * * @param array * an array * @param signed * signed / unsigned flag * @return the max value of the array */ public static double max(Object array, boolean signed) { switch (ArrayUtil.getDataType(array)) { case BYTE: return max((byte[]) array, signed); case SHORT: return max((short[]) array, signed); case INT: return max((int[]) array, signed); case LONG: return max((long[]) array, signed); case FLOAT: return max((float[]) array); case DOUBLE: return max((double[]) array); default: return 0; } } /** * Find the maximum value of an array * * @param array * an array * @param signed * signed / unsigned flag * @return the max value of the array */ public static int max(byte[] array, boolean signed) { if (signed) { byte max = Byte.MIN_VALUE; for (byte v : array) if (v > max) max = v; return max; } int max = Integer.MIN_VALUE; for (int i = 0; i < array.length; i++) { final int v = TypeUtil.unsign(array[i]); if (v > max) max = v; } return max; } /** * Find the maximum value of an array * * @param array * an array * @param signed * signed / unsigned flag * @return the max value of the array */ public static int max(short[] array, boolean signed) { if (signed) { short max = Short.MIN_VALUE; for (short v : array) if (v > max) max = v; return max; } int max = Integer.MIN_VALUE; for (int i = 0; i < array.length; i++) { final int v = TypeUtil.unsign(array[i]); if (v > max) max = v; } return max; } /** * Find the maximum value of an array * * @param array * an array * @param signed * signed / unsigned flag * @return the max value of the array */ public static long max(int[] array, boolean signed) { if (signed) { int max = Integer.MIN_VALUE; for (int v : array) if (v > max) max = v; return max; } long max = Long.MIN_VALUE; for (int i = 0; i < array.length; i++) { final long v = TypeUtil.unsign(array[i]); if (v > max) max = v; } return max; } /** * Find the maximum value of an array * * @param array * an array * @param signed * signed / unsigned flag * @return the max value of the array */ public static long max(long[] array, boolean signed) { if (signed) { long max = Integer.MIN_VALUE; for (long v : array) if (v > max) max = v; return max; } double max = Long.MIN_VALUE; for (int i = 0; i < array.length; i++) { final double v = TypeUtil.unsign(array[i]); // need to compare in double if (v > max) max = v; } // convert back to long (need to be interpreted as unsigned) return TypeUtil.toLong(max); } /** * Find the maximum value of an array * * @param array * an array * @return the max value of the array */ public static float max(float[] array) { float max = -Float.MAX_VALUE; for (float v : array) if (v > max) max = v; return max; } /** * Find the maximum value of an array * * @param array * an array * @return the max value of the array */ public static double max(double[] array) { double max = -Double.MAX_VALUE; for (double v : array) if (v > max) max = v; return max; } /** * Element-wise minimum of two arrays * * @param a1 * =input1 * @param a2 * =input2 * @param output * - the array of min values */ public static void min(double[] a1, double[] a2, double[] output) { for (int i = 0; i < a1.length; i++) if (a1[i] <= a2[i]) output[i] = a1[i]; else output[i] = a2[i]; } /** * Element-wise minimum of two arrays * * @param a1 * =input1 * @param a2 * =input2 * @return the array of min values */ public static double[] min(double[] a1, double[] a2) { double[] result = new double[a1.length]; min(a1, a2, result); return result; } /** * Element-wise maximum of two arrays * * @param a1 * =input1 * @param a2 * =input2 * @param output * - the array of max values */ public static void max(double[] a1, double[] a2, double[] output) { for (int i = 0; i < a1.length; i++) if (a1[i] >= a2[i]) output[i] = a1[i]; else output[i] = a2[i]; } /** * Element-wise maximum of two arrays * * @param a1 * =input1 * @param a2 * =input2 * @return the array of max values */ public static double[] max(double[] a1, double[] a2) { double[] result = new double[a1.length]; max(a1, a2, result); return result; } /** * Reorders the given array to compute its median value * * @param input * @param preserveData * set to true if the given array should not be changed (a copy will be made) */ public static double median(double[] input, boolean preserveData) { return select(input.length / 2, preserveData ? input.clone() : input); } /** * Computes the Maximum Absolute Deviation aka MAD of the given array * * @param input * @param normalPopulation * normalizes the population by 1.4826 */ public static double mad(double[] input, boolean normalPopulation) { double[] temp = new double[input.length]; double median = median(input, true); if (normalPopulation) for (int i = 0; i < input.length; i++) temp[i] = 1.4826f * (input[i] - median); else for (int i = 0; i < input.length; i++) temp[i] = (input[i] - median); abs(temp, true); return median(temp, false); } /** * (routine ported from 'Numerical Recipes in C 2nd ed.')<br> * Computes the k-th smallest value in the input array and rearranges the array such that the * wanted value is located at data[k-1], Lower values * are stored in arbitrary order in data[0 .. k-2] Higher values will be stored in arbitrary * order in data[k .. end] * * @param k * @param data * @return the k-th smallest value in the array */ public static double select(int k, double[] data) { int i, ir, j, l, mid; double a, temp; l = 1; ir = data.length; while (true) { if (ir <= l + 1) { if (ir == l + 1 && data[ir - 1] < data[l - 1]) { temp = data[l - 1]; data[l - 1] = data[ir - 1]; data[ir - 1] = temp; } return data[k - 1]; } mid = (l + ir) >> 1; temp = data[mid - 1]; data[mid - 1] = data[l]; data[l] = temp; if (data[l] > data[ir - 1]) { temp = data[l + 1 - 1]; data[l] = data[ir - 1]; data[ir - 1] = temp; } if (data[l - 1] > data[ir - 1]) { temp = data[l - 1]; data[l - 1] = data[ir - 1]; data[ir - 1] = temp; } if (data[l] > data[l - 1]) { temp = data[l]; data[l] = data[l - 1]; data[l - 1] = temp; } i = l + 1; j = ir; a = data[l - 1]; while (true) { do i++; while (data[i - 1] < a); do j--; while (data[j - 1] > a); if (j < i) break; temp = data[i - 1]; data[i - 1] = data[j - 1]; data[j - 1] = temp; } data[l - 1] = data[j - 1]; data[j - 1] = a; if (j >= k) ir = j - 1; if (j <= k) l = i; } } /** * Computes the sum of all values from the specified input array. * * @param array * an array * @param signed * signed / unsigned flag * @return the sum of all values from the array */ public static double sum(Object array, boolean signed) { switch (ArrayUtil.getDataType(array)) { case BYTE: return sum((byte[]) array, signed); case SHORT: return sum((short[]) array, signed); case INT: return sum((int[]) array, signed); case LONG: return sum((long[]) array, signed); case FLOAT: return sum((float[]) array); case DOUBLE: return sum((double[]) array); default: return 0d; } } /** * Computes the sum of all values in the input array * * @param input * the array to sum up * @param signed * signed / unsigned flag */ public static double sum(byte[] input, boolean signed) { double sum = 0; if (signed) { for (byte b : input) sum += b; } else { for (byte b : input) sum += TypeUtil.unsign(b); } return sum; } /** * Computes the sum of all values in the input array * * @param input * the array to sum up * @param signed * signed / unsigned flag */ public static double sum(short[] input, boolean signed) { double sum = 0; if (signed) { for (short s : input) sum += s; } else { for (short s : input) sum += TypeUtil.unsign(s); } return sum; } /** * Computes the sum of all values in the input array * * @param input * the array to sum up * @param signed * signed / unsigned flag */ public static double sum(int[] input, boolean signed) { double sum = 0; if (signed) { for (int i : input) sum += i; } else { for (int i : input) sum += TypeUtil.unsign(i); } return sum; } /** * Computes the sum of all values in the input array * * @param input * the array to sum up * @param signed * signed / unsigned flag */ public static double sum(long[] input, boolean signed) { double sum = 0; if (signed) { for (long l : input) sum += l; } else { for (long l : input) sum += TypeUtil.unsign(l); } return sum; } /** * Computes the sum of all values in the input array * * @param input * the array to sum up */ public static double sum(float[] input) { double sum = 0; for (float f : input) sum += f; return sum; } /** * Computes the sum of all values in the input array * * @param input * the array to sum up */ public static double sum(double[] input) { double sum = 0; for (double d : input) sum += d; return sum; } /** * Computes the mean value of the given array * * @param input */ public static double mean(double[] input) { return sum(input) / input.length; } /** * Computes the unbiased variance of the given array * * @param input * @param unbiased * set to true if the result should be normalized by the population size minus 1 */ public static double var(double[] input, boolean unbiased) { double var = 0, mean = mean(input); for (double f : input) var += (f - mean) * (f - mean); return var / (unbiased ? input.length - 1 : input.length); } /** * Computes the standard deviation of the given array (the variance square root) * * @param input * @param unbiased * set to true if the variance should be unbiased * @return the square root of the variance */ public static double std(double[] input, boolean unbiased) { return Math.sqrt(var(input, unbiased)); } /** * Rescales the given array to [newMin,newMax]. Nothing is done if the input is constant or if * the new bounds equal the old ones. * * @param input * the input array * @param newMin * the new min bound * @param newMax * the new max bound * @param overwrite * true overwrites the input data, false returns the result in a new structure */ public static double[] rescale(double[] input, double newMin, double newMax, boolean overwrite) { double min = min(input), max = max(input); if (min == max || (min == newMin && max == newMax)) return input; double[] result = overwrite ? input : new double[input.length]; double ratio = (newMax - newMin) / (max - min); double base = newMin - (min * ratio); for (int i = 0; i < input.length; i++) result[i] = base + input[i] * ratio; return result; } /** * Standardize the input data by subtracting the mean value and dividing by the standard * deviation * * @param input * the data to standardize * @param overwrite * true if the output should overwrite the input, false if a new array should be returned * @return the standardized data */ public static double[] standardize(double[] input, boolean overwrite) { double[] output = overwrite ? input : new double[input.length]; subtract(input, mean(input), output); divide(output, std(output, true), output); return output; } /** * Computes the classical correlation coefficient between 2 populations.<br> * This coefficient is given by:<br> * * <pre> * sum(a[i] * b[i]) * r(a,b) = ------------------------------------------- * sqrt( sum(a[i] * a[i]) * sum(b[i] * b[i]) ) * </pre> * * @param a * a population * @param b * a population * @return the correlation coefficient between a and b. * @throws IllegalArgumentException * if the two input population have different sizes */ public static double correlation(double[] a, double[] b) throws IllegalArgumentException { if (a.length != b.length) throw new IllegalArgumentException("Populations must have same size"); double sum = 0, sqsum_a = 0, sqsum_b = 0; double ai, bi; for (int i = 0; i < a.length; i++) { ai = a[i]; bi = b[i]; sum += ai * bi; sqsum_a += ai * ai; sqsum_b += bi * bi; } return sum / Math.sqrt(sqsum_a * sqsum_b); } /** * Computes the Pearson correlation coefficient between two populations of same size N. <br> * This coefficient is computed by: <br> * * <pre> * sum(a[i] * b[i]) - N * mean(a) * mean(b) * r(a,b) = ---------------------------------------- * (N-1) * std(a) * std(b) * </pre> * * @param a * a population * @param b * a population * @return the Pearson correlation measure between a and b. * @throws IllegalArgumentException * if the two input population have different sizes */ public static double correlationPearson(double[] a, double[] b) throws IllegalArgumentException { if (a.length != b.length) throw new IllegalArgumentException("Populations must have same size"); double sum = 0; for (int i = 0; i < a.length; i++) sum += a[i] * b[i]; return (sum - a.length * mean(a) * mean(b)) / ((a.length - 1) * std(a, true) * std(b, true)); } }