package weka.core.matrix;
import weka.core.Instances;
public class MatlabMatrix extends Matrix {
public MatlabMatrix(double[] vals) {
super(vals);
}
private static final long serialVersionUID = 6532949304630529880L;
public MatlabMatrix(double[][] A) {
super(A);
}
public MatlabMatrix(Instances data) {
super(data);
}
public MatlabMatrix(int n, int m) {
super(n, m);
}
public MatlabMatrix(int m, int n, int i) {
// TODO Auto-generated constructor stub
super(m, n, i);
}
/**
* 同matlab .^2
*
* @param isNewMatrix
* 是否生成新的矩阵
* @return
*/
public MatlabMatrix dotSquare(boolean isNewMatrix) {
MatlabMatrix matrixR = null;
if (isNewMatrix) {
matrixR = this.copy();
} else {
matrixR = this;
}
double[][] C = matrixR.getArray();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
C[i][j] = Math.pow(C[i][j], 2);
}
}
return matrixR;
}
/**
* 同matlab exp
*
* @param isNewMatrix
* 是否生成新的矩阵
* @return
*/
public MatlabMatrix exp(boolean isNewMatrix) {
MatlabMatrix matrixR = null;
if (isNewMatrix) {
matrixR = this.copy();
} else {
matrixR = this;
}
double[][] C = matrixR.getArray();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
C[i][j] = Math.exp(C[i][j]);
}
}
return matrixR;
}
/**
* 两个矩阵之间的欧式距离,矩阵的列数必须一致
*
* @param second
* 计算目标矩阵
* @param isDiagZero
* 是否强制对角为0
* @return
*/
public MatlabMatrix l2distanceMatrix(Matrix second, boolean isDiagZero) {
int srDim = second.getRowDimension();
MatlabMatrix matrix = new MatlabMatrix(this.m, srDim, 0);
for (int i = 0; i < this.m; i++) {
for (int j = 0; j < srDim; j++) {
if (isDiagZero && i == j) {
matrix.set(i, j, 0);
} else {
double sum = 0;
for (int k = 0; k < this.n; k++) {
sum += Math.pow(this.get(i, k) - second.get(j, k), 2.0);
}
matrix.set(i, j, Math.sqrt(sum));
}
}
}
return matrix;
}
/**
* 两个矩阵之间的欧式距离,矩阵的列数必须一致
*/
public MatlabMatrix l2distanceSigmaExpMatrix(Matrix second, double sigma) {
int srDim = second.getRowDimension();
MatlabMatrix matrix = new MatlabMatrix(this.m, srDim, 0);
double sigmaV = -2 * sigma * sigma;
for (int i = 0; i < this.m; i++) {
for (int j = 0; j < srDim; j++) {
double sum = 0;
for (int k = 0; k < this.n; k++) {
sum += Math.pow(this.get(i, k) - second.get(j, k), 2.0);
}
matrix.set(i, j, Math.exp(sum / sigmaV));
}
}
return matrix;
}
/**
* 取对角矩阵 如果输入为矩阵,则将矩阵的对角取出为向量。<br>
* 如果输入为向量,无论行向量或者列向量,一律返回以向量值为对角的矩阵,矩阵中除对角外其他为值均为0。
*/
public MatlabMatrix diag() {
MatlabMatrix matrix = null;
if (m == 1 || n == 1) {
int dim = m > n ? m : n;
matrix = new MatlabMatrix(dim, dim, 0);
if (m > n) {
for (int i = 0; i < m; i++) {
matrix.set(i, i, this.get(i, 0));
}
} else {
for (int i = 0; i < n; i++) {
matrix.set(i, i, this.get(0, i));
}
}
} else {
int dim = m < n ? m : n;
matrix = new MatlabMatrix(dim, 1, 0);
for (int i = 0; i < dim; i++) {
matrix.set(i, 0, this.get(i, i));
}
}
return matrix;
}
/**
* 在没有维度参数的情况下,就是把每一列当成向量,向量元素和为结果矩阵的行元素。<br>
* 如果带有维度参数,则输出的结果矩阵为对应维度的向量值。例子中使用的是二维矩阵。<br>
* 所以没有维度参数和维度参数为1的情况下输出行向量。 维度参数为2的情况下输出为列向量。<br>
* 维度参数为3的情况下,源矩阵原样输出,因为没有第三个维度。 <br>
* 如果输入为数组,则将每个数组元素相加为一个数值。
*
* @param dim
* @return
*/
public MatlabMatrix sum(int dim) {
MatlabMatrix matrix = null;
if (m == 1 || n == 1) {
matrix = new MatlabMatrix(1, 1, 0);
double sum = 0;
if (m > n) {
for (int i = 0; i < m; i++) {
sum += this.A[i][0];
}
} else {
for (int i = 0; i < n; i++) {
sum += this.A[0][i];
}
}
matrix.set(0, 0, sum);
} else {
if (dim == 1) {
matrix = new MatlabMatrix(1, n, 0);
for (int i = 0; i < n; i++) {
double sum = 0;
for (int j = 0; j < m; j++) {
double v = this.A[j][i];
sum += v;
}
matrix.set(0, i, sum);
}
} else if (dim == 2) {
matrix = new MatlabMatrix(m, 1, 0);
for (int i = 0; i < m; i++) {
double sum = 0;
for (int j = 0; j < n; j++) {
double v = this.A[i][j];
sum += v;
}
matrix.set(i, 0, sum);
}
}
}
return matrix;
}
/*****************************************************************
* AdditionalMethod for Vector
*****************************************************************
*/
/**
* Returns the maximum of a vector.
* <p>
* If multiple maximums exist, the index of the first is returned.
*/
public double max() {
double ma = A[0][0];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (ma < A[i][j]) {
ma = A[i][j];
}
}
}
return ma;
}
/**
* 同sum(1);
*
* @return
*/
public MatlabMatrix sum() {
return this.sum(1);
}
/**
* 矩阵中的所有元素值除以v
*
* @param v
*/
public MatlabMatrix divide(double v, boolean isNewMatrix) {
MatlabMatrix m_divide;
if (isNewMatrix) {
m_divide = new MatlabMatrix(m, n);
} else {
m_divide = this;
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
m_divide.getArray()[i][j] = (A[i][j] / v);
}
}
return m_divide;
}
@Override
public QRDecomposition qr() {
return super.qr();
}
@Override
public double sumV() throws Exception {
return super.sumV();
}
/**
* Matrix inverse or pseudoinverse 相当于 matlab A^-1
*
* @return inverse(A) if A is square, pseudoinverse otherwise.
*/
public MatlabMatrix inverse() {
return new MatlabMatrix(solve(identity(m, m)).getArray());
}
/**
* Generate identity matrix
*
* @param m
* Number of rows.
* @param n
* Number of colums.
* @return An m-by-n matrix with ones on the diagonal and zeros elsewhere.
*/
public static MatlabMatrix identity(int m, int n) {
MatlabMatrix A = new MatlabMatrix(m, n);
double[][] X = A.getArray();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
X[i][j] = (i == j ? 1.0 : 0.0);
}
}
return A;
}
public static void main(String args[]) {
double v[][] = { { 1.30637740629866, 2.83386924576936 },
{ -2.00161691590550, -3.61457330221293 },
{ -1.77905799893163, 0.993926938635369 } };
double v1[][] = { { 1, 2, 3 }, { 3, 4, 5 }, { 3, 4, 5 } };
double[][] vx = new double[1][1];
vx[0] = v1[0].clone();
MatlabMatrix matrix = new MatlabMatrix(v);
MatlabMatrix matrix1 = new MatlabMatrix(vx);
v1[0][0] = 90;
// System.out.println(matrix.l2distanceMatrix(matrix).toString());
// matrix1.divide(2, false);
System.out.println(matrix1.toString());
}
/**
* Matrix transpose.
*
* @return A'
*/
public MatlabMatrix transpose() {
MatlabMatrix X = new MatlabMatrix(n, m);
double[][] C = X.getArray();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
C[j][i] = A[i][j];
}
}
return X;
}
/**
* Linear algebraic matrix multiplication, A * B
*
* @param B
* another matrix
* @return Matrix product, A * B
* @throws IllegalArgumentException
* Matrix inner dimensions must agree.
*/
public MatlabMatrix times(MatlabMatrix B) {
if (B.m != n) {
throw new IllegalArgumentException(
"Matrix inner dimensions must agree.");
}
MatlabMatrix X = new MatlabMatrix(m, B.n);
double[][] C = X.getArray();
double[] Bcolj = new double[n];
for (int j = 0; j < B.n; j++) {
for (int k = 0; k < n; k++) {
Bcolj[k] = B.A[k][j];
}
for (int i = 0; i < m; i++) {
double[] Arowi = A[i];
double s = 0;
for (int k = 0; k < n; k++) {
s += Arowi[k] * Bcolj[k];
}
C[i][j] = s;
}
}
return X;
}
/*****************************************************************
* AdditionalMethod for Vector
*****************************************************************
*/
/**
* Returns the abs of a Matrix.
* <p>
* If multiple maximums exist, the index of the first is returned.
*/
public MatlabMatrix abs() {
MatlabMatrix m_abs = new MatlabMatrix(m, n);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
m_abs.A[i][j] = Math.abs(A[i][j]);
}
}
return m_abs;
}
/**
* C = A - B
*
* @param B
* another matrix
* @return A - B
*/
public MatlabMatrix minus(MatlabMatrix B) {
checkMatrixDimensions(B);
MatlabMatrix X = new MatlabMatrix(m, n);
double[][] C = X.getArray();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
C[i][j] = A[i][j] - B.A[i][j];
}
}
return X;
}
/**
* Make a deep copy of a matrix
*/
public MatlabMatrix copy() {
MatlabMatrix X = new MatlabMatrix(m, n);
double[][] C = X.getArray();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
C[i][j] = A[i][j];
}
}
return X;
}
/**
* Get a submatrix.
*
* @param i0
* Initial row index
* @param i1
* Final row index
* @param c
* Array of column indices.
* @return A(i0:i1,c(:))
* @throws ArrayIndexOutOfBoundsException
* Submatrix indices
*/
public MatlabMatrix getMatrix(int i0, int i1, int[] c) {
MatlabMatrix X = new MatlabMatrix(i1 - i0 + 1, c.length);
double[][] B = X.getArray();
try {
for (int i = i0; i <= i1; i++) {
for (int j = 0; j < c.length; j++) {
B[i - i0][j] = A[i][c[j]];
}
}
} catch (ArrayIndexOutOfBoundsException e) {
throw new ArrayIndexOutOfBoundsException("Submatrix indices");
}
return X;
}
/**
* sum of a vector
*
* @return the sum of all the elements of a vector.
*/
public double sumRV() throws Exception {
if (m != 1)
throw new Exception("Only for row vector type Matrix");
double sum = 0;
for (int i = 0; i < n; i++)
sum = sum + A[0][i];
return sum;
}
public final MatlabMatrix getRowMatrix(int rowIndex) throws Exception {
double[][] rowValue = new double[1][n];
rowValue[0] = this.getRow(rowIndex).clone();
return new MatlabMatrix(rowValue);
}
}