?? matrix.java
字號:
/* * @(#)Matrix.java 1.3 20/9/96 Akio Utsugi */import java.lang.Math;import java.util.Random;/** * Matrix is a class for matrix objects with basic linear calculation methods. * @version 1.2 17 Sep 1996 * @author <a href="http://www.aist.go.jp/NIBH/~b0616/"> Akio Utsugi </a> */public class Matrix{ final static double small = 1e-8; int row, col; double value[][];/** * Construct a square matrix object. * @param n size */ public Matrix(int n) { this(n, n); } /** * Construct a rectangle matrix object. * @param row number of row * @param col number of column */ public Matrix(int row, int col) { int i, j; this.row = row; this.col = col; value = new double[row][col]; for(i=0; i<row; i++){ for(j=0; j<col; j++){ value[i][j] = 0; } } }/* * Creation of special matrices */ /** * Make an identity matrix. * @param n size */ static public Matrix identity(int n) { int i; Matrix ret = new Matrix(n); for(i=0; i<n; i++){ ret.value[i][i] = 1; } return ret; }/** * Make a standard Gaussian random Matrix. * @param row number of row * @param col number of column * @param seed random seed */ static public Matrix random(int row, int col, int seed) { int i, j; Random rnd = new Random(seed); Matrix ret = new Matrix(row, col); for(i=0; i<row; i++){ for(j=0; j<col; j++){ ret.value[i][j] = rnd.nextGaussian(); } } return ret; }/** * Same as random(row, col, 1). */ static public Matrix random(int row, int col) { return random(row, col, 1); } /** * Copy the matrix. */ public Matrix copy() { int i, j; Matrix ret = new Matrix(row, col); for(i=0; i<row; i++){ for(j=0; j<col; j++){ ret.value[i][j] = value[i][j]; } } return ret; }/* * Basic Matrix Calculations *//** * Transpose: X'. */ public Matrix transpose() { int i, j; Matrix ret = new Matrix(col, row); for(i=0; i< row; i++){ for(j=0; j< col; j++){ ret.value[j][i] = value[i][j]; } } return ret; } /** * Linear conversion: a*X + b*Y. */ public Matrix linearConv(double a, double b, Matrix Y) { int i, j; int Y_row = Y.row; int Y_col = Y.col; if(row == Y_row && col == Y_col){ Matrix ret = new Matrix(row, col); for(i=0; i < row; i++){ for(j=0; j < col; j++){ ret.value[i][j] = a*value[i][j] + b*Y.value[i][j]; } } return ret; } else{ return null; } } /** * Update by Linear conversion: X = a*X + b*Y. */ public void updateLinearConv(double a, double b, Matrix Y) { int i, j; int Y_row = Y.row; int Y_col = Y.col; for(i=0; i < row; i++){ for(j=0; j < col; j++){ value[i][j] = a*value[i][j] + b*Y.value[i][j]; } } } /** * Scalar product: aX. */ public Matrix multipliedBy(double a) { int i, j; Matrix ret = new Matrix(row, col); for(i=0; i< row; i++){ for(j=0; j< col; j++){ ret.value[i][j] = a*value[i][j]; } } return ret; }/** * Matrix multiplication: X*Y. */ public Matrix multipliedBy(Matrix Y) { int i, j, k; double s; int Y_row = Y.row, Y_col = Y.col; if(col != Y_row){ return null; } Matrix ret = new Matrix(row, Y_col); for(i=0; i< row; i++){ for(j=0; j<Y_col; j++){ s = 0; for(k=0; k<col; k++){ s += value[i][k] * Y.value[k][j]; } ret.value[i][j] = s; } } return ret; } /** * Matrix division: X\Y. */ public Matrix dividedBy(Matrix Y) { return this.dividedBy(Y, 2*col-1); }/** * Matrix division with bandwidth: X\Y. */ public Matrix dividedBy(Matrix Y, int bw) { Matrix L, U, ret; int n, m, i, j, k; double w, s, pp; L = this.copy(); U = Y.copy(); m = L.row; n = U.col; bw = bw/2 + 1; for(k = 0; k < m; k++){ pp=L.value[k][k]; if(Math.abs(pp)< small){ return null; } w = 1/pp; for(j = k+1; j < k+bw && j < m ; j++){ s = w*L.value[k][j]; L.value[k][j] = s; for(i = k+1; i < k+bw+1 && i < m; i++){ s = L.value[i][j] - L.value[i][k]*L.value[k][j]; L.value[i][j] = s; } } for(j = 0; j < n; j++){ s=w*U.value[k][j]; U.value[k][j] = s; for(i = k+1; i < k+bw && i < m; i++){ s=U.value[i][j] - L.value[i][k] * U.value[k][j]; U.value[i][j] = s; } } } ret = new Matrix(m, n); for(i = m; --i>=0;){ for(j = 0; j < n; j++){ w=U.value[i][j]; for(k = i+1; i < k+bw && k < m; k++){ w -= L.value[i][k] * ret.value[k][j]; } ret.value[i][j] = w; } } return ret; }/* * Special purpose calculations *//** * Cross squared Euclidean distance Matrix: Z_{ij} = ||X_i - Y_j||^2 */ public Matrix crossSqDistance(Matrix Y) { Matrix ret; int i, j, k; double s, d; int Y_row = Y.row, Y_col = Y.col; if(col != Y_col){ return null; } ret = new Matrix(row, Y_row); for(i=0; i<row; i++){ for(j=0; j<Y_row; j++){ s = 0; for(k=0; k<col; k++){ d = value[i][k] - Y.value[j][k]; s += d*d; } ret.value[i][j] = s; } } return ret; } /** * Update by exponential : exp(X_{ij}) */ public void updateExp() { int i, j; for(i=0; i<row; i++){ for(j=0; j<col; j++){ value[i][j] = Math.exp(value[i][j]); } } } /** * Make a horizontal-summation vector. */ public Matrix horizontalSum() { int i, j; double s; Matrix ret = new Matrix(row, 1); for(i=0; i<row; i++){ s = 0; for(j=0; j<col; j++){ s += value[i][j]; } ret.value[i][0] = s; } return ret; }/** * Make a vertical-summation vector. */ public Matrix verticalSum() { int i, j; double s; Matrix ret = new Matrix(1, col); for(j=0; j<col; j++){ s = 0; for(i=0; i<row; i++){ s += value[i][j]; } ret.value[0][j] = s; } return ret; }/** * Summation of all entries. */ public double sumEntries() { int i, j; double s = 0; for(i=0; i<row; i++){ for(j=0; j<col; j++){ s += value[i][j]; } } return s; } /** * Summation of squared entries. */ public double sumSqrEntries() { int i, j; double s = 0; for(i=0; i<row; i++){ for(j=0; j<col; j++){ s += value[i][j]*value[i][j]; } } return s; }/** * Multiply entries. */ public Matrix mulipliedEntriesWith(Matrix Y) { Matrix ret; int i, j; ret = new Matrix(row, col); for(i=0; i<row; i++){ for(j=0; j<col; j++){ ret.value[i][j] = value[i][j]*Y.value[i][j]; } } return ret; } /** * X_{ij} = X_{ij}/v_{j}. */ public void updateDivideByRowVector(Matrix vec) { int i, j; for(j=0; j<col; j++){ for(i=0; i<row; i++){ value[i][j] = value[i][j]/vec.value[0][j]; } } }/** * If the matrix is a row or column vector, make a diagonal matrix from it. * Otherwise extract its diagonal as a row vector. */ public Matrix diagonal() { Matrix ret; int i, n; if(row == 1){ ret = new Matrix(col, col); for(i=0; i< col; i++){ ret.value[i][i] = value[0][i]; } } else if(col == 1){ ret = new Matrix(row, row); for(i=0; i< row; i++){ ret.value[i][i] = value[i][0]; } } else{ n = Math.min(row, col); ret = new Matrix(1, n); for(i=0; i< n; i++){ ret.value[0][i] = value[i][i]; } } return ret; }/** * Make a row vector including the eigenvalues of the matrix. * @param eps allowable absolute value of off-diagonal entries * @lmax maximum number of repeat */ public Matrix eigenvalues(double eps, int lmax) { int n; int i, j, im = 0, jm = 0, ll; double pmax, pii, pjj, pij, d, tn; double a, b, p1, p2, q1, q2, dd; Matrix px, qx, lmd; px = this.copy(); n = px.row; qx = Matrix.identity(n); ll=0; do{ pmax = Math.abs(px.value[0][1]); ll++; for(i=0; i<n-1; i++){ for(j=i+1; j<n; j++){ if(pmax<= Math.abs(px.value[i][j])){ pmax= Math.abs(px.value[i][j]); im=i; jm=j; } } } if(pmax<=eps) break; pii=px.value[im][im]; pjj=px.value[jm][jm]; pij=px.value[im][jm]; d=pii-pjj; dd=d*d+4.*pij*pij; tn=2.*pij/(d+Math.sqrt(dd)*(d > 0 ? 1 : -1)); a=1./Math.sqrt(1.+tn*tn); b=a*tn; for(i=0; i<n; i++){ p1=px.value[i][im]; p2=px.value[i][jm]; px.value[i][im] = p1*a+p2*b; px.value[i][jm] = -p1*b+p2*a; q1=qx.value[i][im]; q2=qx.value[i][jm]; qx.value[i][im] = q1*a+q2*b; qx.value[i][jm] = -q1*b+q2*a; } for(i=0; i<n; i++){ p1=px.value[im][i]; p2=px.value[jm][i]; px.value[im][i] = p1*a+p2*b; px.value[jm][i] = -p1*b+p2*a; } }while(ll<lmax); lmd = px.diagonal(); return lmd; }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -