|
Matrix.java
|
// FILE. . . . . d:/hak/hlt/src/hlt/math/matrix/sources/Matrix.java // EDIT BY . . . Hassan Ait-Kaci // ON MACHINE. . Hak-Laptop // STARTED ON. . Fri Nov 15 13:09:37 2019
|
package hlt.math.matrix;
| package hlt.math.matrix documentation listing |
import hlt.language.tools.Misc; // import hlt.math.fuzzy.StandardFuzzyAlgebra;
This defines the class Matrix that implements basic
two-dimensional linear algebra in the form of a collection of
operations defined on a Matrix class represented as a 2D
array of doubles.
Contents (package hlt.math.matrix
documentation listing)
|
public class Matrix {
Object Constructors |
| Construct a vacuous Matrix using the default entry algebra (StandardAlgebra). |
public Matrix () { super(); }
| Construct a vacuous Matrix setting the number algebra to the given NumberAlgebra. |
protected Matrix (NumberAlgebra algebra) { NumberAlgebra.setCurrentAlgebra(algebra); }
| Construct a rows-by-cols Matrix of 0.0's. |
public Matrix (int rows, int cols) { if (rows <= 0 || cols <= 0) throw new RuntimeException("Illegal matrix dimensions: ("+ rows+","+cols+")"); this.rows = rows; this.cols = cols; data = new double[rows][cols]; }
| Construct a square Matrix of order order with all entries 0.0's. |
public Matrix (int order) { if (order <= 0) throw new RuntimeException("Illegal square matrix order: ("+ order+")"); this.rows = order; this.cols = order; data = new double[order][order]; }
| Construct a new Matrix copying the given data array. |
public Matrix (double[][] data) { this(data,false); }
| Construct a new Matrix sharing the given data array if inPlace is true, and copying it otherwise. |
public Matrix (double[][] data, boolean inPlace) { if (inPlace) setData(data); else { rows = data.length; cols = data[0].length; this.data = copyData(data); } }
| Construct a new Matrix from the data array of the given Matrix. |
protected Matrix (Matrix M) { this(M.data); }
Object Components |
| The number of rows of this Matrix. |
protected int rows;
| The number of columns of this Matrix. |
protected int cols;
| This is the rows-by-cols array containing the entries of this Matrix. |
protected double[][] data;
Component-Access Methods |
| Return the rank of this Matrix. It is always the same as rows, but used only for square-matrix methods |
public final int rank () { return rows; }
| Return the order of this Matrix. It is always the same as rows, but used only for square-matrix methods |
public final int order () { return rows; }
| Return the number of rows of this Matrix. |
public final int rows () { return rows; }
| Return the number of columns of this Matrix. |
public final int cols () { return cols; }
| Return the data array of this Matrix. |
public final double[][] data () { return data; }
Component-Setter/Getter Methods |
| Set the (i,j) entry of this Matrix to the given value and return the previous value that was there. Throws a RuntimeException for indices out of bounds. N.B.: Matrix indices are counted from 1. |
public double set (int i, int j, double value) { // check for legal entry and adjust i and j to start from 0 in data in // the code following this checkLegalEntry(i--,j--); return safeDataUpdate(i,j,truncate(value)); }
| Set the (row,col) entry of this Matrix data array to the given value and return the previous value that was there. N.B. This counts row and col from 0 and assumes indexing is safe (e.g., after checkLegalEntry). |
protected final double safeDataUpdate (int row, int col, double value) { double old = data[row][col]; data[row][col] = value; return old; }
| This is an in-place pointwise update that modifies each entry of this matrix to the value of the corresponding entry in the given matrix. |
public Matrix update (Matrix M) { if (rows != M.rows || cols != M.cols) throw new RuntimeException("Incompatible matrix dimensions: <" +rows+","+cols+"> =/= <"+M.rows+","+M.cols+">"); for (int i = 0; i < rows; i++) for (int j = 0; j < cols; j++) data[i][j] = M.data[i][j]; return this; }
| Return the value of in this Matrix are entry indices (i,j). Throws a RuntimeException for indices out of bounds. N.B.: Matrix indices are counted from 1. |
public final double get (int i, int j) { // check for legal entry and adjust i and j to start from 0 in data in // the code following this checkLegalEntry(i--,j--); return data[i][j]; }
| Modifies this matrix to have the given two-dimensional data array of doubles and corresponding numbers of rows and columns. If the array null a runtime exception is thrown. |
public Matrix setData (double[][] data) { if (data == null) throw new RuntimeException ("Attempt to initialize a matrix with a null data array"); rows = data.length; cols = data[0].length; this.data = data; return this; }
Object Methods |
| Return the sum of its double arguments as their sum according to the current number algebra in effect. |
static public double sum (double x, double y) { return NumberAlgebra.getCurrentAlgebra().sum(x,y); }
| Return the product of its double arguments as their product according to the current number algebra in effect. |
static public double product (double x, double y) { return NumberAlgebra.getCurrentAlgebra().product(x,y); }
| Return the difference of its double arguments as their difference according to the current number algebra in effect. |
static public double difference (double x, double y) { return NumberAlgebra.getCurrentAlgebra().difference(x,y); }
| Return the negation of its double argument as its negation according to the current number algebra in effect. |
static public double negation (double x) { return NumberAlgebra.getCurrentAlgebra().negation(x); }
| Return a new Matrix equal to this+M. |
public Matrix plus (Matrix M) { return new Matrix().setData(dataPlus(data,M.data)); } protected final double[][] dataPlus (double[][] A, double[][] B) { int rows = A.length; int cols = A[0].length; verifyCompatibleDimension(rows,cols,B.length,B[0].length); double[][] newData = new double[rows][cols]; for (int row = 0; row < rows; row++) for (int col = 0; col < cols; col++) newData[row][col] = sum(A[row][col], B[row][col]); return newData; }
| Modify in place the entries of this to those of this plus M and return this. |
public Matrix i_plus (Matrix M) { verifyCompatibleDimension(M.rows,M.cols,rows,cols); for (int row = 0; row < rows; row++) for (int col = 0; col < cols; col++) data[row][col] = sum(data[row][col], M.data[row][col]); return this; }
| Return a new Matrix equal to this times M (does not modify this). |
public Matrix times (Matrix M) { if (cols != M.rows) throw new RuntimeException("Cannot multiply a "+rows+"x"+cols+ " matrix by a "+M.rows+"x"+M.cols+" matrix"); Matrix result = new Matrix(rows,M.cols); for (int row = 0; row < rows; row++) for (int col = 0; col < M.cols; col++) { double entry = 0.0; for (int k = 0; k < cols; k++) entry = sum(entry, product(data[row][k], M.data[k][col])); // N.B: since multiplying two truncated entries may exceed the // truncation limit, the resulting matrix entry must be truncated result.data[row][col] = truncate(entry); } return result; }
| Modify in place the entries of this to those of this times M and return this. |
public Matrix i_times (Matrix M) { return setData(this.times(M).data); }
| Return a new Matrix equal to this-M. |
public Matrix minus (Matrix M) { verifyCompatibleDimension(M.rows,M.cols,rows,cols); Matrix result = new Matrix(rows,cols); for (int row = 0; row < rows; row++) for (int col = 0; col < cols; col++) result.data[row][col] = difference(data[row][col], M.data[row][col]); return result; }
| Modify this Matrix to this-M and return this |
public Matrix i_minus (Matrix M) { verifyCompatibleDimension(M.rows,M.cols,rows,cols); for (int row = 0; row < rows; row++) for (int col = 0; col < cols; col++) data[row][col] = difference(data[row][col], M.data[row][col]); return this; }
| Return a new Matrix equal to -this. |
public Matrix minus () { Matrix result = new Matrix(rows,cols); for (int row = 0; row < rows; row++) for (int col = 0; col < cols; col++) result.data[row][col] = negation(data[row][col]); return result; }
| Modify this Matrix to -M and return this |
public Matrix i_minus () { for (int row = 0; row < rows; row++) for (int col = 0; col < cols; col++) data[row][col] = negation(data[row][col]); return this; }
| Return a new Matrix each entry of which is equal the corresponding entry in this multiplied by scale. |
public Matrix scale (double factor) { Matrix result = new Matrix(rows,cols); for (int row = 0; row < rows; row++) for (int col = 0; col < cols; col++) // N.B: since multiplying a truncated entry by a double may // exceed the truncation limit, the resulting matrix entry must // be truncated result.data[row][col] = truncate(factor*data[row][col]); return result; }
| Modify this Matrix to factorthis and return this |
public Matrix i_scale (double factor) { for (int row = 0; row < rows; row++) for (int col = 0; col < cols; col++) // N.B: since multiplying a truncated entry by a double may // exceed the truncation limit, the resulting matrix entry must // be truncated data[row][col] = truncate(factor*data[row][col]); return this; }
| Return true iff this matrix and M are entry-wise equal. |
public final boolean equal (Matrix M) { verifyCompatibleDimension(M.rows,M.cols,rows,cols); return equalData(data,M.data); }
| Swap rows row and col of this Matrix. |
public void swapRows (int row, int col) { double[] tmp = data[row]; data[row] = data[col]; data[col] = tmp; }
| Swap columns row and col of this Matrix. |
public void swapCols (int row, int col) { double tmp; for (int k = 0; k < data.length; k++) { tmp = data[k][row]; data[k][row] = data[k][col]; data[k][col] = tmp; } }
| Return a new Matrix that is the transpose of this one. |
public Matrix transpose () { return new Matrix().setData(dataTranspose(data)); }
Object Boolean Properties |
| Return true if this Matrix is pointwise-equal to the given one. |
public boolean equals (Matrix B) { Matrix A = this; if (A == B) return true; if (A.data == B.data) return true; if (B.rows != A.rows || B.cols != A.cols) throw new RuntimeException("Incompatible matrix dimensions: <" +A.rows+","+A.cols+"> =/= <"+B.rows+","+B.cols+">"); for (int i = 0; i < rows; i++) for (int j = 0; j < cols; j++) if (A.data[i][j] != B.data[i][j]) return false; return true; }
| Return true iff this matrix has no data array. |
public final boolean isVacuous () { return data == null; }
| Return true iff this Matrix is degenerate (i.e., one of its rows or columns has only 0.0). |
public boolean isDegenerate () { return (degenerateRow() != -1) || (degenerateCol() != -1); }
| Return the row index of a row that contains only 0.0 if there exists one; -1 otherwise. |
public int degenerateRow () { for (int row = 0; row < rows; row++) { int col = 0; boolean rowIsAllZero = true; while (rowIsAllZero && col < cols) { rowIsAllZero = (data[row][col] == 0.0); col++; } if (rowIsAllZero) return row; } return -1; }
| Return the column index of a column that contains only 0.0 if there exists one; -1 otherwise. |
public int degenerateCol () { for (int col = 0; col < cols; col++) { int row = 0; boolean colIsAllZero = true; while (colIsAllZero && row < rows) { colIsAllZero = (data[row][col] == 0.0); row++; } if (colIsAllZero) return col; } return -1; }
| Return true iff all entries are 0.0. |
public boolean isZeroMatrix () { for (int row = 0; row < rows; row++) for (int col = 0; col < cols; col++) if (data[row][col] != 0.0) return false; return true; } /* ************************************************************************ */
| Return true iff this is a row-stochastic matrix; i.e., all the rows are in [0.0,1.0] and their components add up to 1.0. |
public final boolean isRowStochastic () { return isRowStochastic(data); }
| Modifies this non-negative matrix in place so that all its rows have non-negative entries that add up to 1. It does so by normalizing each entry by dividing it by the sum of all the entries on its row. |
public final void makeRowStochastic () { for (int row = 0; row < rows; row++) normalizeRow(row); }
| Return true iff this is a column-stochastic matrix; i.e., all the columns are in [0.0,1.0] and their components add up to 1.0. |
public final boolean isColumnStochastic () { return isColumnStochastic(data); }
| Return true iff this is a doubly-stochastic matrix; i.e., that it all the rows and all the columns have only entries in [0.0,1.0] that add up to 1.0 in each dimension. |
public final boolean isDoublyStochastic () { return isDoublyStochastic(data); }
| Return true iff the given data array this is a row-stochastic matrix; i.e., all the rows are in [0.0,1.0] and their components add up to 1.0. |
protected final boolean isRowStochastic (double[][] data) { int rows = data.length; int cols = data[0].length; for (int row = 0; row < rows; row++) { double rowSum = 0; for (int col = 0; col < cols; col++) { if (data[row][col] < 0.0 || data[row][col] > 1.0) return false; // not within [0.0,1.0] rowSum = sum(rowSum, data[row][col]); } if (truncate(rowSum) != 1.0) return false; } // ok - we're good return true; }
| Return true iff the given data array is column-stochastic; i.e., all the columns are in [0.0,1.0] and their components add up to 1.0. |
protected final boolean isColumnStochastic (double[][] data) { int rows = data.length; int cols = data[0].length; for (int col = 0; col < cols; col++) { double colSum = 0; for (int row = 0; row < rows; row++) { if (data[row][col] < 0.0 || data[row][col] > 1.0) return false; // not within [0.0,1.0] colSum = sum(colSum, data[row][col]); } if (truncate(colSum) != 1.0) return false; } // ok - we're good return true; }
| Return true iff this is a doubly-stochastic data array; i.e., that it all the rows and all the columns have only entries in [0.0,1.0] that add up to 1.0 in each dimension. |
protected final boolean isDoublyStochastic (double[][] data) { int rows = data.length; int cols = data[0].length; // as we compute for each row the sum of its entries we also // accumulate the sum on entries for each column and store it in // this array until we reach the last row double[] colSums = new double[rows]; for (int row = 0; row < rows; row++) { double rowSum = 0; for (int col = 0; col < cols; col++) { if (data[row][col] < 0.0 || data[row][col] > 1.0) return false; // not within [0.0,1.0] rowSum = sum(rowSum, data[row][col]); colSums[row] = sum(colSums[row], data[row][col]); } if (rowSum != 1.0) return false; } // if we're here, we need to check each column sums for (int row = 0; row < rows; row++) if (truncate(colSums[row]) != 1.0) return false; // ok - we're good return true; }
| Modifies the row-th row of this Matrix by normalizing each of its entries by dividing it by the sum of all the entries on this row. N.B.: This does not works due to rounding issue (see truncate). |
private final void normalizeRow (int row) { double rowSum = 0.0; // the sum of the entries on this row System.err.println(); System.err.println("------------------------------------------------------------------------"); System.err.println("Row sum ["+row+"]:"); System.err.println("------------------------------------------------------------------------"); System.err.println(); for (int col = 0; col < cols; col++) { data[row][col] = truncate(data[row][col]); if (data[row][col] < 0.0) throw new RuntimeException ("Negative data array entry "+data[row][col]+" at indices "+ row+","+col+": can only make non-negative matrix row-stochastic."); System.err.print(" "); System.err.printf(floatFormatString(),data[row][col]); System.err.print(col<(cols-1)?"+":""); rowSum = sum(rowSum, data[row][col]); } rowSum = truncate(rowSum); System.err.println(" ---> rowSum["+row+"] = "+rowSum); if (rowSum == 0.0) return; // then there is nothing to do // needed to sum the normalized row entries to offset rounding errors double normalizedRowSum = 0.0; double actualNormalizedRowSum = 0.0; for (int col = 0; col < cols; col++) { if (data[row][col] == rowSum) { // this means that the row has only one non-zero at col // so the normalized value at col is 1.00 (and all // others still 0.0) data[row][col] = normalizedRowSum = actualNormalizedRowSum = 1.0; return; } // dividing by the sum is safe since != 0.0: double normalizedEntry = truncate(data[row][col]/rowSum); System.err.print(" "); System.err.printf(floatFormatString(),normalizedEntry); System.err.print(col<(cols-1)?"+":""); if (col == lastNonZeroColInRow(row)) { // this is the last non-zero in this row: adjust to how // close to 1.0: i.e., 1.0 - sum of all the previous non-0 // normalized entries! data[row][col] = difference(1.0, actualNormalizedRowSum); actualNormalizedRowSum = sum(actualNormalizedRowSum, normalizedEntry); normalizedRowSum = 1.0; } else // otherwise, just normalize the entry: { actualNormalizedRowSum = sum(actualNormalizedRowSum, normalizedEntry); data[row][col] = normalizedEntry; } } System.err.println(" ---> actualNormalizedRowSum["+row+"] = "+actualNormalizedRowSum); // System.err.println(" ---> normalizedRowSum["+row+"] = "+normalizedRowSum); System.err.println(); if (truncate(actualNormalizedRowSum) == 1.0) System.err.println("Actual normalized sum of row["+row+ "] is close enough to 1.0: so row["+row+ "] is deemed row-stochastic"); else System.err.println("Actual normalized sum of row["+row+ "] is NOT close enough to 1.0: so row["+row+ "] is NOT row-stochastic"); System.err.println("------------------------------------------------------------------------"); }
| Return the column index of the first non-zero entry in the given row, or -1 if there is none (i.e., the row contains only zero entries). |
public final int firstNonZeroColInRow (int row) { int col = 0; while (col < cols && data[row][col] == 0.0) col++; return (col == cols) ? -1 : col; }
| Return the row index of the first non-zero entry in the given col, or -1 if there is none (i.e., the column contains only zero entries). |
public final int firstNonZeroRowInColumn (int col) { int row = 0; while (row < rows && data[row][row] == 0.0) row++; return (row == rows) ? -1 : row; }
| Return the column index of the last non-zero entry in the given row, or -1 if there is none (i.e., the row contains only zero entries). |
public final int lastNonZeroColInRow (int row) { int col = cols-1; while (col > 0 && data[row][col] == 0.0) col--; return col; }
| Return the row index of the last non-zero entry in the given col, or -1 if there is none (i.e., the column contains only zero entries). |
public final int lastNonZeroRowInColumn (int col) { int row = rows-1; while (row > 0 && data[row][row] == 0.0) row--; return row; }
Square-Matrix Specific MethodsFollowing are some methods concerning square matrices; i.e., or equal numbers of rows and columns. |
| Return true iff this Matrix is square. |
public final boolean isSquare () { return (rows == cols); }
| Return the trace of this (square) Matrix (i.e., the sum of all its diagonal entries). |
public final double trace () { if (!isSquare()) throw new RuntimeException("Can only compute trace of a non-square matrix"); double result = 0.0; for (int i = 0; i < rows; i++) result += data[i][i]; return result; }
| Return true iff this is a square diagonal matrix. |
public final boolean isDiagonal () { if (!isSquare()) return(false); // need only sweep through the upper triangular part and check // whether either of each symmetric entries is non-zero for (int row = 0; row < rows-1; row++) for (int col = 1; col < cols; col++) if (data[row][col] != 0.0 || data[col][row] != 0.0) return false; return true; }
| If this is a square matrix, this returns this after modifying its data array in place to its transpose. If it is not square, it throws a RuntimeException. |
public Matrix i_transpose () { if (!isSquare()) throw new RuntimeException("Cannot transpose a non-square matrix in place!"); // need only sweep through the upper triangular part and swap // symmetric non-equal entries (this is necessarily safe) for (int row = 0; row < rows-1; row++) for (int col = 1; col < cols; col++) if (data[col][row] != data[row][col]) data[col][row] = safeDataUpdate(row,col,data[col][row]); return this; }
Vector-Specific MethodsFollowing are some methods concerning one-dimensional matrices; i.e., (row or column) vectors. |
| Return true iff this is a one-dimensional Matrix. |
public boolean isVector () { return isRowVector() || isColVector(); }
| Return true iff this is a one-row Matrix. |
public boolean isRowVector () { return rows == 1; }
| Return true iff this is a one-colum Matrix. |
public boolean isColVector () { return cols == 1; }
I/O Object Methods |
| Prints this matrix to standard output printing each double entry formatted using the default floatFormat format string. |
public void show () { System.out.println(); for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) System.out.printf(floatFormatString(),data[row][col]); System.out.println(); } System.out.println(); } final protected void showData () { showDataArray(data); }
Static Methods |
| Return true iff this.data and M.data are entry-wise equal. |
static protected final boolean equalData (double[][] data1, double[][] data2) { for (int row = 0; row < data1.length; row++) for (int col = 0; col < data1[0].length; col++) if (data1[row][col] != data2[row][col]) return false; return true; }
| Return a new double[][] that is the transpose of the given array data. |
static public final double[][] dataTranspose (double[][] data) { int rows = data.length; int cols = data[0].length; double[][] newData = new double[cols][rows]; for (int row = 0; row < rows; row++) for (int col = 0; col < cols; col++) newData[col][row] = data[row][col]; return newData; } static final protected void showDataArray (double[][] data) { for (int row = 0; row < data.length; row++) { for (int col = 0; col < data[0].length; col++) System.out.printf(floatFormatString(),data[row][col]); System.out.println(); } }
Useful Static Matrix MethodsThe following are various (static) useful methods handy when using Matrix. |
| Return a new square Matrix of order order with all entries 0.0's. |
public static Matrix newSquareMatrix (int order) { return new Matrix(order); }
| Return true if the given entry is assimilitated to zero according to the current set precision. |
static public boolean isZeroEntry (double entry) { return Math.abs(entry) < currentPrecision(); }
| Return a new double[][] that is equal to the given array data. |
static public final double[][] copyData (double[][] data) { int rows = data.length; int cols = data[0].length; double[][] dataCopy = new double[rows][cols]; for (int row = 0; row < rows; row++) for (int col = 0; col < cols; col++) dataCopy[row][col] = data[row][col]; return dataCopy; }
| Return a new identity Matrix of order order. |
static public Matrix identity (int order) { double[][] id = new double[order][order]; for(int i = 0; i< order; i++) id[i][i] = 1.0; return new Matrix(id); }
Consistency CheckingThe following are various (static) methods that are used in various places to verify the consistency of various Matrix parameters in a given context. |
| Verifies the compatibility of the given dimensions and throws an IncompatibleMatrixDimensionException if it is violated. |
static final protected void verifyCompatibleDimension (int rows, int cols, int otherRows, int otherCols) { if (rows != otherRows || cols != otherCols) throw new IncompatibleMatrixDimensionException(rows,cols,otherRows,otherCols); }
| Throws a RuntimeException if there is no such entry at indices (i,j) in this Matrix. N.B.: Matrix indices are counted from 1. |
final protected void checkLegalEntry (int i, int j) { checkLegalIndex(i,data.length); checkLegalIndex(j,data[0].length); }
| Throws a RuntimeException if index i is not between 1 and size inclusive. N.B.: Matrix indices are counted from 1. |
static final protected void checkLegalIndex (int i, int size) { if (i < 1 || i > size) throw new RuntimeException ("Matrix index "+i+" out of bounds [1,"+size+"]"); }
| Throws a RuntimeException if any entry in the given data array is not stochastic. |
static final protected void checkForStochasticEntries (double[][] data) { for (int row = 0; row < data.length; row++) for (int col = 0; col < data[0].length; col++) if (data[row][col] < 0.0 || data[row][col] > 1.0) throw new RuntimeException ("Non-stochastic entry in data array at (row,col): ("+row+","+col+")"); }
Printing ControlThe following are various (static) paraphernalia for the control of printing the entries of a Matrix object. |
| Print width used to format doubles and doubles using Java's System.out.printf format syntax. In order to control the format of entries printed by the show() method, redefine this string to the wished format string. |
static private int printWidth = 9;
| Return the printf width used for printing floating-point numbers. types. |
static public final int printWidth () { return printWidth; }
| Sets the format string to the specified width, which will be the total print width used for printing floating-point numbers with printf. This cannot be less that 3 (if so, it is set to 3). |
static public final int setPrintWidth (int width) { // %[width].[precision]f return printWidth = Math.max(3,width); }
| Resets to 9 the total print width for floating-point numbers used in printf format string. |
static public final int resetPrintWidth () { return setPrintWidth(9); }
| Return the current floating-point format string in effect for printing floating-point values using printf. |
public static String floatFormatString () { return "%" + Integer.toString(printWidth) + "." + Integer.toString(currentSignificantDigits()) + "f"; }
Precision ControlThe following are various (static) paraphernalia for the control of double precision when dealing with random values. |
| Return a double[rows][cols] with entries equal to random values between 0.0 and 1.0 inclusive. |
static public double[][] randomDataArray (int rows, int cols) { double[][] data = new double[rows][cols]; for (int row = 0; row < rows; row++) for (int col = 0; col < cols; col++) data[row][col] = randomValue(); return data; }
| Return a double[rows][cols] with entries equal to random values between 0.0 and scale inclusive. |
static public double[][] randomDataArray (int rows, int cols, double scale) { double[][] data = new double[rows][cols]; for (int row = 0; row < rows; row++) for (int col = 0; col < cols; col++) data[row][col] = randomValue(scale); return data; }
| Toss a coin and return either false or true. This can be biased by setting COIN_TOSS_BIAS to any double between [0.0,1.0]. The lower the bias makes coin tossing return false; the higher, it makes it return true. If 1, then coin-toss is always true. If 0, then coin-toss is always false. The default is COIN_TOSS_BIAS = 0.5. |
static public final boolean headsOrTail () { if (Math.random() < COIN_TOSS_BIAS) return true; return false; }
| The default COIN_TOSS_BIAS. |
static private double COIN_TOSS_BIAS = 0.5;
| Return the current toss-coin bias (a double in [0.0,1.0]). |
static public final double bias () { return COIN_TOSS_BIAS; }
| Set the toss-coin bias to bias. The lower the bias makes coin tossing return false more often; the higher, it makes it return true more often. If 1, then coin-toss is always true. If 0, then coin-toss is always false. |
static public final double setBias (double bias) { return COIN_TOSS_BIAS = Math.max(0,Math.min(1,bias)); }
| Reset the toss-coin bias to 0.5. |
static public final double resetBias () { return COIN_TOSS_BIAS = 0.5; }
| Return the result of truncating value to the value obtained by setting to 0 all its digits past the position indicated by currentSignificantDigits(). |
static public final double truncate (double value) { return value; // NO OP UNTIL I FIGURE OUT HOW TO CONTROL THIS DAMN THING! // double scale = Math.pow(10,currentSignificantDigits()); // return Math.floor(value*scale)/scale; // this means always <= value! // // return round(Math.floor(value*scale)/scale); // see below }
| Do the same kind of rounding that we do for values that are too close (within current threshold θ) of 0.0 or 1.0, but to any value in [θ,1-θ] closest (within current threshold θ). e.g.: if threshold θ = 0.01 and digits = 3 (i.e., precision = 0.001), the double value 0.123456 is rounded downwards to 0.123 because: ... N.B.: this not well defined unless we justify why we round to the closest value at a precision equal to 10×precision! |
static private final double round (double value) { // finish later; does nothing and return argument for now return value; }
| Return the given array data after of truncating all its entries by setting to 0 all its digits past the position indicated by currentSignificantDigits(). |
static public final double[][] truncate (double[][] data) { if (data == null) throw new RuntimeException("Vacuous data array"); for (int row = 0; row < data.length; row++) for (int col = 0; col < data[0].length; col++) data[row][col] = truncate(data[row][col]); return data; }
| The greatest number of significant decimal digits accepted for a matrix entries. It is set by default to 5 decimal places. |
static private int MAX_SIGNIFICANT_DIGITS = 5;
The method maxSignificantDigits() return the currently
effective number of significant decimal digits after the dot that are
taken into account.
N.B.: maxSignificantDigits() is the next integer
higher than -log10(currentPrecision()); i.e., in
Java:
maxSignificantDigits() == -Math.ceil(Math.log10(currentPrecision()))
For example, if currentPrecision() = 0.0001, then
log10currentPrecision() = -4, i.e.,
maxSignificantDigits() = 4.
To keep all this inter-dependencies this consistent, the maximum
number of significant digits is the only constant that can be reset
and all others are computed from it.
|
static public final int maxSignificantDigits () { return MAX_SIGNIFICANT_DIGITS; }
| The method setMaxSignificantDigits() sets the maximum number of significant decimal digits after the dot that are taken into account to the maximum of 1 and digits and return it. |
static public final int setMaxSignificantDigits (int digits) { return MAX_SIGNIFICANT_DIGITS = Math.max(1,digits); }
| How many significant decimal digits are currently taken into account for matrix entries (all digits after this one are 0). This defaults to 1. |
static private int CURRENT_SIGNIFICANT_DIGITS = 1;
| Return the current number of significant of decimal digits after the dot that are taken into account. |
public static int currentSignificantDigits () { return CURRENT_SIGNIFICANT_DIGITS; }
| The method setCurrentSignificantDigits(int) sets the current number of significant decimal digits dot to the given int if it is between 1 and maxSignificantDigits(), or whichever of these that is closest otherwise, and return it. |
static public final int setCurrentSignificantDigits (int digits) { return CURRENT_SIGNIFICANT_DIGITS = Math.min(Math.max(1,digits),maxSignificantDigits()); }
| The method currentPrecision() return the precision currently in effect. N.B.: It is always equal to 10-currentSignificantDigits(); i.e., in Java, Math.pow(10,-d). For example, if currentSignificantDigits() = 3, then currentPrecision() = 0.001. |
static public final double currentPrecision () { return Math.pow(10.0,-CURRENT_SIGNIFICANT_DIGITS); }
Random-Number Generation ControlThe following are various (static) paraphernalia for the control of how close to 0.0 or 1.0 some random values generated by the randomValue() method should be rounded downwards to 0.0 or upwards to 1.0 according a coin toss. (See the methods that control coin-toss bias.) |
| This is a value in [0.0,1.0] used as approximation threshold to 0.0 if too close; defaults to 0.0. |
static private double THRESHOLD0 = 0.0;
| Return the threshold for random rounding approximation to 0.0 currently in effect. |
static public final double threshold0 () { return THRESHOLD0; }
| This is a value in [0.0,1.0] used as approximation threshold to 1.0 if too close; defaults to 0.0. |
static private double THRESHOLD1 = 0.0;
| Return the threshold for random rounding approximation to 1.0 currently in effect. |
static public final double threshold1 () { return THRESHOLD1; }
| Sets the current approximation threshold to 0.0 to the given double in [0.0,1.0] used as approximation threshold to round downwards to 0.0 if too close. |
static public double setThreshold0 (double threshold) { return THRESHOLD0 = Math.min(Math.max(0.0,threshold),1.0); }
| Resets the current approximation threshold to 0.0 its default value (0.0). |
static public double resetThreshold0 () { return THRESHOLD0 = 0.0; }
| Sets the current approximation threshold to 1.0 to the given double in [0.0,1.0] used as approximation threshold to round upwards to 1.0 if too close. |
static public double setThreshold1 (double threshold) { return THRESHOLD1 = Math.min(Math.max(0.0,threshold),1.0); }
| Resets the current approximation threshold to 1.0 to its default value (0.0). |
static public double resetThreshold1 () { return THRESHOLD1 = 0.0; }
| Resets the current approximation thresholds to 0.0 and 1 to their default value (0.0). |
static public void resetThresholds () { resetThreshold0(); resetThreshold1(); }
| The static method randomValue() return a random double picked in the closed interval [0.0,1.0] (i.e., including 0.0 and 1.0), modulo the currently effective number of decimal digits and precision. The int digits (= 1, 2, etc,...) is how many decimal digits after the decimal point doubles are approximated. |
static protected double randomValue () { // pick a random double in [0.0,1.0) double picked = truncate(Math.random()); // the above return a double in [0.0,1.0): it does not include 1.0 // or may me too small to be worth distinguishing from 0.0; so // we round it to either 0.0 or 1.0 if too close to either double threshold0 = threshold0(); double threshold1 = threshold1(); if (picked < threshold0) /* when picked is too close to 0.0 according to threshold0 */ return headsOrTail() ? picked : /* toss a coin and return either what was picked or */ 0.0; /* return 0.0 (round downwards) */ if ((1-picked) < threshold1) /* when picked is too close to 1.0 according to threshold1 */ return headsOrTail() ? picked : /* toss a coin and return either what was picked or */ 1.0; /* return 1.0 (round upwards) */ // otherwise return picked as is return picked; }
| Show the random-number generation and doubleing-point precision control parameters currently in effect. |
static public void showParameters () { ln(); say("--------------------------------------------------------------------"); say("Matrix class parameter settings:") ; say("--------------------------------------------------------------------"); say(" current number algebra = "+NumberAlgebra.getCurrentAlgebra()); jot(" significant number of digits = "+currentSignificantDigits()); say(" (i.e., precision = "+currentPrecision()+")"); jot(" floating-point print width = "+printWidth()); say(" (i.e., format string = "+floatFormatString()+")"); say(" random number generation parameters:"); say(" \tthreshold to 0.0 = "+threshold0()); say(" \tthreshold to 1.0 = "+threshold1()); say(" \tcoin-toss bias = "+bias()); say("--------------------------------------------------------------------"); }
| The static method randomValue(double scale) return a random double picked in the closed interval [0.0,scale] if scale is positive, or [scale,0.0] if scale is negative, modulo the currently effective number of decimal digits and precision. |
static private double randomValue (double scale) { return truncate(scale*randomValue()); }
| Create and return a random square matrix of order order with entries in [0.0,1.0]. |
public static Matrix randomSquare (int order) { return random(order,order); }
| Create and return a random square matrix of order order with entries in [0.0,1.0] scaled by a factor scale. |
public static Matrix randomSquare (int order, double scale) { return random(order,order,scale); }
| Create and return a random rows-by-cols matrix with entries in [0.0,1.0]. |
public static Matrix random (int rows, int cols) { return new Matrix().setData(randomDataArray(rows,cols)); }
| Create and return a random rows-by-cols matrix with entries in [0.0,scale]. |
public static Matrix random (int rows, int cols, double scale) { return new Matrix().setData(randomDataArray(rows,cols,scale)); }
Miscellaneous Static I/O tools |
| Print an empty line on the standard output. |
static public void ln () { Misc.ln(); }
| Print n empty lines on the standard output. |
static public void ln (int n) { Misc.ln(n); }
| Print a line not ending in a CR on the standard output. |
static public void jot (String what) { Misc.jot(what); }
| Print a line ending in a CR on the standard output. |
static public void say (String what) { Misc.say(what); }
| Print a line ending in a CR and skip a line on the standard output. |
static public void sln (String what) { Misc.sln(what); } }
This file was generated on Wed Dec 18 03:37:41 PST 2019 from file Matrix.java
by the hlt.language.tools.Hilite Java tool written by Hassan Aït-Kaci