Package scalaSci.math.array

Source Code of scalaSci.math.array.DoubleArray

package scalaSci.math.array;

import scalaSci.math.array.util.Function;
import scalaSci.math.array.util.IndexFunction;
import scalaSci.math.array.util.Random;
import scalaSci.math.array.util.Sorting;
import scalaExec.Interpreter.GlobalValues;


public class DoubleArray {
    static public double log2Conv = Math.log(2.0);

  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));
                System.out.println("before sin = ");
                M = sin(M);
                System.out.println("sin = "+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.
   *
   * @returns 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;
  }

public static double[][] Subtract(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;
  }

public static double[][] Add(double[][] M, double a) {
                int Rows = M.length;  int Cols = M[0].length;
                double [][]res = new double[Rows][Cols];
    for (int i = 0; i < Rows; i++)
      for (int j = 0; j < Cols; j++)
        res[i][j] = M[i][j] + a;
    return res;
  }

        public static double[][] Add(double[][] M, double [][]M2) {
               int Rows = M.length;  int Cols = M[0].length;
                double [][]res = new double[Rows][Cols];
    for (int i = 0; i < Rows; i++)
      for (int j = 0; j < Cols; j++)
        res[i][j] = M[i][j] + M2[i][j];
    return res;
  }

public static double[][] Subtract(double[][] M, double [][]M2) {
               int Rows = M.length;  int Cols = M[0].length;
                double [][]res = new double[Rows][Cols];
    for (int i = 0; i < Rows; i++)
      for (int j = 0; j < Cols; j++)
        res[i][j] = M[i][j] - M2[i][j];
    return res;
  }

        public static double[][]  sin(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.sin(M[i][j]);
    return Ms;
  }


 
  public static double[][]  cos(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.cos(M[i][j]);
    return Ms;
  }
 
  public static double[][]  tan(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.tan(M[i][j]);
    return Ms;
  }
 
 
  public static double[][]  asin(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.asin(M[i][j]);
    return Ms;
  }
 
 
  public static double[][]  acos(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.acos(M[i][j]);
    return Ms;
  }
 
  public static double[][]  atan(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.atan(M[i][j]);
    return Ms;
  }
 
 
  public static double[][]  sinh(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.sinh(M[i][j]);
    return Ms;
  }
 
 
  public static double[][]  cosh(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.cosh(M[i][j]);
    return Ms;
  }
 
 
  public static double[][]  tanh(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.tanh(M[i][j]);
    return Ms;
  }
 
  public static double[][]  exp(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.exp(M[i][j]);
    return Ms;
  }
 
  public static double[][]  log(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.log(M[i][j]);
    return Ms;
  }
 
  public static double[][]  log2(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.log(M[i][j])/log2Conv;
    return Ms;
  }
 
 
  public static double[][]  log10(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.log10(M[i][j]);
    return Ms;
  }
 
 
  public static double[][]  abs(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.abs(M[i][j]);
    return Ms;
  }
 
 
  public static double[][]  ceil(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.ceil(M[i][j]);
    return Ms;
  }
 
 
  public static double[][]  floor(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.floor(M[i][j]);
    return Ms;
  }
 
  public static double[][]  round(double [][] M) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.round(M[i][j]);
    return Ms;
  }
 
  public static double[][]  pow(double [][] M, double exponent ) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.pow(M[i][j],  exponent );
    return Ms;
  }
 
 
  public static double[][]  sqrt(double [][] M ) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.sqrt(M[i][j]);
    return Ms;
  }
 
 
  public static double[][]  toDegress(double [][] M ) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.toDegrees(M[i][j]);
    return Ms;
  }
 
  public static double[][]  toRadians(double [][] M ) {
                double [][] Ms = new double[M.length][M[0].length];
                for (int i = 0; i < M.length; i++)
        for (int j = 0; j < M[i].length; j++)
        Ms[i][j] = Math.toRadians(M[i][j]);
    return Ms;
  }
  
 
 
 
  /**
   * Adds a matrix to another matrix, which should be of the same dimension.
   *
   * @returns 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:<br>
   * <code>
   * double[][] id = identity(3);<br>
   * Result is:<br>
   * 1.0 0.0 0.0<br>
   * 0.0 1.0 0.0<br>
   * 0.0 0.0 1.0<br>
   * </code>
   * @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:<br>
   * <code>
   * double[][] eig = diagonal(3, 2.1);<br>
   * Result is:<br>
   * 2.1 0.0 0.0<br>
   * 0.0 2.1 0.0<br>
   * 0.0 0.0 2.1<br>
   * </code>
   * @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:<br>
   * <code>
   * double[][] eig = diagonal(1.0,2.0,3.0);<br>
   * Result is:<br>
   * 1.0 0.0 0.0<br>
   * 0.0 2.0 0.0<br>
   * 0.0 0.0 3.0<br>
   * </code>
   * @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 <code>fill(int m, int n, 1.0)</code> instead.
   */
  public static double[][] one(int m, int n) {
    return fill(m, n, 1.0);
  }

        public static double[][] zero(int m, int n) {
    return fill(m, n, 0.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 <code>fill(int m, int n, double c)</code> 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 <code>fill(int m, double c)</code> 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 <code>fill(int m, double c)</code> 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:<br>
   * <code>
   * double[][] u = fill(2, 3, 1.0);<br>
   * Result is:<br>
   * 1.0 1.0 1.0<br>
   * 1.0 1.0 1.0<br>
   * </code>
   * @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:<br>
   * <code>
   * double[] u = fill(3, 1.0);<br>
   * Result is:<br>
   * 1.0 1.0 1.0<br>
   * </code>
   * @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
   * <em>pitch</em> and starts at <em>begin</em>. 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 <em>begin</em> to <em>end</em> with step
   * size <em>pitch</em>.
   * @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:<br>
   * <code>
   * 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}};<br>
   * double[][] b = getSubMatrixRangeCopy(a, 2, 3, 1, 3);<br>
   * input is:<br>
   *  0  1  2  3  4<br>
   *  1  7  8  9 10<br>
   *  2 13 14 15 16<br>
   *  3 19 20 21 22<br>
   *  4 25 26 27 28<br>
   * result is:<br>
   * 13 14 15<br>
   * 19 20 21<br>
   * </code>
   * @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:<br>
   * <code>
   * 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}};<br>
   * double[][] z = getColumnsRangeCopy(a, 2, 4);<br>
   * input is:<br>
   * 0   1   2   3   4<br>
   * 1   7   8   9  10<br>
   * 2  13  14  15  16<br>
   * 3  19  20  21  22<br>
   * 4  25  26  27  28<br>
   * result is:<br>
   *  2   3   4<br>
   *  8   9  10<br>
   * 14  15  16<br>
   * 20  21  22<br>
   * 26  27  28<br>
   * </code>
   * @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:<br>
   * <code>
   * 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}};<br>
   * double[][] z = getColumnsCopy(a, 2, 4);<br>
   * input is:<br>
   * 0   1   2   3   4<br>
   * 1   7   8   9  10<br>
   * 2  13  14  15  16<br>
   * 3  19  20  21  22<br>
   * 4  25  26  27  28<br>
   * result is:<br>
   *  0   2   4<br>
   *  1   8  10<br>
   *  2  14  16<br>
   *  3  20  22<br>
   *  4  26  28<br>
   * </code>
   * @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:<br>
   * <code>
   * 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}};<br>
   * double[][] z = getColumnCopy(a, 2);<br>
   * input is:<br>
   * 0   1   2   3   4<br>
   * 1   7   8   9  10<br>
   * 2  13  14  15  16<br>
   * 3  19  20  21  22<br>
   * 4  25  26  27  28<br>
   * Result is:<br>
   * 2   8  14  20  26<br>
   * </code>
   * @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 <i>column</i> 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:<br>
   * <code>
   * 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}};<br>
   * double[][] z = getRowsCopy(a, 2, 4);<br>
   * input is:<br>
   * 0   1   2   3   4<br>
   * 1   7   8   9  10<br>
   * 2  13  14  15  16<br>
   * 3  19  20  21  22<br>
   * 4  25  26  27  28<br>
   * result is:<br>
   *  2  13  14  15  16<br>
   *  4  25  26  27  28<br>
   * </code>
   * @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:<br>
   * <code>
   * 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}};<br>
   * double[] z = getRowCopy(a, 2);<br>
   * input is:<br>
   * 0   1   2   3   4<br>
   * 1   7   8   9  10<br>
   * 2  13  14  15  16<br>
   * 3  19  20  21  22<br>
   * 4  25  26  27  28<br>
   * result is:<br>
   *  2  13  14  15  16<br>
   * </code>
   * @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:<br>
   * <code>
   * 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}};<br>
   * double[][] z = getRowsRangeCopy(a, 2, 4);<br>
   * input is:<br>
   * 0   1   2   3   4<br>
   * 1   7   8   9  10<br>
   * 2  13  14  15  16<br>
   * 3  19  20  21  22<br>
   * 4  25  26  27  28<br>
   * result is:<br>
   * 2  13  14  15  16<br>
   * 3  19  20  21  22<br>
   * 4  25  26  27  28<br>
   * </code>
   * @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:<br>
   * <code>
   * double[] a = {00,11,22,33,44,55,66,77,88,99};<br>
   * double[] z = getRangeCopy(a, 2, 5);<br>
   * result is:<br>
   * 22  33  44  55<br>
   * </code>
   * @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:
   * <br>
   * <code>
   * double[] a = {00,11,22,33,44,55,66,77,88,99};<br>
   * double[] z = getCopy(a, 2, 5);<br>
   * result is:<br>
   * 22  55<br>
   * </code>
   * @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>i</i>
   */
  public static int getColumnDimension(double[][] M, int i) {
    return M[i].length;
  }

  /**
   * Extract diagonal from a matrix.
   * Example:<br>
   * <code>
   * 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}};<br>
   * double[] z = getDiagonal(a, 1);<br>
   * input is:<br>
   * 0   1   2   3   4<br>
   * 1   7   8   9  10<br>
   * 2  13  14  15  16<br>
   * 3  19  20  21  22<br>
   * 4  25  26  27  28<br>
   * result is:<br>
   *  1 8 15 22<br>
   * </code>
   * @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:<br>
   * <code>
   * double[] a = {00,11,22,33,44}, b = {55,66,77,88};
   * double[][] z = mergeRows(a, b);
   * result is:<br>
   *   0  11  22  33  44
   *  55  66  77  88
   * </code>
   * @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:<br>
   * <code>
   * double[] a = {00,11,22,33,44}, b = {55,66,77,88,99};
   * double[][] z = mergeColumns(a, b);
   * result is:<br>
   *  0  55
   * 11  66
   * 22  77
   * 33  88
   * 44  99
   * </code>
   * @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:<br>
   * <code>
   * double[] a = {00,11,22,33,44}, b = {55,66,77,88,99};<br>
   * double[] z = merge(a, b, a);<br>
   * result is:<br>
   *   0  11  22  33  44  55  66  77  88  99   0  11  22  33  44
   * </code>
   * @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:<br>
   * <code>
   * 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}};<br>
   * double[] b = {00,11,22,33,44}, c = {55,66,77,88,99};<br>
   * double[][] z = insertColumns(a, 2, b, c);<br>
   * input matrix is:<br>
   *  0   1   2   3   4<br>
   *  1   7   8   9  10<br>
   *  2  13  14  15  16<br>
   *  3  19  20  21  22<br>
   *  4  23  24  25  26<br>
   * result is:<br>
   *  0   1   0  55   2   3   4<br>
   *  1   7  11  66   8   9  10<br>
   *  2  13  22  77  14  15  16<br>
   *  3  19  33  88  20  21  22<br>
   *  4  23  44  99  24  25  26<br>
   * </code>
   * @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:<br>
   * <code>
   * double[][] a = {{0,1,2,3,4},{1,7,8,9,10},{2,13,14,15,16},{3,19,20,21,22}};<br>
   * double[] b = {0,11,22,33,44}, c = {55,66,77,88,99};<br>
   * double[][] z = insertRows(a, 1, b, c);<br>
   * result is:<br>
   *   0   1   2   3   4<br>
   *   0  11  22  33  44<br>
   *  55  66  77  88  99<br>
   *   1   7   8   9  10<br>
   *   2  13  14  15  16<br>
   *   3  19  20  21  22<br>
   * </code>
   * @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:<br>
   * <code>
   * double[] b = {00,11,22,33,44}, c = {55,66,77,88,99};<br>
   * double[] z = insert(b, 2, 333, 444);<br>
   * result is:<br>
   * 0  11 333 444  22  33  44
   * double[] z = insert(b, 2, c);<br>
   * result is:<br>
   * 0  11  55  66  77  88  99  22  33  44<br>
   * </code>
   * @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:<br>
   * <code>
   * 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}};<br>
   * double[][] z = deleteColumnsRange(a, 1, 3);<br>
   * result is:<br>
   *  0   4<br>
   *  1  10<br>
   *  2  16<br>
   *  3  22<br>
   *  4  26<br>
   * </code>
   * @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<x.length-1)
      System.arraycopy(x[i], J2 + 1, array[i], J1, x[i].length - (J2 + 1));
    }
    return array;
  }

  /**
   * Deletes a list of columns from a matrix.
   * Example:<br>
   * <code>
   * 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}};<br>
   * double[][] z = deleteColumns(a, 1, 3);<br>
   * result is:<br>
   *  0  2   4<br>
   *  1  8  10<br>
   *  2  14 16<br>
   *  3  20 22<br>
   *  4  24 26<br>
   * </code>
   * @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:<br>
   * <code>
   * 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}};<br>
   * double[][] z = deleteRowsRange(a, 1, 3);<br>
   * result is:<br>
   *   0   1   2   3   4<br>
   *   4  23  24  25  26<br>
   * </code>
   * @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:<br>
   * <code>
   * 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}};<br>
   * double[][] z = deleteRows(a, 1, 3);<br>
   * result is:<br>
   *   0   1   2   3   4<br>
   *   2  13  14  15  16<br>
   *   4  23  24  25  26<br>
   * </code>
   * @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:<br>
   * <code>
   * double[] b = {00,11,22,33,44};<br>
   * double[] z = deleteRange(b, 1, 3);<br>
   * Result is:<br>
   * 0  44<br>
   * </code>
   * @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<x.length-1)
    System.arraycopy(x, J2 + 1, array, J1, x.length - (J2 + 1));
    return array;
  }

  /**
   * Delete a list of elements from an array.
   * Example:<br>
   * <code>
   * double[] b = {00,11,22,33,44};<br>
   * double[] z = deleteRange(b, 1, 3);<br>
   * Result is:<br>
   * 0  22  44<br>
   * </code>
   * @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 <em>Y</em>
   * 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:<br>
   * <code>
   * double[] y = {0.0, 1.0, 4.0, 9.0, 16.0};<br>
   * double[][] xy = buildXY(0.0, 4.0, y);<br>
   *
   * result:<br>
   * 0.0   0.0<br>
   * 1.0   1.0<br>
   * 2.0   4.0<br>
   * 3.0   9.0<br>
   * 4.0   16.0<br>
   * </code>
   *
   * @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:<br>
   * <code>
   * double[] x = {0,1,2};<br>
   * double[] y = {1,7,8};<br>
   * double[][] z = buildXY(x, y);<br>
   * result is:<br>
   *  0   1<br>
   *  1   7<br>
   *  2   8<br>
   * </code>
   * @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:<br>
   * <code>
   * double[][] a = {{0,  1,   2,   3,   4},<br>
   *                 {1, .7,   8,   9,  10},<br>
   *                 {2, 13, 1.4, 1.5,  16},<br>
   *                 {3, 19,  20,  21,  22},<br>
   *                 {4, 23,  24,  25, 2.6}};<br>
   * double[] z = min(a);<br>
   * Result is:<br>
   * 0.0  0.7  1.4  1.5  2.6<br>
   * </code>
   * @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:<br>
   * <code>
   * double[][] a = {{0,  1,  2,   3,  4},<br>
   *                 {1,  7, 88,   9, 10},<br>
   *                 {2, 13, 14,  15, 16},<br>
   *                 {3, 19, 20, 201, 22},<br>
   *                 {4, 23, 24,  25, 26}};<br>
   * double[] z = max(a);<br>
   * Result is:<br>
   * 4  23  88  201  26<br>
   * </code>
   * @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:<br>
   * <code>
   * double[][] a = {{0,  1,   2,   3,   4},<br>
   *                 {1, .7,   8,   9,  10},<br>
   *                 {2, 13, 1.4, 1.5,  16},<br>
   *                 {3, 19,  20,  21,  22},<br>
   *                 {4, 23,  24,  25, 2.6}};<br>
   * int[] z = minIndex(a);<br>
   * Result is:<br>
   * 0  1  2  2  4<br>
   * </code>
   * @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:<br>
   <code>
   * double[][] a = {{0,  1,  2,   3,  4},<br>
   *                 {1,  7, 88,   9, 10},<br>
   *                 {2, 13, 14,  15, 16},<br>
   *                 {3, 19, 20, 201, 22},<br>
   *                 {4, 23, 24,  25, 26}};<br>
   * int[] z = maxIndex(a);<br>
   * Result is:<br>
   * 4  4  1  3  4<br>
   * </code>
   * @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:<br>
   * <code>
   * double[] b = {0,1,2,3,4};<br>
   * double[] z = cumSum(b);<br>
   * result is:<br>
   *  0    1    3    6   10<br>
   * </code>
   * @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:<br>
   * <code>
   * double[][] a = {{0,  1,  2,  3,  4},<br>
   *                 {1,  7,  8,  9, 10},<br>
   *                 {2, 13, 14, 15, 16},<br>
   *                 {3, 19, 20, 21, 22},<br>
   *                 {4, 23, 24, 25, 26}};<br>
   * double[][] z = cumSum(a);<br>
   * result is:<br>
   *  0    1    2    3    4<br>
   *  1    8   10   12   14<br>
   *  3   21   24   27   30<br>
   *  6   40   44   48   52<br>
   * 10   63   68   73   78<br>
   * </code>
   * @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:<br>
   * <code>
   * double[] b = {1,2,3,4};<br>
   * double[] z = cumProduct(b);<br>
   * Result is:<br>
   * 1    2    6   24<br>
   * </code>
   * @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:<br>
   * <code>
   * double[][] a = {{0,  1,  2,  3,  4},<br>
   *                 {1,  7,  8,  9, 10},<br>
   *                 {2, 13, 14, 15, 16},<br>
   *                 {3, 19, 20, 21, 22},<br>
   *                 {4, 23, 24, 25, 26}};<br>
   * result is:<br>
   * 0        1        2        3        4<br>
   * 0        7       16       27       40<br>
   * 0       91      224      405      640<br>
   * 0     1729     4480     8505    14080<br>
   * 0    39767   107520   212625   366080<br>
   * </code>
   * @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:<br>
   * <code>
   * double[][] a = {{1.234, 4.5, 6.78},{1.2, 3.45, 6.789}};<br>
   * System.out.println(tostring(a));<br>
   * result is:<br>
   * 1.234 4.5 6.78<br>
   * 1.2 3.45 6.789
   * </code>
   * @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(GlobalValues.fmtString.format(v[i][j]) + " ");
      str.append(GlobalValues.fmtString.format(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:<br>
   * <code>
   * double[][] a = random(2, 3);<br>
   * System.out.println(tostring("%7.3f", a));<br>
   * result is:<br>
   *   0.654   0.115   0.422<br>
   *   0.560   0.839   0.280<br>
   * </code>
   * @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 scalaSci.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:<br>
   * <code>
   * double[] b = {{1,2,3,4},{5,6,7,8}};<br>
   * Function inverse = new Function() { public double f(double x) { return 1/x; }};<br>
   * double[] z = f(b, inverse);<br>
   * Result is: <br>
   *  1.00  0.50 0.333 0.25<br>
   *  0.20 0.167 0.143 0.125<br>
   * </code>
   * @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 scalaSci.math.array.util.*; to get Function interface.
   * Example:<br>
   * <code>
   * double[] b = {1,2,3,4};<br>
   * Function inverse = new Function() { public double f(double x) { return 1/x; }};<br>
   * double[] z = f(b, inverse);<br>
   * Result is: <br>
   *  1.00 0.50 0.33 0.25
   * </code>
   * @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:<br>
   * <code>
   * IndexFunction square = new IndexFunction() <br>
   *            { public double fi(int x) { return x*x; }};<br>
   * double[] z = findex(5, square);<br>
   * Result is:<br>
   * 0 1 4 9 16<br>
   * </code>
   * @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:<br>
   * <code>
   * double[][] a = {{3, 5, 2, 1, 2}, <br>
   *                 {1, 3, 8, 9, 0}, <br>
   *                 {2, 4, 2, 5, 6}, <br>
   *                 {0, 1, 2, 3, 4}, <br>
   *                 {4, 2, 1, 5, 2}};<br>
   * double[][] z = sort(a,1);<br>
   * Result is:<br>
   * 0  1  2  3  4<br>
   * 4  2  1  5  2<br>
   * 1  3  8  9  0<br>
   * 2  4  2  5  6<br>
   * 3  5  2  1  2<br>
   * </code>
   * 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;
  }
       
        public static double[][] dot(double [][]v1, double [][] v2)  {
            int v1X = v1.length;
            int v2X = v2.length;
            int v1Y = v1[0].length;
            int v2Y = v2[0].length;
            if (v1X != v2X || v1Y != v2Y)  {
                System.out.println("dimensions in dot() do not fit");
                return null;
            }
            double [][] res = new double [v1X][v1Y];
            for (int r=0; r<v1X; r++)
                for (int c=0; c<v1Y; c++)
                    res[r][c] = v1[r][c]*v2[r][c];
           
            return res;
        }
 
           
           
            
       
}
TOP

Related Classes of scalaSci.math.array.DoubleArray

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.