weka matrix类功能扩展,模拟matlab

这个Java类实现了矩阵的基本运算,如平方、指数、欧氏距离、Σexp等,同时支持矩阵转置、乘法、求解逆矩阵等操作。特别地,它提供了两个矩阵间的欧氏距离计算,包括带权重的欧氏距离,并且能够从矩阵中提取对角线元素。
摘要由CSDN通过智能技术生成

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);
 }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值