package edu.hawaii.jmotif.algorithm;
import java.util.Formatter;
import java.util.Locale;
/**
* Implements methods for matrix data generation and transformation.
*
* @author Pavel Senin
*
*/
public final class MatrixFactory {
/** EOF symbol. */
private static final String CR = "\n";
/**
* Disable constructor.
*/
private MatrixFactory() {
super();
}
/**
* Creates a single row matrix of doubles filled by zeroes.
*
* @param m the desired number of columns.
* @return the single row matrix of m columns.
*/
public static double[][] zeros(int m) {
return new double[1][m];
}
/**
* Creates matrix of size n (rows) x m (columns) filled by zeroes.
*
* @param n the number of rows.
* @param m the number of columns.
* @return the nxm matrix of zeroes.
*/
public static double[][] zeros(int n, int m) {
return new double[n][m];
}
/**
* Compare two matrices by elements.
*
* @param a the first matrix.
* @param b the second matrix.
* @return true if matrices are equal, false in the case where at least one element is not equal,
* or matrices are of different dimensions.
*/
public static boolean equals(final double[][] a, final double[][] b) {
int rowsA = a.length;
int colsA = a[0].length;
int rowsB = b.length;
int colsB = b[0].length;
if ((rowsA == rowsB) && (colsA == colsB)) {
for (int i = 0; i < rowsA; i++) {
for (int j = 0; j < colsA; j++) {
if (a[i][j] != b[i][j]) {
return false;
}
}
}
return true;
}
else {
return false;
}
}
/**
* Clone the matrix.
*
* @param a the matrix to duplicate.
* @return the copy (a new instance) of the input matrix.
*/
public static double[][] clone(double[][] a) {
double[][] res = new double[a.length][a[0].length];
for (int i = 0; i < a.length; i++) {
System.arraycopy(a[i], 0, res[i], 0, a[0].length);
}
return res;
}
/**
* Perform the matrix transposition.
*
* @param a an input matrix.
* @return an instance of transposed matrix.
*/
public static double[][] transpose(double[][] a) {
int rows = a.length;
int cols = a[0].length;
double[][] res = new double[cols][rows];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
res[j][i] = a[i][j];
}
}
return res;
}
/**
* Mimics Matlab function for reshape: returns the m-by-n matrix B whose elements are taken
* column-wise from A. An error results if A does not have m*n elements.
*
* @param a the source matrix.
* @param n number of rows in the new matrix.
* @param m number of columns in the new matrix.
*
* @return reshaped matrix.
*/
public static double[][] reshape(double[][] a, int n, int m) {
int cEl = 0;
int aRows = a.length;
double[][] res = new double[n][m];
for (int j = 0; j < m; j++) {
for (int i = 0; i < n; i++) {
res[i][j] = a[cEl % aRows][cEl / aRows];
cEl++;
}
}
return res;
}
/**
* Computes column means for the matrix.
*
* @param a the input matrix.
* @return result.
*/
public static double[] colMeans(double[][] a) {
double[] res = new double[a[0].length];
for (int j = 0; j < a[0].length; j++) {
double sum = 0;
int counter = 0;
for (int i = 0; i < a.length; i++) {
if (Double.isNaN(a[i][j]) || Double.isInfinite(a[i][j])) {
continue;
}
sum += a[i][j];
counter += 1;
}
if (counter == 0) {
res[j] = Double.NaN;
}
else {
res[j] = sum / ((double) counter);
}
}
return res;
}
/**
* Prints out matrix.
*
* @param a the matrix to print.
* @return ready for console output string.
*/
public static String toString(double[][] a) {
int rows = a.length;
int cols = a[0].length;
StringBuffer sb = new StringBuffer(4000);
Formatter formatter = new Formatter(sb, Locale.US);
sb.append(" ");
for (int j = 0; j < cols; j++) {
formatter.format(" [%1$3d]", j);
}
sb.append(CR);
for (int i = 0; i < rows; i++) {
formatter.format(" [%1$3d] ", i);
for (int j = 0; j < cols; j++) {
formatter.format(" %1$ 6f", a[i][j]);
}
sb.append(CR);
}
return sb.toString();
}
/**
* Prints out matrix.
*
* @param a the matrix to print.
* @return ready for console output string.
*/
public static String toCodeString(double[][] a) {
int rows = a.length;
int cols = a[0].length;
StringBuffer sb = new StringBuffer(4000);
Formatter formatter = new Formatter(sb, Locale.US);
for (int i = 0; i < rows; i++) {
sb.append("{");
for (int j = 0; j < cols; j++) {
formatter.format(" %1$ 4f", a[i][j]);
sb.append(", ");
}
sb.delete(sb.length() - 2, sb.length());
sb.append("}," + CR);
}
return sb.toString();
}
}