All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.math.array.DoubleArray Maven / Gradle / Ivy

The newest version!
package org.math.array;

import org.math.array.util.Function;
import org.math.array.util.IndexFunction;
import org.math.array.util.Random;
import org.math.array.util.Sorting;

/**
 * A class for dealing with double arrays and matrices.
 * Copyright : BSD License
 *
 * @author Yann RICHET
 */

public class DoubleArray {

	public static void main(String[] args) {
		double[][] M = random(4, 3);
		System.out.println(toString(M));
		M = resize(M, 5, 6);
		System.out.println(toString(M));
	}

	// Basic Manipulation methods

	/**
	 * Adds a single value to a matrix, e.g. adds the constant value a
	 * to all element of the matrix M.
	 *
	 * @return The resulting matrix.
	 */
	public static double[][] add(double[][] M, double a) {
		for (int i = 0; i < M.length; i++)
			for (int j = 0; j < M[i].length; j++)
				M[i][j] = M[i][j] + a;
		return M;
	}

	/**
	 * Adds a matrix to another matrix, which should be of the same dimension.
	 *
	 * @return The resulting matrix.
	 */
	public static double[][] add(double[][] M1, double[][] M2) {
		if (M1.length != M2.length) {
			System.err.println("Matrices must be of the same dimension");
			return M1;
		}
		double[][] M = new double[M1.length][M1[0].length];
		for (int i = 0; i < M1.length; i++) {
			if (M1[i].length != M2[i].length) {
				System.err.println("Matrices must be of the same dimension");
				return M1;
			}
			for (int j = 0; j < M1[i].length; j++) {
				M[i][j] = M1[i][j] + M2[i][j];
			}
		}
		return M;
	}

	// Create methods

	/**
	 * Generates an m x m identity matrix. Result has ones along the diagonal
	 * and zeros everywhere else. Example:
* * double[][] id = identity(3);
* Result is:
* 1.0 0.0 0.0
* 0.0 1.0 0.0
* 0.0 0.0 1.0
*
* @param m an integer > 0. * @return m x m two dimensional array of doubles. */ public static double[][] identity(int m) { return diagonal(m, 1.0); } /** * Returns an m x m matrix. result has constants along the diagonal * and zeros everywhere else. Example:
* * double[][] eig = diagonal(3, 2.1);
* Result is:
* 2.1 0.0 0.0
* 0.0 2.1 0.0
* 0.0 0.0 2.1
*
* @param m an integer > 0. * @param c Constant that lies along diagonal. Set c=1 for identity matrix. * @return m x m 2D array of doubles. */ public static double[][] diagonal(int m, double c) { if (m < 1) throw new IllegalArgumentException("First argument must be > 0"); double[][] I = new double[m][m]; for (int i = 0; i < I.length; i++) I[i][i] = c; return I; } /** * Returns an m x m matrix. result has specified values along the diagonal * and zeros everywhere else. Example:
* * double[][] eig = diagonal(1.0,2.0,3.0);
* Result is:
* 1.0 0.0 0.0
* 0.0 2.0 0.0
* 0.0 0.0 3.0
*
* @param c Values that lies along diagonal. * @return c.length x c.length 2D array of doubles. */ public static double[][] diagonal(double... c) { double[][] I = new double[c.length][c.length]; for (int i = 0; i < I.length; i++) I[i][i] = c[i]; return I; } /** * Provides an m x n matrix filled with ones. * @param m Number of rows in returned matrix * @param n Number of columns in returned matrix * @return m x n 2D array of ones * @deprecated use fill(int m, int n, 1.0) instead. */ public static double[][] one(int m, int n) { return fill(m, n, 1.0); } /** * Provides an mxn matrix filled with constant c * @param m Number of rows in returned matrix * @param n Number of columns in returned matrix * @param c Constant that fills matrix * @return m x n 2D array of constants * @deprecated use fill(int m, int n, double c) instead. */ public static double[][] one(int m, int n, double c) { return fill(m, n, c); } /** * Provides an m element array filled with ones * @param m Number of elements in returned array * @return m element array of ones * @deprecated use fill(int m, double c) instead. */ public static double[] one(int m) { return fill(m, 1.0); } /** * Provides an m element array filled with constant c * @param m Number of elements in returned array * @param c Constant that fills array * @return m element array of constants * @deprecated Use fill(int m, double c) instead. */ public static double[] one(int m, double c) { return fill(m, c); } // The fill methods are included so we can have equivalent methods in IntegerArray. // There are ambiguities between DoubleArray and IntegerArray if we try to implement // equivalent versions of the one() methods in both. the fill() methods are delineated // by the type of the fill constant. I wish I could get rid of one(m,n,c) and one(m,c) // but they are legacy code now. /** * Fills an m x n matrix of doubles with constant c. Example:
* * double[][] u = fill(2, 3, 1.0);
* Result is:
* 1.0 1.0 1.0
* 1.0 1.0 1.0
*
* @param m Number of rows in matrix * @param n Number of columns in matrix * @param c constant that fills matrix * @return m x n 2D array of constants c */ public static double[][] fill(int m, int n, double c) { double[][] o = new double[m][n]; for (int i = 0; i < o.length; i++) for (int j = 0; j < o[i].length; j++) o[i][j] = c; return o; } /** * Provides an m element array filled with constant c. Example:
* * double[] u = fill(3, 1.0);
* Result is:
* 1.0 1.0 1.0
*
* @param m Number of elements in returned array * @param c Constant that fills array * @return m element array of constants */ public static double[] fill(int m, double c) { double[] o = new double[m]; for (int i = 0; i < o.length; i++) o[i] = c; return o; } /** * Generates an m x n matrix of random numbers uniformly distributed * between 0 and 1. * @param m Number of rows in matrix * @param n Number of columns in matrix * @return 2D array of random numbers. */ public static double[][] random(int m, int n) { double[][] array = new double[m][n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { array[i][j] = Random.raw(); } } return array; } /** * Generates an m element array of random numbers uniformly distributed between 0 and 1. * @param m Size of array * @return Array of random numbers. */ public static double[] random(int m) { double[] array = new double[m]; for (int i = 0; i < m; i++) { array[i] = Random.raw(); } return array; } /** * Generates an mxn matrix of random numbers uniformly distributed between min and max. * @param m Number of rows in matrix * @param n Number of columns in matrix * @param min minimum value of the random numbers * @param max maximum value of the random numbers * @return 2D array of random numbers. */ public static double[][] random(int m, int n, double min, double max) { double[][] array = new double[m][n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { array[i][j] = min + Random.raw() * (max - min); } } return array; } /** * Generates an m element array of random numbers uniformly distributed between min and max. * @param m Size of array * @param min minimum value of the random numbers * @param max maximum value of the random numbers * @return Array of random numbers. */ public static double[] random(int m, double min, double max) { double[] array = new double[m]; for (int i = 0; i < m; i++) { array[i] = min + Random.raw() * (max - min); } return array; } /** * Generates an m x n matrix of random numbers uniformly distributed numbers. * The bounds of the random numbers each column are in the arrays min and max. * So the values in column j are uniformly distributed random numbers between min[j] and max[j] * @param m Number of rows in matrix * @param n Number of columns in matrix * @param min minimum value of the random numbers in a column * @param max maximum value of the random numbers in a column * @return 2D array of random numbers. */ public static double[][] random(int m, int n, double[] min, double[] max) { double[][] array = new double[m][n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { array[i][j] = min[j] + Random.raw() * (max[j] - min[j]); } } return array; } /** * Provides an mxn matrix. Each column is a sequence of successive values of stepsize * pitch and starts at begin. The columns are all identical. * @param m Number of rows in matrix * @param n Number of columns in matrix * @param begin First value in sequence * @param pitch Step size of sequence * @return m x n 2D array */ public static double[][] increment(int m, int n, double begin, double pitch) { double[][] array = new double[m][n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { array[i][j] = begin + i * pitch; } } return array; } /** * Provides a sequence of successive values in an array. e.g. increment(4, 3, 2) = {3,5,7,9} * @param m Size of array * @param begin Starting value * @param pitch Step size * @return m point array. Sequence of values from begin to begin + (m-1)*pitch */ public static double[] increment(int m, double begin, double pitch) { double[] array = new double[m]; for (int i = 0; i < m; i++) { array[i] = begin + i * pitch; } return array; } /** * Generates an mxn matrix. Each column is a sequence of succesive values. Each column * has it's own starting value and step size. * @param m Number of rows in matrix * @param n Number of columns in matrix * @param begin Array of starting values for each column. length must = n. * @param pitch Array of step sizes for each column. length must = n. * @return 2D array */ public static double[][] increment(int m, int n, double[] begin, double[] pitch) { if (begin.length != n || pitch.length != n) throw new IllegalArgumentException("Length of 3rd and 4th arguments must = second argument"); double[][] array = new double[m][n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { array[i][j] = begin[j] + i * pitch[j]; } } return array; } /** * Generates an array of successive values from begin to end with step * size pitch. * @param begin First value in sequence * @param pitch Step size of sequence * @param end Last value of sequence * @return Array of successive values */ public static double[] increment(double begin, double pitch, double end) { double[] array = new double[(int) ((end - begin) / pitch)]; for (int i = 0; i < array.length; i++) { array[i] = begin + i * pitch; } return array; } // Modify rows & columns methods /** * Generate a copy of an array * @param M Input array. * @return A copy of the input array. */ public static double[] copy(double[] M) { double[] array = new double[M.length]; System.arraycopy(M, 0, array, 0, M.length); return array; } /** * Generate a copy of a matrix * @param M Input matrix. * @return A copy of the input matrix */ public static double[][] copy(double[][] M) { double[][] array = new double[M.length][M[0].length]; for (int i = 0; i < array.length; i++) System.arraycopy(M[i], 0, array[i], 0, M[i].length); return array; } /** * Generate a resized copy of a matrix * @param M Input matrix. * @param m number of rows of new matrix. * @param n number of columns of new matrix. * @return A resized copy of the input matrix */ public static double[][] resize(double[][] M, int m, int n) { double[][] array = new double[m][n]; for (int i = 0; i < Math.min(M.length, m); i++) System.arraycopy(M[i], 0, array[i], 0, Math.min(M[i].length, n)); return array; } /** * Carve out a submatrix from the input matrix and return a copy. * Result is the intersection of rows i1 through i2 * and columns j1 through j2 inclusive. Example:
* * double[][] a = {{0,1,2,3,4},{1,7,8,9,10},{2,13,14,15,16},{3,19,20,21,22},{4,25,26,27,28}};
* double[][] b = getSubMatrixRangeCopy(a, 2, 3, 1, 3);
* input is:
* 0 1 2 3 4
* 1 7 8 9 10
* 2 13 14 15 16
* 3 19 20 21 22
* 4 25 26 27 28
* result is:
* 13 14 15
* 19 20 21
*
* @param M Input matrix * @param i1 Index of first row in cut * @param i2 Index of last row in cut * @param j1 Index of first column in cut * @param j2 Index of last column in cut * @return submatrix. Input matrix is left unharmed. */ public static double[][] getSubMatrixRangeCopy(double[][] M, int i1, int i2, int j1, int j2) { double[][] array = new double[i2 - i1 + 1][j2 - j1 + 1]; for (int i = 0; i < i2 - i1 + 1; i++) System.arraycopy(M[i + i1], j1, array[i], 0, j2 - j1 + 1); return array; } /** * Extract a range of columns from a matrix. * Example:
* * double[][] a = {{0,1,2,3,4},{1,7,8,9,10},{2,13,14,15,16},{3,19,20,21,22},{4,25,26,27,28}};
* double[][] z = getColumnsRangeCopy(a, 2, 4);
* input is:
* 0 1 2 3 4
* 1 7 8 9 10
* 2 13 14 15 16
* 3 19 20 21 22
* 4 25 26 27 28
* result is:
* 2 3 4
* 8 9 10
* 14 15 16
* 20 21 22
* 26 27 28
*
* @param M Input matrix * @param j1 Index of first column to be extracted. * @param j2 Index of last column to be extracted. * @return An mxn matrix where m=number of rows in M and n=j2-j1+1 */ public static double[][] getColumnsRangeCopy(double[][] M, int j1, int j2) { double[][] array = new double[M.length][j2 - j1 + 1]; for (int i = 0; i < M.length; i++) System.arraycopy(M[i], j1, array[i], 0, j2 - j1 + 1); return array; } /** * Extract specific columns from a matrix. * Example:
* * double[][] a = {{0,1,2,3,4},{1,7,8,9,10},{2,13,14,15,16},{3,19,20,21,22},{4,25,26,27,28}};
* double[][] z = getColumnsCopy(a, 2, 4);
* input is:
* 0 1 2 3 4
* 1 7 8 9 10
* 2 13 14 15 16
* 3 19 20 21 22
* 4 25 26 27 28
* result is:
* 0 2 4
* 1 8 10
* 2 14 16
* 3 20 22
* 4 26 28
*
* @param M Input matrix * @param J Each is the index of a column. There can be as many indices listed as there are columns in M. * @return An mxn matrix where m=number of rows in M and n=number of indices listed */ public static double[][] getColumnsCopy(double[][] M, int... J) { double[][] array = new double[M.length][J.length]; for (int i = 0; i < M.length; i++) for (int j = 0; j < J.length; j++) array[i][j] = M[i][J[j]]; return array; } /** * Extract one column from a matrix. * * Example:
* * double[][] a = {{0,1,2,3,4},{1,7,8,9,10},{2,13,14,15,16},{3,19,20,21,22},{4,25,26,27,28}};
* double[][] z = getColumnCopy(a, 2);
* input is:
* 0 1 2 3 4
* 1 7 8 9 10
* 2 13 14 15 16
* 3 19 20 21 22
* 4 25 26 27 28
* Result is:
* 2 8 14 20 26
*
* @param M Input matrix * @param j Index of desired column * @return Array of values from extracted column. */ public static double[] getColumnCopy(double[][] M, int j) { double[] array = new double[M.length]; for (int i = 0; i < M.length; i++) array[i] = M[i][j]; return array; } /** * Extract one column from a three dimensional array. The result is an array of the * values in the first dimension. * @param M Input 3D array * @param j The index of the second dimension. * @param k The index of the third dimension * @return An array */ public static double[] getColumnCopy(double[][][] M, int j, int k) { double[] array = new double[M.length]; for (int i = 0; i < M.length; i++) array[i] = M[i][j][k]; return array; } /** * Extract specific rows from a matrix. * Example:
* * double[][] a = {{0,1,2,3,4},{1,7,8,9,10},{2,13,14,15,16},{3,19,20,21,22},{4,25,26,27,28}};
* double[][] z = getRowsCopy(a, 2, 4);
* input is:
* 0 1 2 3 4
* 1 7 8 9 10
* 2 13 14 15 16
* 3 19 20 21 22
* 4 25 26 27 28
* result is:
* 2 13 14 15 16
* 4 25 26 27 28
*
* @param M Input matrix * @param I Each is the index of a column. * @return An mxn matrix where m=number of indices listed and n=number of columns in m */ public static double[][] getRowsCopy(double[][] M, int... I) { double[][] array = new double[I.length][M[0].length]; for (int i = 0; i < I.length; i++) System.arraycopy(M[I[i]], 0, array[i], 0, M[I[i]].length); return array; } /** * Extract a row from a matrix. * Example:
* * double[][] a = {{0,1,2,3,4},{1,7,8,9,10},{2,13,14,15,16},{3,19,20,21,22},{4,25,26,27,28}};
* double[] z = getRowCopy(a, 2);
* input is:
* 0 1 2 3 4
* 1 7 8 9 10
* 2 13 14 15 16
* 3 19 20 21 22
* 4 25 26 27 28
* result is:
* 2 13 14 15 16
*
* @param M Input matrix * @param i index of row to copy * @return An array of n values where n = number of columns in M */ public static double[] getRowCopy(double[][] M, int i) { double[] array = new double[M[0].length]; System.arraycopy(M[i], 0, array, 0, M[i].length); return array; } /** * Extract a range of rows from a matrix. * Example:
* * double[][] a = {{0,1,2,3,4},{1,7,8,9,10},{2,13,14,15,16},{3,19,20,21,22},{4,25,26,27,28}};
* double[][] z = getRowsRangeCopy(a, 2, 4);
* input is:
* 0 1 2 3 4
* 1 7 8 9 10
* 2 13 14 15 16
* 3 19 20 21 22
* 4 25 26 27 28
* result is:
* 2 13 14 15 16
* 3 19 20 21 22
* 4 25 26 27 28
*
* @param M Input matrix * @param i1 Index of first row to be extracted. * @param i2 Index of last row to be extracted. * @return An mxn matrix where m=j2-j1+1 and n=number of columns in M */ public static double[][] getRowsRangeCopy(double[][] M, int i1, int i2) { double[][] array = new double[i2 - i1 + 1][M[0].length]; for (int i = 0; i < i2 - i1 + 1; i++) System.arraycopy(M[i + i1], 0, array[i], 0, M[i + i1].length); return array; } /** * Extract a section of an array. * Example:
* * double[] a = {00,11,22,33,44,55,66,77,88,99};
* double[] z = getRangeCopy(a, 2, 5);
* result is:
* 22 33 44 55
*
* @param M Input array * @param j1 Index of first term to get * @param j2 Index of last term to get * @return An array with j2-j1+1 elements */ public static double[] getRangeCopy(double[] M, int j1, int j2) { double[] array = new double[j2 - j1 + 1]; System.arraycopy(M, j1, array, 0, j2 - j1 + 1); return array; } /** * Extract specific elements from an array. * Example: *
* * double[] a = {00,11,22,33,44,55,66,77,88,99};
* double[] z = getCopy(a, 2, 5);
* result is:
* 22 55
*
* @param M The input array. * @param I the indices of the elements to extract * @return The output array of n elements where n=number of indices listed. */ public static double[] getCopy(double[] M, int... I) { double[] array = new double[I.length]; for (int i = 0; i < I.length; i++) array[i] = M[I[i]]; return array; } /** * Get the number of columns in a specified row of a matrix. Used for oddly sized matrices. * @param M Input matrix * @param i Index of row whose column length will be returned * @return The number of columns in row i */ public static int getColumnDimension(double[][] M, int i) { return M[i].length; } /** * Extract diagonal from a matrix. * Example:
* * double[][] a = {{0,1,2,3,4},{1,7,8,9,10},{2,13,14,15,16},{3,19,20,21,22},{4,25,26,27,28}};
* double[] z = getDiagonal(a, 1);
* input is:
* 0 1 2 3 4
* 1 7 8 9 10
* 2 13 14 15 16
* 3 19 20 21 22
* 4 25 26 27 28
* result is:
* 1 8 15 22
*
* @param M Input matrix * @param I index of diagonal to copy * @return An array */ public static double[] getDiagonal(double[][] M, int I) { int nr = M.length, nc = M.length; int nd = 0; if (nc < nr) { if (I >= 0) { nd = nc - I; } else if (I < (nc - nr)) { nd = nr + I; } else { nd = nc; } } else { if (I <= 0) { nd = nr + I; } else if (I > (nc - nr)) { nd = nc - I; } else { nd = nr; } } double[] d = new double[nd]; for (int i = 0; i < d.length; i++) d[i] = M[i + I][i + I]; return d; } /** * Combine a set of arrays into a matrix. Each array becomes a row. Rows may be of different lengths. * Example:
* * double[] a = {00,11,22,33,44}, b = {55,66,77,88}; * double[][] z = mergeRows(a, b); * result is:
* 0 11 22 33 44 * 55 66 77 88 *
* @param x Input arrays * @return A matrix. Will be non-rectangular if arrays are not all the same length. */ public static double[][] mergeRows(double[]... x) { double[][] array = new double[x.length][]; for (int i = 0; i < array.length; i++) { array[i] = new double[x[i].length]; System.arraycopy(x[i], 0, array[i], 0, array[i].length); } return array; } /** * Combine a set of arrays into a matrix. Each array becomes a column. Arrays must all be of same length. * Example:
* * double[] a = {00,11,22,33,44}, b = {55,66,77,88,99}; * double[][] z = mergeColumns(a, b); * result is:
* 0 55 * 11 66 * 22 77 * 33 88 * 44 99 *
* @param x Input arrays * @return An mxn matrix where m=size of any input array and n is the number of arrays. */ public static double[][] mergeColumns(double[]... x) { double[][] array = new double[x[0].length][x.length]; for (int i = 0; i < array.length; i++) for (int j = 0; j < array[i].length; j++) array[i][j] = x[j][i]; return array; } /** * Converts an n element array into an n x 1 matrix. Handy for matrix math. * @param x n element array * @return n x 1 matrix */ public static double[][] columnVector(double[] x) { return mergeColumns(x); } /** * Converts an n element array into an 1 x n matrix. Handy for matrix math. * @param x n element array * @return 1 x n matrix */ public static double[][] rowVector(double[] x) { return mergeRows(x); } /** * Concatenates arrays. * Example:
* * double[] a = {00,11,22,33,44}, b = {55,66,77,88,99};
* double[] z = merge(a, b, a);
* result is:
* 0 11 22 33 44 55 66 77 88 99 0 11 22 33 44 *
* @param x Input arrays * @return Output array. */ public static double[] merge(double[]... x) { int[] xlength_array = new int[x.length]; xlength_array[0] = x[0].length; for (int i = 1; i < x.length; i++) xlength_array[i] = x[i].length + xlength_array[i - 1]; double[] array = new double[xlength_array[x.length - 1]]; System.arraycopy(x[0], 0, array, 0, x[0].length); for (int i = 1; i < x.length; i++) System.arraycopy(x[i], 0, array, xlength_array[i - 1], x[i].length); return array; } // I didn't favor this insertColumns method because it was so different from insertRows() // and it just seemed more likely that someone would want to insert arrays rather than // whole matrices. See the new version below. /* public static double[][] insertColumns(double[][] x, int J, double[]... y) { double[][] array = new double[x.length][x[0].length + y[0].length]; System.out.println("y[0].length="+y[0].length); for (int i = 0; i < array.length; i++) { System.out.println(tostring("%3.0f",array)+"\n"); System.arraycopy(x[i], 0, array[i], 0, J); System.arraycopy(y[i], 0, array[i], J, y[i].length); System.arraycopy(x[i], J, array[i], J + y[i].length, x[i].length - J); } return array; } */ /** * Insert any number of arrays between 2 columns of a matrix. Size of the arrays must * equal number of rows in the matrix. * Example:
* * double[][] a = {{0,1,2,3,4},{1,7,8,9,10},{2,13,14,15,16},{3,19,20,21,22},{4,23,24,25,26}};
* double[] b = {00,11,22,33,44}, c = {55,66,77,88,99};
* double[][] z = insertColumns(a, 2, b, c);
* input matrix is:
* 0 1 2 3 4
* 1 7 8 9 10
* 2 13 14 15 16
* 3 19 20 21 22
* 4 23 24 25 26
* result is:
* 0 1 0 55 2 3 4
* 1 7 11 66 8 9 10
* 2 13 22 77 14 15 16
* 3 19 33 88 20 21 22
* 4 23 44 99 24 25 26
*
* @param x Input m x n matrix. * @param J Index of column before which the new columns will be inserted. * @param y The arrays to be inserted * @return New matrix with added columns. */ public static double[][] insertColumns(double[][] x, int J, double[]... y) { return transpose(insertRows(transpose(x), J, y)); } /*public static double[][] insertColumn(double[][] x, double[] y, int J) { double[][] array = new double[x.length][x[0].length + 1]; for (int i = 0; i < array.length; i++) { System.arraycopy(x[i], 0, array[i], 0, J); array[i][J] = y[i]; System.arraycopy(x[i], J, array[i], J + 1, x[i].length - J); } return array; }*/ /** * Insert any number of arrays between 2 rows of a matrix. Size of the arrays must * equal number of columns in the matrix. * Example:
* * double[][] a = {{0,1,2,3,4},{1,7,8,9,10},{2,13,14,15,16},{3,19,20,21,22}};
* double[] b = {0,11,22,33,44}, c = {55,66,77,88,99};
* double[][] z = insertRows(a, 1, b, c);
* result is:
* 0 1 2 3 4
* 0 11 22 33 44
* 55 66 77 88 99
* 1 7 8 9 10
* 2 13 14 15 16
* 3 19 20 21 22
*
* @param x Input m x n matrix. * @param I Index of row before which the new rows will be inserted. * @param y The arrays to be inserted * @return New matrix with added rows. */ public static double[][] insertRows(double[][] x, int I, double[]... y) { double[][] array = new double[x.length + y.length][x[0].length]; for (int i = 0; i < I; i++) System.arraycopy(x[i], 0, array[i], 0, x[i].length); for (int i = 0; i < y.length; i++) System.arraycopy(y[i], 0, array[i + I], 0, y[i].length); for (int i = 0; i < x.length - I; i++) System.arraycopy(x[i + I], 0, array[i + I + y.length], 0, x[i].length); return array; } /*public static double[][] insertRow(double[][] x, double[] y, int I) { double[][] array = new double[x.length + 1][x[0].length]; for (int i = 0; i < I; i++) System.arraycopy(x[i], 0, array[i], 0, x[i].length); System.arraycopy(y, 0, array[I], 0, y.length); for (int i = 0; i < x.length - I; i++) System.arraycopy(x[i + I], 0, array[i + I + 1], 0, x[i].length); return array; }*/ /** * Insert any number of values, or a single array, between 2 elements of an array. * Example:
* * double[] b = {00,11,22,33,44}, c = {55,66,77,88,99};
* double[] z = insert(b, 2, 333, 444);
* result is:
* 0 11 333 444 22 33 44 * double[] z = insert(b, 2, c);
* result is:
* 0 11 55 66 77 88 99 22 33 44
*
* @param x Input array. * @param I Index of element before which the values will be inserted. * @param y Values to be inserted. Can also be a single array. * @return Expanded array. */ public static double[] insert(double[] x, int I, double... y) { double[] array = new double[x.length + y.length]; System.arraycopy(x, 0, array, 0, I); System.arraycopy(y, 0, array, I, y.length); System.arraycopy(x, I, array, I + y.length, x.length - I); return array; } /** * Deletes a range of columns from a matrix. * Example:
* * double[][] a = {{0,1,2,3,4},{1,7,8,9,10},{2,13,14,15,16},{3,19,20,21,22},{4,23,24,25,26}};
* double[][] z = deleteColumnsRange(a, 1, 3);
* result is:
* 0 4
* 1 10
* 2 16
* 3 22
* 4 26
*
* @param x The input matrix * @param J1 The Index of the first column to delete. * @param J2 The index of the last column to delete. * @return The reduced matrix. */ public static double[][] deleteColumnsRange(double[][] x, int J1, int J2) { double[][] array = new double[x.length][x[0].length - (J2 - J1 + 1)]; for (int i = 0; i < array.length; i++) { System.arraycopy(x[i], 0, array[i], 0, J1); //if (J2 * * double[][] a = {{0,1,2,3,4},{1,7,8,9,10},{2,13,14,15,16},{3,19,20,21,22},{4,23,24,25,26}};
* double[][] z = deleteColumns(a, 1, 3);
* result is:
* 0 2 4
* 1 8 10
* 2 14 16
* 3 20 22
* 4 24 26
*
* @param x The input matrix * @param J The indices of the columns to be deleted. There must be no more indices listed * than there are columns in the input matrix. * @return The reduced matrix. */ public static double[][] deleteColumns(double[][] x, int... J) { /*double[][] array = new double[x.length][x[0].length - J.length]; for (int i = 0; i < array.length; i++) { System.arraycopy(x[i], 0, array[i], 0, J[0]); for (int j = 0; j < J.length - 1; j++) System.arraycopy(x[i], J[j] + 1, array[i], J[j] - j, J[j + 1] - J[j] - 1); System.arraycopy(x[i], J[J.length - 1] + 1, array[i], J[J.length - 1] - J.length + 1, x[i].length - J[J.length - 1] - 1); } return array;*/ // TODO improve efficiency here return transpose(deleteRows(transpose(x), J)); } /** * Deletes a range of rows from a matrix. * Example:
* * double[][] a = {{0,1,2,3,4},{1,7,8,9,10},{2,13,14,15,16},{3,19,20,21,22},{4,23,24,25,26}};
* double[][] z = deleteRowsRange(a, 1, 3);
* result is:
* 0 1 2 3 4
* 4 23 24 25 26
*
* @param x The input matrix * @param I1 The Index of the first row to delete. * @param I2 The index of the last row to delete. * @return The reduced matrix. */ public static double[][] deleteRowsRange(double[][] x, int I1, int I2) { double[][] array = new double[x.length - (I2 - I1 + 1)][x[0].length]; for (int i = 0; i < I1; i++) System.arraycopy(x[i], 0, array[i], 0, x[i].length); for (int i = 0; i < x.length - I2 - 1; i++) System.arraycopy(x[i + I2 + 1], 0, array[i + I1], 0, x[i].length); return array; } /** * Deletes a list of rows from a matrix. * Example:
* * double[][] a = {{0,1,2,3,4},{1,7,8,9,10},{2,13,14,15,16},{3,19,20,21,22},{4,23,24,25,26}};
* double[][] z = deleteRows(a, 1, 3);
* result is:
* 0 1 2 3 4
* 2 13 14 15 16
* 4 23 24 25 26
*
* @param x The input matrix * @param I The indices of the rows to delete. * @return The reduced matrix. */ public static double[][] deleteRows(double[][] x, int... I) { double[][] array = new double[x.length - I.length][x[0].length]; int i2 = 0; for (int i = 0; i < x.length; i++) { if (!into(i, I)) { System.arraycopy(x[i], 0, array[i2], 0, x[i].length); i2++; } } /*for (int i = 0; i < I[0]; i++) System.arraycopy(x[i], 0, array[i], 0, x[i].length); for (int j = 0; j < I.length - 1; j++) for (int i = I[j] + 1; i < I[j + 1]; i++) System.arraycopy(x[i], 0, array[i - j], 0, x[i].length); for (int i = I[I.length - 1] + 1; i < x.length; i++) System.arraycopy(x[i], 0, array[i - I.length], 0, x[i].length);*/ return array; } /** * Delete a range of elements from an array. * Example:
* * double[] b = {00,11,22,33,44};
* double[] z = deleteRange(b, 1, 3);
* Result is:
* 0 44
*
* @param x Input array * @param J1 Index of first element to delete. Must be > = 0 and < = x.length * @param J2 Index of last element to delete. Must be > = J1 and < = x.length * @return Reduced array. */ public static double[] deleteRange(double[] x, int J1, int J2) { double[] array = new double[x.length - (J2 - J1 + 1)]; System.arraycopy(x, 0, array, 0, J1); //if (J2 * * double[] b = {00,11,22,33,44};
* double[] z = deleteRange(b, 1, 3);
* Result is:
* 0 22 44
*
* @param x Input array * @param J Index of elements to delete. Each must be > = 0 and < = x.length * @return Reduced array. */ public static double[] delete(double[] x, int... J) { double[] array = new double[x.length - J.length]; int j2 = 0; for (int j = 0; j < x.length; j++) { if (!into(j, J)) { array[j2] = x[j]; j2++; } } /*System.arraycopy(x, 0, array, 0, J[0]); for (int j = 0; j < J.length - 1; j++) System.arraycopy(x, J[j] + 1, array, J[j] - j, J[j + 1] - J[j] - 1); System.arraycopy(x, J[J.length - 1] + 1, array, J[J.length - 1] - J.length + 1, x.length - J[J.length - 1] - 1);*/ return array; } /** * Determines if a value is within an array * @param i Value to be searched for. * @param I array to be searched * @return true if found. fales if not. */ private static boolean into(int i, int[] I) { boolean in = false; for (int j = 0; j < I.length; j++) { in = in || (i == I[j]); } return in; } /** * Generate a two column matrix. Second column is just the values in Y * The first column is a uniform sequence of values from Xmin to Xmax. Step size * is automatic. Useful for generating values for an x axis when y is already * defined and bundling the pairs into a matrix. * Example:
* * double[] y = {0.0, 1.0, 4.0, 9.0, 16.0};
* double[][] xy = buildXY(0.0, 4.0, y);
* * result:
* 0.0 0.0
* 1.0 1.0
* 2.0 4.0
* 3.0 9.0
* 4.0 16.0
*
* * @param Xmin The first value in the first column * @param Xmax The last value in the first column * @param Y An array that will fill the second column. * @return nx2 array of values where n = length of y. * @throws IllegalArgumentException */ public static double[][] buildXY(double Xmin, double Xmax, double[] Y) { if (Xmax < Xmin) throw new IllegalArgumentException("First argument must be less than second"); int n = Y.length; double[][] XY = new double[n][2]; for (int i = 0; i < n; i++) { XY[i][0] = Xmin + (Xmax - Xmin) * (double) i / (double) (n - 1); XY[i][1] = Y[i]; } return XY; } /** * Join two arrays into a matrix. Each array becomes a column in the matrix. * Example:
* * double[] x = {0,1,2};
* double[] y = {1,7,8};
* double[][] z = buildXY(x, y);
* result is:
* 0 1
* 1 7
* 2 8
*
* @see #mergeColumns(double[][]) */ public static double[][] buildXY(double[] X, double[] Y) { return mergeColumns(X, Y); } // min/max methods /** * Finds the minimum value in each column of a matrix. * Example:
* * double[][] a = {{0, 1, 2, 3, 4},
* {1, .7, 8, 9, 10},
* {2, 13, 1.4, 1.5, 16},
* {3, 19, 20, 21, 22},
* {4, 23, 24, 25, 2.6}};
* double[] z = min(a);
* Result is:
* 0.0 0.7 1.4 1.5 2.6
*
* @param M The input matrix * @return Array of minimums from each column of M. */ public static double[] min(double[][] M) { double[] min = new double[M[0].length]; for (int j = 0; j < min.length; j++) { min[j] = M[0][j]; for (int i = 1; i < M.length; i++) min[j] = Math.min(min[j], M[i][j]); } return min; } /** * Finds minimum value in either a list of numbers or a single array. * @param M Can be a list of values e.g. min(1,22,333,.4) or an array. * @return The minimum value. */ public static double min(double... M) { double min = M[0]; for (int i = 1; i < M.length; i++) min = Math.min(min, M[i]); return min; } /** * Finds the maximum value in each column of a matrix. * Example:
* * double[][] a = {{0, 1, 2, 3, 4},
* {1, 7, 88, 9, 10},
* {2, 13, 14, 15, 16},
* {3, 19, 20, 201, 22},
* {4, 23, 24, 25, 26}};
* double[] z = max(a);
* Result is:
* 4 23 88 201 26
*
* @param M The input matrix * @return Array of maximums from each column of M. */ public static double[] max(double[][] M) { double[] max = new double[M[0].length]; for (int j = 0; j < max.length; j++) { max[j] = M[0][j]; for (int i = 1; i < M.length; i++) max[j] = Math.max(max[j], M[i][j]); } return max; } /** * Finds maximum value in either a list of numbers or a single array. * @param M Can be a list of values e.g. min(1,22,333,.4) or an array. * @return The maximum value. */ public static double max(double... M) { double max = M[0]; for (int i = 1; i < M.length; i++) max = Math.max(max, M[i]); return max; } /** * Finds the indices of the minimum values in each column of a matrix. * Example:
* * double[][] a = {{0, 1, 2, 3, 4},
* {1, .7, 8, 9, 10},
* {2, 13, 1.4, 1.5, 16},
* {3, 19, 20, 21, 22},
* {4, 23, 24, 25, 2.6}};
* int[] z = minIndex(a);
* Result is:
* 0 1 2 2 4
*
* @param M Input matrix. * @return Array of indices of the minimums from each column of M. */ public static int[] minIndex(double[][] M) { int[] minI = new int[M[0].length]; for (int j = 0; j < minI.length; j++) { minI[j] = 0; for (int i = 1; i < M.length; i++) if (M[i][j] < M[minI[j]][j]) minI[j] = i; } return minI; } /** * Finds the index of the minumum value in a list of values or an array. * @param M Can be a list of values e.g. minIndex(11,22,44,2) or an array * @return index of minimum value in M */ public static int minIndex(double... M) { int minI = 0; for (int i = 1; i < M.length; i++) if (M[i] < M[minI]) minI = i; return minI; } /** * Finds the indices of the minimum values in each column of a matrix. * Example:
* * double[][] a = {{0, 1, 2, 3, 4},
* {1, 7, 88, 9, 10},
* {2, 13, 14, 15, 16},
* {3, 19, 20, 201, 22},
* {4, 23, 24, 25, 26}};
* int[] z = maxIndex(a);
* Result is:
* 4 4 1 3 4
*
* @param M Input matrix. * @return Array of indices of the maximums from each column of M. */ public static int[] maxIndex(double[][] M) { int[] maxI = new int[M[0].length]; for (int j = 0; j < maxI.length; j++) { maxI[j] = 0; for (int i = 1; i < M.length; i++) if (M[i][j] > M[maxI[j]][j]) maxI[j] = i; } return maxI; } /** * Finds the index of the maximum value in a list of values or an array. * @param M Can be a list of values e.g. maxIndex(11,22,44,2) or an array * @return index of maximum value in M */ public static int maxIndex(double... M) { int maxI = 0; for (int i = 1; i < M.length; i++) if (M[i] > M[maxI]) maxI = i; return maxI; } // cumulative methods /** * Calculate the sum of the values in an array * @param v input array * @return sum of values in v */ public static double sum(double[] v) { int m = v.length; double s = 0; for (int i = 0; i < m; i++) s += v[i]; return s; } /** * Calculates the sum of each column in a matrix. * @param v * @return Array. value of i'th element is sum of values in column(i) */ public static double[] sum(double[][] v) { int m = v.length; int n = v[0].length; double[] X = new double[n]; double s; for (int j = 0; j < n; j++) { s = 0; for (int i = 0; i < m; i++) s += v[i][j]; X[j] = s; } return X; } /** * Calculates the cumulative sum of an array. Think of it as an integral. * Example:
* * double[] b = {0,1,2,3,4};
* double[] z = cumSum(b);
* result is:
* 0 1 3 6 10
*
* @param v Input array. * @return Output array of same length as v. */ public static double[] cumSum(double[] v) { int m = v.length; double[] X = new double[m]; double s = 0; for (int i = 0; i < m; i++) { s += v[i]; X[i] = s; } return X; } /** * Calculates the cumulative sum of each column in a matrix. * Example:
* * double[][] a = {{0, 1, 2, 3, 4},
* {1, 7, 8, 9, 10},
* {2, 13, 14, 15, 16},
* {3, 19, 20, 21, 22},
* {4, 23, 24, 25, 26}};
* double[][] z = cumSum(a);
* result is:
* 0 1 2 3 4
* 1 8 10 12 14
* 3 21 24 27 30
* 6 40 44 48 52
* 10 63 68 73 78
*
* @param v * @return Output matrix. Each column is the cumulative sum of each column in v. */ public static double[][] cumSum(double[][] v) { int m = v.length; int n = v[0].length; double[][] X = new double[m][n]; double s; for (int j = 0; j < n; j++) { s = 0; for (int i = 0; i < m; i++) { s += v[i][j]; X[i][j] = s; } } return X; } /** * Calculates the product of the values in an array. * @param v Input array. * @return The product of the values in v. */ public static double product(double[] v) { int m = v.length; double p = 1; for (int i = 0; i < m; i++) p *= v[i]; return p; } /** * Calculates the product of the values in each column of a matrix. * @param v Input matrix. * @return An array of n values where n=number of columns in v. The i'th element is product * of the values in the i'th column of v. */ public static double[] product(double[][] v) { int m = v.length; int n = v[0].length; double[] X = new double[n]; for (int j = 0; j < n; j++) { double p = 1; for (int i = 0; i < m; i++) p *= v[i][j]; X[j] = p; } return X; } /** * Calculates cumulative product of the values in an array. * Example:
* * double[] b = {1,2,3,4};
* double[] z = cumProduct(b);
* Result is:
* 1 2 6 24
*
* @param v Input array * @return Out put array of same size as v. */ public static double[] cumProduct(double[] v) { int m = v.length; double[] X = new double[m]; double s = 1; for (int i = 0; i < m; i++) { s *= v[i]; X[i] = s; } return X; } /** * Calculates the cumulative product of each column in a matrix. * Example:
* * double[][] a = {{0, 1, 2, 3, 4},
* {1, 7, 8, 9, 10},
* {2, 13, 14, 15, 16},
* {3, 19, 20, 21, 22},
* {4, 23, 24, 25, 26}};
* result is:
* 0 1 2 3 4
* 0 7 16 27 40
* 0 91 224 405 640
* 0 1729 4480 8505 14080
* 0 39767 107520 212625 366080
*
* @param v * @return Output matrix. Each column is the cumulative product of each column in v. */ public static double[][] cumProduct(double[][] v) { int m = v.length; int n = v[0].length; double[][] X = new double[m][n]; double s; for (int j = 0; j < n; j++) { s = 1; for (int i = 0; i < m; i++) { s *= v[i][j]; X[i][j] = s; } } return X; } // print methods /** * Generates a string that holds a nicely organized space-seperated version of a matrix or array. * An extra space is automatically included. * Note the lower case S. It's tostring() not toString(). * Example:
* * double[][] a = {{1.234, 4.5, 6.78},{1.2, 3.45, 6.789}};
* System.out.println(tostring(a));
* result is:
* 1.234 4.5 6.78
* 1.2 3.45 6.789 *
* @param v Matrix or array * @return A string of a nicely organized version of the matrix or array. */ public static String toString(double[]... v) { StringBuffer str = new StringBuffer(); for (int i = 0; i < v.length; i++) { for (int j = 0; j < v[i].length - 1; j++) str.append(v[i][j] + " "); str.append(v[i][v[i].length - 1]); if (i < v.length - 1) str.append("\n"); } return str.toString(); } /** * Generates a string that holds a nicely organized version of a matrix or array. * Uses format specifier, e.g. "%5.3f", "%11.1E", ... * An extra space is automatically included. * Note the lower case S. It's tostring() not toString(). * Example:
* * double[][] a = random(2, 3);
* System.out.println(tostring("%7.3f", a));
* result is:
* 0.654 0.115 0.422
* 0.560 0.839 0.280
*
* @param format A standard format specifier for one value * @param v Matrix or array * @return A string of a nicely organized version of the matrix or array. */ public static String toString(String format, double[]... v) { StringBuffer str = new StringBuffer(); for (int i = 0; i < v.length; i++) { for (int j = 0; j < v[i].length - 1; j++) str.append(String.format(format + " ", v[i][j])); str.append(String.format(format, v[i][v[i].length - 1])); if (i < v.length - 1) str.append("\n"); } return str.toString(); } // check methods /** * Throws an error exception if an argument is invalid. Handy to make sure the right number * of values is passed around. * @param msg Message to be printed if the error occurs. * @throws IllegalArgumentException */ public static void throwError(String msg) { throw new IllegalArgumentException(msg); } /** * Checks to make sure each row of a matrix is of a specified dimension. Handy for making sure * matrices are rectangular. * @param M Input matrix * @param n Number of elements that should be in each row of M * @throws IllegalArgumentException */ public static void checkColumnDimension(double[][] M, int n) { for (int i = 0; i < M.length; i++) if (M[i].length != n) throwError("row " + i + " have " + M[i].length + " columns instead of " + n + " columns expected."); } /** * Same as checkColumnDimension() but just returns a boolean value rather than throwing an exception. * @param M Input matrix * @param n Number of elements that should be in each row of M * @return true if each row of M has n values. false otherwise. * @see #checkColumnDimension(double[][], int) */ public static boolean isColumnDimension(double[][] M, int n) { for (int i = 0; i < M.length; i++) if (M[i].length != n) return false; return true; } /** * Checks to make sure each column of a matrix is of a specified dimension. Handy for making sure * matrices are rectangular. * @param M Input matrix * @param m Number of elements that should be in each column of M. * @throws IllegalArgumentException */ public static void checkRowDimension(double[][] M, int m) { if (M.length != m) throwError("columns have " + M.length + " rows instead of " + m + " rows expected."); } /** * Same as checkRowDimension() but just returns a boolean value rather than throwing an exception. * @param M Input matrix * @param m Number of elements that should be in each column of M * @return true if each column of M has n values. false otherwise. * @see #checkRowDimension(double[][], int) */ public static boolean isRowDimension(double[][] M, int m) { if (M.length != m) return false; return true; } /** * Checks to make sure an array is of a specified length. * @param M Input array. * @param n Required number of elements in M * @throws IllegalArgumentException */ public static void checkLength(double[] M, int n) { if (M.length != n) throwError("row have " + M.length + " elements instead of " + n + " elements expected."); } /** * Same as checkLength but returns a boolean value rather than throwing an exception. * @param M Input array. * @param n Required number of elements in M. * @return true if M.length==n. false otherwise. */ public static boolean isLength(double[] M, int n) { if (M.length != n) return false; return true; } // function methods /** * Apply a scalar function to every element of an array. * Must import org.math.array.util.*; to get Function interface. * The function named f in Function must be overridden. Be careful not * to define any other functions named f in your code. * Example:
* * double[] b = {{1,2,3,4},{5,6,7,8}};
* Function inverse = new Function() { public double f(double x) { return 1/x; }};
* double[] z = f(b, inverse);
* Result is:
* 1.00 0.50 0.333 0.25
* 0.20 0.167 0.143 0.125
*
* @param M The input array * @param f Function object * @return array of same size as M. */ public static double[][] f(double[][] M, Function f) { double[][] fM = new double[M.length][]; for (int i = 0; i < fM.length; i++) { fM[i] = new double[M[i].length]; for (int j = 0; j < fM[i].length; j++) fM[i][j] = f.f(M[i][j]); } return fM; } /** * Apply a scalar function to every element of an array. * Must import org.math.array.util.*; to get Function interface. * Example:
* * double[] b = {1,2,3,4};
* Function inverse = new Function() { public double f(double x) { return 1/x; }};
* double[] z = f(b, inverse);
* Result is:
* 1.00 0.50 0.33 0.25 *
* @param M The input array * @param func Function object whose sole method f(double) has already been overridden. * @return array of same size as M. */ public static double[] f(double[] M, Function func) { double[] fM = new double[M.length]; for (int i = 0; i < fM.length; i++) fM[i] = func.f(M[i]); return fM; } /** * Provides a sequence of values to which some function has been applied. * Sort of a mutant version of increment(). * Example:
* * IndexFunction square = new IndexFunction()
* { public double fi(int x) { return x*x; }};
* double[] z = findex(5, square);
* Result is:
* 0 1 4 9 16
*
* @param m Number of terms in the output array. The values 0..m-1 will be fed to the function * @param f An IndexFunction object whose method fi(int) has already been overridden. * @return An array of m elements. fi(0), fi(1), ... fi(m-1) */ public static double[] findex(int m, IndexFunction f) { double[] fm = new double[m]; for (int i = 0; i < fm.length; i++) fm[i] = f.fi(i); return fm; } // sort methods /** * Sorts an array in ascending order. * @param values Input array * @return Sorted version of input array. */ public static double[] sort(double[] values) { double[] sorted_values = new double[values.length]; System.arraycopy(values, 0, sorted_values, 0, values.length); new Sorting(sorted_values, false); return sorted_values; } /** * Sorts the rows of a matrix using a specified column as the key. * Example:
* * double[][] a = {{3, 5, 2, 1, 2},
* {1, 3, 8, 9, 0},
* {2, 4, 2, 5, 6},
* {0, 1, 2, 3, 4},
* {4, 2, 1, 5, 2}};
* double[][] z = sort(a,1);
* Result is:
* 0 1 2 3 4
* 4 2 1 5 2
* 1 3 8 9 0
* 2 4 2 5 6
* 3 5 2 1 2
*
* Fixed (I hope) 3/28/06. * @param values Input matrix * @param column Index of column to be used as the sorting key. * @return Matrix whose rows have been shuffled around. */ public static double[][] sort(double[][] values, int column) { double[][] sorted_values = new double[values.length][values[0].length]; Sorting s = new Sorting(getColumnCopy(values, column), false); for (int i = 0; i < sorted_values.length; i++) System.arraycopy(values[s.getIndex(i)], 0, sorted_values[i], 0, values[s.getIndex(i)].length); return sorted_values; } /** * Transposes an mxn matrix into an nxm matrix. Each row of the input matrix becomes a column in the * output matrix. * @param M Input matrix. * @return Transposed version of M. */ public static double[][] transpose(double[][] M) { double[][] tM = new double[M[0].length][M.length]; for (int i = 0; i < tM.length; i++) for (int j = 0; j < tM[0].length; j++) tM[i][j] = M[j][i]; return tM; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy